summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjechao <jechao@broadcom.com>2012-03-13 18:32:24 -0700
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:13 -0700
commit5140bed9a19aadca962184ebc9ed823d5d7cb745 (patch)
tree13e18514ba8082f49480597c0bd340fdeabec03d
parent0afef5f7d9b3fe739671c1caa0aa5f1245e0c31d (diff)
downloadexternal_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.c103
-rw-r--r--gki/common/gki.h1
-rw-r--r--gki/ulinux/gki_ulinux.c85
-rw-r--r--main/bte_main.c92
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;
}
/*****************************************************************************