From fd7a09572600881a0d2aca1e6d6caff032ca04ad Mon Sep 17 00:00:00 2001 From: Sharvil Nanavati Date: Thu, 24 Jul 2014 09:07:36 -0700 Subject: Work around race condition between thread shutdown and vendor lib shutdown. This race condition occurs because of a structural bug - the userial thread depends on the HCI thread and the HCI thread depends on the userial thread but both are independently owned and torn down. This change fixes a crash bug due to the race condition (NULL pointer access in userial thread). http://b/16483216 Change-Id: I91ea274856ac72e9d72b92f0dc5c94e53aaf22f4 --- hci/src/bt_hci_bdroid.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/hci/src/bt_hci_bdroid.c b/hci/src/bt_hci_bdroid.c index 174cc1f..c38536a 100644 --- a/hci/src/bt_hci_bdroid.c +++ b/hci/src/bt_hci_bdroid.c @@ -83,6 +83,7 @@ volatile bool fwcfg_acked; typedef struct { thread_t *worker_thread; + pthread_mutex_t worker_thread_lock; bool epilog_timer_created; timer_t epilog_timer_id; } bt_hc_cb_t; @@ -213,17 +214,33 @@ static void event_tx_cmd(void *msg) { } void bthc_rx_ready(void) { - thread_post(hc_cb.worker_thread, event_rx, NULL); + pthread_mutex_lock(&hc_cb.worker_thread_lock); + + if (hc_cb.worker_thread) + thread_post(hc_cb.worker_thread, event_rx, NULL); + + pthread_mutex_unlock(&hc_cb.worker_thread_lock); } void bthc_tx(HC_BT_HDR *buf) { - if (buf) - utils_enqueue(&tx_q, buf); - thread_post(hc_cb.worker_thread, event_tx, NULL); + pthread_mutex_lock(&hc_cb.worker_thread_lock); + + if (hc_cb.worker_thread) { + if (buf) + utils_enqueue(&tx_q, buf); + thread_post(hc_cb.worker_thread, event_tx, NULL); + } + + pthread_mutex_unlock(&hc_cb.worker_thread_lock); } void bthc_idle_timeout(void) { - thread_post(hc_cb.worker_thread, event_lpm_idle_timeout, NULL); + pthread_mutex_lock(&hc_cb.worker_thread_lock); + + if (hc_cb.worker_thread) + thread_post(hc_cb.worker_thread, event_lpm_idle_timeout, NULL); + + pthread_mutex_unlock(&hc_cb.worker_thread_lock); } /******************************************************************************* @@ -238,8 +255,12 @@ void bthc_idle_timeout(void) { static void epilog_wait_timeout(UNUSED_ATTR union sigval arg) { ALOGI("...epilog_wait_timeout..."); + thread_free(hc_cb.worker_thread); + + pthread_mutex_lock(&hc_cb.worker_thread_lock); hc_cb.worker_thread = NULL; + pthread_mutex_unlock(&hc_cb.worker_thread_lock); } /******************************************************************************* @@ -305,6 +326,8 @@ static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr) hc_cb.epilog_timer_created = false; fwcfg_acked = false; + pthread_mutex_init(&hc_cb.worker_thread_lock, NULL); + /* store reference to user callbacks */ bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb; @@ -437,7 +460,10 @@ static void cleanup( void ) } thread_free(hc_cb.worker_thread); + + pthread_mutex_lock(&hc_cb.worker_thread_lock); hc_cb.worker_thread = NULL; + pthread_mutex_unlock(&hc_cb.worker_thread_lock); if (hc_cb.epilog_timer_created) { @@ -454,6 +480,8 @@ static void cleanup( void ) set_power(BT_VND_PWR_OFF); vendor_close(); + pthread_mutex_destroy(&hc_cb.worker_thread_lock); + fwcfg_acked = false; bt_hc_cbacks = NULL; } -- cgit v1.2.3 From 2a4c34d02b8c287c24e820bac716d42b52a99b74 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Wed, 3 Sep 2014 09:40:10 -0700 Subject: Bluetooth: Properly initialize UART fds If the vendor library is unable to open the UART, the passed in file descriptor array is unchanged. This array was uninitialized stack memory which may miss the illegal fd check and barrel ahead forking a userial read thread causing FD_SET problems should the uninitialized stack memory be bogus fds outside the processes boundaries. Verify that the vendor library was actually opening exactly one uart. Bug: 16651586 Change-Id: I24e700cdb0b0f3ed107f56b94b5b535abba66806 --- hci/src/userial.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hci/src/userial.c b/hci/src/userial.c index 4c2a8db..34de045 100644 --- a/hci/src/userial.c +++ b/hci/src/userial.c @@ -281,9 +281,12 @@ bool userial_open(userial_port_t port) { // Call in to the vendor-specific library to open the serial port. int fd_array[CH_MAX]; + for (int i = 0; i < CH_MAX; i++) + fd_array[i] = -1; + int num_ports = vendor_send_command(BT_VND_OP_USERIAL_OPEN, &fd_array); - if (num_ports > 1) { + if (num_ports != 1) { ALOGE("%s opened wrong number of ports: got %d, expected 1.", __func__, num_ports); goto error; } -- cgit v1.2.3 From 93c87f7a838e0566799d5c664500db8cb8483f3e Mon Sep 17 00:00:00 2001 From: Andre Eisenbach Date: Thu, 4 Sep 2014 12:43:05 -0700 Subject: Fix error in tick calculation when timer is removed A previous changed introduced an error in the timer tick calculation when removing a timer. This could lead to timers expiring sooner than expected. Bug: 17390240 Change-Id: Id3291aaf492a7178782e6f804dad71387c3c9382 --- gki/common/gki_time.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gki/common/gki_time.c b/gki/common/gki_time.c index b5fe7e2..aa95195 100644 --- a/gki/common/gki_time.c +++ b/gki/common/gki_time.c @@ -704,9 +704,6 @@ BOOLEAN GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT if (p_tle == NULL || p_timer_listq->p_first == NULL) return FALSE; - p_tle->ticks = 0; - p_tle->in_use = FALSE; - /* Add the ticks remaining in this timer (if any) to the next guy in the list. ** Note: Expired timers have a tick value of '0'. */ @@ -715,6 +712,9 @@ BOOLEAN GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT p_tle->p_next->ticks += p_tle->ticks; } + p_tle->ticks = 0; + p_tle->in_use = FALSE; + /* Unlink timer from the list. */ if (p_timer_listq->p_first == p_tle) -- cgit v1.2.3 From 5180dd341f570e977ef76e96ac78264439d8a91c Mon Sep 17 00:00:00 2001 From: Priti Aghera Date: Thu, 4 Sep 2014 13:29:28 -0700 Subject: Set random address before connection request Send Set_Random_Address when privacy is enabled. If Set_Random_Address is not sent to controller, Connection request will be sent with host address as all 0's Bug: 17386986 Change-Id: I59877e52bf76a56696800ff0e75487c633adde3c --- stack/btm/btm_ble_gap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c index f477956..f9011c3 100644 --- a/stack/btm/btm_ble_gap.c +++ b/stack/btm/btm_ble_gap.c @@ -582,7 +582,7 @@ void BTM_BleConfigPrivacy(BOOLEAN enable) if (p_cb->privacy) { /* generate resolvable private address */ - btm_gen_resolvable_private_addr(NULL); + btm_gen_resolvable_private_addr((void*)btm_gen_resolve_paddr_low); } else /* if privacy disabled, always use public address */ { -- cgit v1.2.3 From 67e6cc2c57ee04a53620d8158d54e81eaf61b167 Mon Sep 17 00:00:00 2001 From: Priti Aghera Date: Mon, 8 Sep 2014 13:04:29 -0700 Subject: Notify that link is up after LE read remote features completes ACL link up notifaction was not sent after LE read remote features was successful. Thus, total ACL link up count was not updated. Included a link up notification after LE read remote features is successfull. Bug: 17410697 Change-Id: I41fc640e76fa99354cb63d9b0b3031582178c057 --- stack/btm/btm_ble_gap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c index 3fdbbcc..2f38fbd 100644 --- a/stack/btm/btm_ble_gap.c +++ b/stack/btm/btm_ble_gap.c @@ -3009,6 +3009,8 @@ void btm_ble_read_remote_features_complete(UINT8 *p) if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle)) { STREAM_TO_ARRAY(p_acl_cb->peer_le_features, p, BD_FEATURES_LEN); + /* notify link up here */ + btm_establish_continue(p_acl_cb); l2cble_notify_le_connection (p_acl_cb->remote_addr); break; } -- cgit v1.2.3 From 21005e0e3d5a9ceac7195161918f0ac46d0f876d Mon Sep 17 00:00:00 2001 From: Priti Aghera Date: Tue, 9 Sep 2014 11:30:25 -0700 Subject: Fixed SMP pairing failure due to race condition SMP pairing failure if remote send security request before master side receive LE link connection callback. The racing condition will cause master side bonding failure upon ignoring remote security request and flush out all SMP information. Retain SMP information when a locally initiated pairing is in process solves the problem. Bug: 17412687 Change-Id: Ia2256160c866413f93c6f49e5db82b4c6489d9d2 --- stack/smp/smp_act.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c index 0c2b774..8392a9b 100644 --- a/stack/smp/smp_act.c +++ b/stack/smp/smp_act.c @@ -648,7 +648,8 @@ void smp_proc_discard(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) UNUSED(p_data); SMP_TRACE_DEBUG ("smp_proc_discard "); - smp_reset_control_value(p_cb); + if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) + smp_reset_control_value(p_cb); } /******************************************************************************* ** Function smp_proc_release_delay -- cgit v1.2.3 From 871c08625093fcf63b58f1033adbec9baa818479 Mon Sep 17 00:00:00 2001 From: Matthew Xie Date: Wed, 28 Jan 2015 17:30:13 -0800 Subject: bta_dm_search_cancel sends dm_search state machine complete events bta_dm_search_cancel moves dm_search state from active search to search_canceling state. The function is also responsible of moving the state out of canceling state. Bug: 19017339 Change-Id: Idea0cb0e2987892a5fc0f66db8eed19f57c68b89 --- bta/dm/bta_dm_act.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c index ed38b7e..0c0c222 100644 --- a/bta/dm/bta_dm_act.c +++ b/bta/dm/bta_dm_act.c @@ -1273,14 +1273,29 @@ void bta_dm_search_cancel (tBTA_DM_MSG *p_data) p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; bta_sys_sendmsg(p_msg); - } } /* If no Service Search going on then issue cancel remote name in case it is active */ else if (!bta_dm_search_cb.name_discover_done) { BTM_CancelRemoteDeviceName(); + + if ((p_msg = (tBTA_DM_MSG *) GKI_getbuf(sizeof(tBTA_DM_MSG))) != NULL) + { + p_msg->hdr.event = BTA_DM_REMT_NAME_EVT; + p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; + bta_sys_sendmsg(p_msg); + } } + else { + if ((p_msg = (tBTA_DM_MSG *) GKI_getbuf(sizeof(tBTA_DM_MSG))) != NULL) + { + p_msg->hdr.event = BTA_DM_INQUIRY_CMPL_EVT; + p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; + bta_sys_sendmsg(p_msg); + } + } + #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE if (bta_dm_search_cb.gatt_disc_active) { -- cgit v1.2.3