diff options
author | jechao <jechao@broadcom.com> | 2012-03-13 18:32:24 -0700 |
---|---|---|
committer | Matthew Xie <mattx@google.com> | 2012-07-14 11:19:13 -0700 |
commit | 5140bed9a19aadca962184ebc9ed823d5d7cb745 (patch) | |
tree | 13e18514ba8082f49480597c0bd340fdeabec03d | |
parent | 0afef5f7d9b3fe739671c1caa0aa5f1245e0c31d (diff) | |
download | external_bluetooth_bluedroid-5140bed9a19aadca962184ebc9ed823d5d7cb745.zip external_bluetooth_bluedroid-5140bed9a19aadca962184ebc9ed823d5d7cb745.tar.gz external_bluetooth_bluedroid-5140bed9a19aadca962184ebc9ed823d5d7cb745.tar.bz2 |
Revise on/off control process to address bdroid crashes seen in BT on/off stress tests.
Change-Id: I3c2ed587ddddb293f14c281ccdebb5ba4bf23a7e
-rw-r--r-- | btif/src/btif_core.c | 103 | ||||
-rw-r--r-- | gki/common/gki.h | 1 | ||||
-rw-r--r-- | gki/ulinux/gki_ulinux.c | 85 | ||||
-rw-r--r-- | main/bte_main.c | 92 |
4 files changed, 195 insertions, 86 deletions
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c index e3d1866..50ee650 100644 --- a/btif/src/btif_core.c +++ b/btif/src/btif_core.c @@ -49,8 +49,8 @@ * * Filename: btif_core.c * - * Description: Contains core functionality related to interfacing between - * Bluetooth HAL and BTE core stack. + * Description: Contains core functionality related to interfacing between + * Bluetooth HAL and BTE core stack. * ***********************************************************************************/ @@ -110,8 +110,8 @@ typedef union { /************************************************************************************ ** Static functions ************************************************************************************/ -static bt_status_t btif_init_bluetooth_evt(void); -static bt_status_t btif_shutdown_bluetooth_evt(void); +static bt_status_t btif_associate_evt(void); +static bt_status_t btif_disassociate_evt(void); /* sends message to btif task */ static void btif_sendmsg(void *p_msg); @@ -145,11 +145,11 @@ void btif_dm_execute_service_request(UINT16 event, char *p_param); ** ** Function btif_context_switched ** -** Description Callback used to execute transferred context callback +** Description Callback used to execute transferred context callback ** ** p_msg : message to be executed in btif context ** -** Returns void +** Returns void ** *******************************************************************************/ @@ -163,7 +163,7 @@ static void btif_context_switched(void *p_msg) /* each callback knows how to parse the data */ if (p->p_cb) - p->p_cb(p->event, p->p_param); + p->p_cb(p->event, p->p_param); } @@ -185,7 +185,7 @@ static void btif_context_switched(void *p_msg) bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTIF_COPY_CBACK *p_copy_cback) { - tBTIF_CONTEXT_SWITCH_CBACK *p_msg; + tBTIF_CONTEXT_SWITCH_CBACK *p_msg; BTIF_TRACE_VERBOSE2("btif_transfer_context event %d, len %d", event, param_len); @@ -224,7 +224,7 @@ bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_p ** Description BTIF task handler managing all messages being passed ** Bluetooth HAL and BTA. ** -** Returns void +** Returns void ** *******************************************************************************/ @@ -235,13 +235,13 @@ static void btif_task(UINT32 params) BTIF_TRACE_DEBUG0("btif task starting"); - btif_init_bluetooth_evt(); + btif_associate_evt(); for(;;) { /* wait for specified events */ event = GKI_wait(0xFFFF, 0); - + /* * Wait for the trigger to init chip and stack. This trigger will * be received by btu_task once the UART is opened and ready @@ -261,12 +261,12 @@ static void btif_task(UINT32 params) while((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL) { BTIF_TRACE_VERBOSE1("btif task fetched event %x", p_msg->event); - + switch (p_msg->event) { case BT_EVT_CONTEXT_SWITCH_EVT: btif_context_switched(p_msg); - break; + break; default: BTIF_TRACE_ERROR1("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK); break; @@ -276,7 +276,22 @@ static void btif_task(UINT32 params) } } } - btif_shutdown_bluetooth_evt(); + + btif_disassociate_evt(); + + GKI_task_self_cleanup(BTIF_TASK); + + if (btif_shutdown_pending) + { + btif_shutdown_pending = 0; + + bte_main_shutdown(); + + /* shutdown complete, all events notified and we reset HAL callbacks */ + bt_hal_cbacks = NULL; + } + + BTIF_TRACE_DEBUG0("btif task exiting"); } @@ -313,33 +328,24 @@ void btif_sendmsg(void *p_msg) bt_status_t btif_init_bluetooth(void) { - UINT8 status; bte_main_boot_entry(); - /* start btif task */ - status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR, - (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE), - sizeof(btif_task_stack)); - - if (status != GKI_SUCCESS) - return BT_STATUS_FAIL; - return BT_STATUS_SUCCESS; } /******************************************************************************* ** -** Function btif_init_bluetooth_evt +** Function btif_associate_evt ** -** Description Event indicating bluetooth init is completed +** Description Event indicating btif_task is up ** Attach btif_task to JVM ** ** Returns void ** *******************************************************************************/ -static bt_status_t btif_init_bluetooth_evt(void) +static bt_status_t btif_associate_evt(void) { BTIF_TRACE_DEBUG1("%s: notify ASSOCIATE_JVM", __FUNCTION__); CHECK_CALL_CBACK(bt_hal_cbacks, thread_evt_cb, ASSOCIATE_JVM); @@ -370,14 +376,19 @@ bt_status_t btif_enable_bluetooth(void) return BT_STATUS_DONE; } + /* Start the BTIF task */ + status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR, + (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE), + sizeof(btif_task_stack)); + + if (status != BTA_SUCCESS) + return BT_STATUS_FAIL; + /* add return status for create tasks functions ? */ /* Create the GKI tasks and run them */ bte_main_enable(); - if (status != BTA_SUCCESS) - return BT_STATUS_FAIL; - return BT_STATUS_SUCCESS; } @@ -480,10 +491,7 @@ void btif_disable_bluetooth_evt(void) /* update local state */ btif_enabled = 0; - if (btif_shutdown_pending) - { - btif_shutdown_bluetooth(); - } + GKI_send_event(BTIF_TASK, EVENT_MASK(GKI_SHUTDOWN_EVT)); } @@ -512,23 +520,30 @@ bt_status_t btif_shutdown_bluetooth(void) return BT_STATUS_SUCCESS; } - btif_shutdown_pending = 0; - - GKI_destroy_task(BTIF_TASK); - bte_main_shutdown(); + /* shutdown complete, all events notified and we reset HAL callbacks */ + bt_hal_cbacks = NULL; + return BT_STATUS_SUCCESS; } -static bt_status_t btif_shutdown_bluetooth_evt(void) + +/******************************************************************************* +** +** Function btif_disassociate_evt +** +** Description Event indicating btif_task is going down +** Detach btif_task to JVM +** +** Returns void +** +*******************************************************************************/ + +static bt_status_t btif_disassociate_evt(void) { BTIF_TRACE_DEBUG1("%s: notify DISASSOCIATE_JVM", __FUNCTION__); - CHECK_CALL_CBACK(bt_hal_cbacks, thread_evt_cb, DISASSOCIATE_JVM); - - /* shutdown complete, all events notified and we reset HAL callbacks */ - bt_hal_cbacks = NULL; return BT_STATUS_SUCCESS; } @@ -1063,7 +1078,7 @@ bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id) * enable for the profiles that have been enabled */ btif_enabled_services |= (1 << service_id); BTIF_TRACE_ERROR2("%s: Current Services:0x%x", __FUNCTION__, btif_enabled_services); - if (btif_enabled == TRUE) + if (btif_enabled == 1) { btif_transfer_context(btif_dm_execute_service_request, BTIF_DM_ENABLE_SERVICE, @@ -1091,7 +1106,7 @@ bt_status_t btif_disable_service(tBTA_SERVICE_ID service_id) */ btif_enabled_services &= (tBTA_SERVICE_MASK)(~(1<<service_id)); BTIF_TRACE_ERROR2("%s: Current Services:0x%x", __FUNCTION__, btif_enabled_services); - if (btif_enabled == TRUE) + if (btif_enabled == 1) { btif_transfer_context(btif_dm_execute_service_request, BTIF_DM_DISABLE_SERVICE, diff --git a/gki/common/gki.h b/gki/common/gki.h index a3272d5..a1005dc 100644 --- a/gki/common/gki.h +++ b/gki/common/gki.h @@ -369,6 +369,7 @@ extern "C" { */ GKI_API extern UINT8 GKI_create_task (TASKPTR, UINT8, INT8 *, UINT16 *, UINT16); GKI_API extern void GKI_destroy_task(UINT8 task_id); +GKI_API extern void GKI_task_self_cleanup(UINT8 task_id); GKI_API extern void GKI_exit_task(UINT8); GKI_API extern UINT8 GKI_get_taskid(void); GKI_API extern void GKI_init(void); diff --git a/gki/ulinux/gki_ulinux.c b/gki/ulinux/gki_ulinux.c index 8fdac95..c2838c1 100644 --- a/gki/ulinux/gki_ulinux.c +++ b/gki/ulinux/gki_ulinux.c @@ -363,6 +363,27 @@ void GKI_destroy_task(UINT8 task_id) /* paranoi settings, make sure that we do not execute any mailbox events */ gki_cb.com.OSWaitEvt[task_id] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK| TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK); + +#if (GKI_NUM_TIMERS > 0) + gki_cb.com.OSTaskTmr0R[task_id] = 0; + gki_cb.com.OSTaskTmr0 [task_id] = 0; +#endif + +#if (GKI_NUM_TIMERS > 1) + gki_cb.com.OSTaskTmr1R[task_id] = 0; + gki_cb.com.OSTaskTmr1 [task_id] = 0; +#endif + +#if (GKI_NUM_TIMERS > 2) + gki_cb.com.OSTaskTmr2R[task_id] = 0; + gki_cb.com.OSTaskTmr2 [task_id] = 0; +#endif + +#if (GKI_NUM_TIMERS > 3) + gki_cb.com.OSTaskTmr3R[task_id] = 0; + gki_cb.com.OSTaskTmr3 [task_id] = 0; +#endif + GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT)); #if ( FALSE == GKI_PTHREAD_JOINABLE ) @@ -386,6 +407,70 @@ void GKI_destroy_task(UINT8 task_id) /******************************************************************************* ** +** Function GKI_task_self_cleanup +** +** Description This function is used in the case when the calling thread +** is exiting itself. The GKI_destroy_task function can not be +** used in this case due to the pthread_join call. The function +** cleans up GKI control block associated to the terminating +** thread. +** +** Parameters: task_id - (input) Task id is used for sanity check to +** make sure the calling thread is in the right +** context. +** +** Returns None +** +*******************************************************************************/ +void GKI_task_self_cleanup(UINT8 task_id) +{ + UINT8 my_task_id = GKI_get_taskid(); + + if (task_id != my_task_id) + { + GKI_ERROR_LOG("%s: Wrong context - current task %d is not the given task id %d",\ + __FUNCTION__, my_task_id, task_id); + return; + } + + if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD) + { + /* paranoi settings, make sure that we do not execute any mailbox events */ + gki_cb.com.OSWaitEvt[task_id] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK| + TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK); + +#if (GKI_NUM_TIMERS > 0) + gki_cb.com.OSTaskTmr0R[task_id] = 0; + gki_cb.com.OSTaskTmr0 [task_id] = 0; +#endif + +#if (GKI_NUM_TIMERS > 1) + gki_cb.com.OSTaskTmr1R[task_id] = 0; + gki_cb.com.OSTaskTmr1 [task_id] = 0; +#endif + +#if (GKI_NUM_TIMERS > 2) + gki_cb.com.OSTaskTmr2R[task_id] = 0; + gki_cb.com.OSTaskTmr2 [task_id] = 0; +#endif + +#if (GKI_NUM_TIMERS > 3) + gki_cb.com.OSTaskTmr3R[task_id] = 0; + gki_cb.com.OSTaskTmr3 [task_id] = 0; +#endif + + GKI_exit_task(task_id); + + /* Calling pthread_detach here to mark the thread as detached. + Once the thread terminates, the system can reclaim its resources + without waiting for another thread to join with. + */ + pthread_detach(gki_cb.os.thread_id[task_id]); + } +} + +/******************************************************************************* +** ** Function GKI_shutdown ** ** Description shutdowns the GKI tasks/threads in from max task id to 0 and frees diff --git a/main/bte_main.c b/main/bte_main.c index 5def921..274ee7d 100644 --- a/main/bte_main.c +++ b/main/bte_main.c @@ -119,17 +119,11 @@ UINT32 bte_btu_stack[(BTE_BTU_STACK_SIZE + 3) / 4]; ******************************************************************************/ void bte_main_in_hw_init(void) { - GKI_delay(200); - - if ( (bt_vendor_if = (bt_vendor_interface_t *) bt_vendor_get_interface()) == NULL) + if ( (bt_vendor_if = (bt_vendor_interface_t *) bt_vendor_get_interface()) \ + == NULL) { APPL_TRACE_ERROR0("!!! Failed to get BtVendorInterface !!!"); } - else - { - int result = bt_vendor_if->init(&vnd_callbacks); - APPL_TRACE_EVENT1("libbt-vendor init returns %d", result); - } } /****************************************************************************** @@ -153,8 +147,6 @@ void bte_main_boot_entry(void) BTTRC_TraceInit(MAX_TRACE_RAM_SIZE, &BTE_TraceLogBuf[0], BTTRC_METHOD_RAM); #endif - /* Initialize BTE control block */ - BTE_Init(); } /****************************************************************************** @@ -168,8 +160,10 @@ void bte_main_boot_entry(void) ******************************************************************************/ void bte_main_shutdown() { +#if 0 if (bt_vendor_if) bt_vendor_if->cleanup(); +#endif bt_vendor_if = NULL; GKI_shutdown(); @@ -188,11 +182,18 @@ void bte_main_shutdown() void bte_main_enable(void) { APPL_TRACE_DEBUG1("%s", __FUNCTION__); + + /* Initialize BTE control block */ + BTE_Init(); + lpm_enabled = FALSE; if (bt_vendor_if) { - /* toggle chip power to ensure we will reset chip in case + int result = bt_vendor_if->init(&vnd_callbacks); + APPL_TRACE_EVENT1("libbt-vendor init returns %d", result); + + /* toggle chip power to ensure we will reset chip in case a previous stack shutdown wasn't completed gracefully */ bt_vendor_if->set_power(BT_VENDOR_CHIP_PWR_OFF); bt_vendor_if->set_power(BT_VENDOR_CHIP_PWR_ON); @@ -226,7 +227,11 @@ void bte_main_disable(void) GKI_freeze(); if (bt_vendor_if) - bt_vendor_if->set_power(BT_VENDOR_CHIP_PWR_OFF); + { + bt_vendor_if->set_power(BT_VENDOR_CHIP_PWR_OFF); + bt_vendor_if->cleanup(); + } + } /****************************************************************************** @@ -257,7 +262,7 @@ void bte_main_postload_cfg(void) void bte_main_enable_lpm(BOOLEAN enable) { int result = -1; - + if (bt_vendor_if) result = bt_vendor_if->lpm( \ (enable == TRUE) ? BT_VENDOR_LPM_ENABLE : BT_VENDOR_LPM_DISABLE \ @@ -297,7 +302,7 @@ void bte_main_lpm_allow_bt_device_sleep() void bte_main_lpm_wake_bt_device() { int result = -1; - + if ((bt_vendor_if) && (lpm_enabled == TRUE)) result = bt_vendor_if->lpm(BT_VENDOR_LPM_WAKE_ASSERT); @@ -332,7 +337,7 @@ void bte_main_hci_send (BT_HDR *p_msg, UINT16 event) (char *) (p_msg + 1), \ p_msg->len); else - GKI_freebuf(p_msg); + GKI_freebuf(p_msg); } else { @@ -345,7 +350,7 @@ void bte_main_hci_send (BT_HDR *p_msg, UINT16 event) ** ** Function bte_main_post_reset_init ** -** Description BTE MAIN API - This function is mapped to BTM_APP_DEV_INIT +** Description BTE MAIN API - This function is mapped to BTM_APP_DEV_INIT ** and shall be automatically called from BTE after HCI_Reset ** ** Returns None @@ -366,7 +371,7 @@ void bte_main_post_reset_init() ** ** Function preload_cb ** -** Description VENDOR LIB CALLBACK API - This function is called +** Description VENDOR LIB CALLBACK API - This function is called ** when vendor lib completed stack preload process ** ** Returns None @@ -388,7 +393,7 @@ static void preload_cb(TRANSAC transac, bt_vendor_preload_result_t result) ** ** Function postload_cb ** -** Description VENDOR LIB CALLBACK API - This function is called +** Description VENDOR LIB CALLBACK API - This function is called ** when vendor lib completed stack postload process ** ** Returns None @@ -403,7 +408,7 @@ static void postload_cb(TRANSAC transac, bt_vendor_postload_result_t result) ** ** Function lpm_cb ** -** Description VENDOR LIB CALLBACK API - This function is called +** Description VENDOR LIB CALLBACK API - This function is called ** back from vendor lib to indicate the current LPM state ** ** Returns None @@ -412,14 +417,14 @@ static void postload_cb(TRANSAC transac, bt_vendor_postload_result_t result) static void lpm_cb(bt_vendor_lpm_request_result_t result) { APPL_TRACE_EVENT1("vnd lpm_result_cb %d", result); - lpm_enabled = (result == BT_VENDOR_LPM_ENABLED) ? TRUE : FALSE; + lpm_enabled = (result == BT_VENDOR_LPM_ENABLED) ? TRUE : FALSE; } /****************************************************************************** ** ** Function hostwake_ind ** -** Description VENDOR LIB CALLOUT API - This function is called +** Description VENDOR LIB CALLOUT API - This function is called ** from vendor lib to indicate the HostWake event ** ** Returns None @@ -434,7 +439,7 @@ static void hostwake_ind(bt_vendor_low_power_event_t event) ** ** Function alloc ** -** Description VENDOR LIB CALLOUT API - This function is called +** Description VENDOR LIB CALLOUT API - This function is called ** from vendor lib to request for data buffer allocation ** ** Returns NULL / pointer to allocated buffer @@ -443,16 +448,18 @@ static void hostwake_ind(bt_vendor_low_power_event_t event) static char *alloc(int size) { BT_HDR *p_hdr = NULL; - -// APPL_TRACE_DEBUG1("vnd alloc size=%d", size); - + + /* + APPL_TRACE_DEBUG1("vnd alloc size=%d", size); + */ + p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size); - + if (p_hdr == NULL) { APPL_TRACE_WARNING0("alloc returns NO BUFFER!"); } - + return ((char *) p_hdr); } @@ -460,16 +467,16 @@ static char *alloc(int size) ** ** Function dealloc ** -** Description VENDOR LIB CALLOUT API - This function is called +** Description VENDOR LIB CALLOUT API - This function is called ** from vendor lib to release the data buffer allocated -** through the alloc call earlier. +** through the alloc call earlier ** ** Returns bt_vnd_status_t ** ******************************************************************************/ static int dealloc(TRANSAC transac, char *p_buf) { - GKI_freebuf(transac); + GKI_freebuf(transac); return BT_VENDOR_STATUS_SUCCESS; } @@ -477,11 +484,11 @@ static int dealloc(TRANSAC transac, char *p_buf) ** ** Function data_ind ** -** Description VENDOR LIB CALLOUT API - This function is called -** from vendor lib to pass in the received HCI packets. +** Description VENDOR LIB CALLOUT API - This function is called +** from vendor lib to pass in the received HCI packets ** ** The core stack is responsible for releasing the data buffer -** passed in from vendor lib once the core stack has done with +** passed in from vendor lib once the core stack has done with ** it. ** ** Returns bt_vnd_status_t @@ -490,20 +497,21 @@ static int dealloc(TRANSAC transac, char *p_buf) static int data_ind(TRANSAC transac, char *p_buf, int len) { BT_HDR *p_msg = (BT_HDR *) transac; - -// APPL_TRACE_DEBUG2("vnd data_ind event=0x%04X (len=%d)", p_msg->event, len); + /* + APPL_TRACE_DEBUG2("vnd data_ind event=0x%04X (len=%d)", p_msg->event, len); + */ GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac); - return BT_VENDOR_STATUS_SUCCESS; + return BT_VENDOR_STATUS_SUCCESS; } /****************************************************************************** ** ** Function tx_result ** -** Description VENDOR LIB CALLBACK API - This function is called -** from vendor lib once it has processed/sent the prior data +** Description VENDOR LIB CALLBACK API - This function is called +** from vendor lib once it has processed/sent the prior data ** buffer which core stack passed to it through transmit_buf ** call earlier. ** @@ -520,17 +528,17 @@ static int tx_result(TRANSAC transac, char *p_buf, \ APPL_TRACE_DEBUG2("vnd tx_result %d (event=%04X)", result, \ ((BT_HDR *)transac)->event); */ - + if (result == BT_VENDOR_TX_FRAGMENT) { - GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac); + GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, transac); } else { GKI_freebuf(transac); } - - return BT_VENDOR_STATUS_SUCCESS; + + return BT_VENDOR_STATUS_SUCCESS; } /***************************************************************************** |