From e625c1370e46a722211642b91e9dbc2ade25d6d3 Mon Sep 17 00:00:00 2001 From: Matadeen Mishra Date: Wed, 23 Sep 2015 22:26:46 +0530 Subject: [PATCH] Handling Authentication Failure From the lower layer Use case: DUT unable to do connect with all devices in Multipairing case. Steps: 1. pair with HS 2. disconnect HS. 3. reconnect HS from DUT. Failure: Authentication failure occurred due to LMP transaction collision DUT not deleting link key which lead to unable to connect to device. Root Cause: Not posting the Authentication failure event to application layer, while removing the link-key. Fix: Post the Authentication failure event to application and removing the link-key. Change-Id: I079d8ce89c1fea66f0624127514cec8405bfdd3d Add null check to avoid exception after L2CAP psm assigned Use case: BT will get crash in SNS testing. steps: SNS testing BT ON/OFF. Failure: Crash is observed. Root Cause: If the number of supported services increased, larger service record array is required. Smaller array is resulting in out of record error causing L2CAP deregister. Fix: Check added to avoid null pointer exception if null is returned while fetching sock from id. Also cleanup of SDP and security records done during BT turning Off. Change-Id: I2e77127262119cabf2c372f894427dcdf3350e80 Prevent crash due to second attempt to clean up eager_reader Null out the eager readers once they are cleaned up, so we don't try to clean them up later if an error occurs opening the HAL again later. Change-Id: I07df1010a1a619cb67b306d64e274d450234a002 Remove bonded device information on pairing rejected Use Case: Remove bonded device information from the BTIF layer storage when authentication failed. Failure: Remote device appeared in the paired list after authentication failed. Steps: 1. Create a connection from DUT to remote. 2. Remove linkkey in remote. 3. Create connection from DUT to remote, which is in paired list of DUT, Remote rejected the connection and authentication failed. But after BT OFF/ON, remote device appeared in the paired list Root Cause: Not removing device if remoted rejected the pairing request with reason pairing not allowed Fix: Remove bonded device information from the BTIF layer storage on rejected with pairing not allowed reason from remote Change-Id: Ic9e5e1ed70d304edd3dbca82a73833753fa0093c GAP: Save pin code length for incoming legacy SAP connection Use case: Carkit cannot reconnect to DUT in Sim Access Profile mode Steps: 1. Pair with a car-kit (Agree all SAP, MAP, PBAP requests) 2. Initiate disconnection on DUT 3. Initiate re-connection on the car-kit. Failure: SAP profile reconnection failing as dut gives negetive linkkey reply. Root Cause: sec_flags not getting updated without pin len and stack triggering negative link key reply even linkkey is proper for 16 digit authentication of SAP. Fix: Save pin length during BTM_PINCodeReply. Change-Id: I8300dd3ff497058291143313b169190910e0a7c5 Ignore pairing not allowed error when pairing in progress Use case: Pairing with both devices fails, when there is clash of pairing from 2 devices 1. Create a link from Test tool to DUT. Remove bonding info in Test tool. 2. Create a link from DUT to magic mouse. Unpair the link from DUT. 3. Click on magic mouse, it creates a link, and we get a pairing pop-up in DUT. 4. Try to pair from Test tool to DUT. Failure: Pairing with mouse should success and other pairing should fail. But both pairing fails Root cause: Stack sending pairing not allowed error to upper layers for the second device when already pairing is in progress with some other device, which is impacting the existing pairing. Fix: Issue fixed by Ignore pairing not allowed error for the second device when already pairing is in progress with some other device. Change-Id: I20dbd70e7429505a580c9a20d40a8d92318f6c3e Handled delayed info response from remote during SDP Use case: DUT is not connecting to windows-7 tablet Failure: Connection is not successful with windows-7 tablet. Steps: 1. Turn on BT on DUT 2. Pair and connect from remote device. Root Cause: DUT initiates connection with out waiting for information response from remote device during SDP. Fix: DUT will not wait for information response from the remote during SDP. Change-Id: Iee0251f8f81923b1291983b66b31c78e14d21af0 GAP: Update Paging and inquiry busy level seperately Use case: Bluetooth Search Fail while ACL disconnection. Steps: 1. Headset(HBS 760) connect 2. Put Headset off 3. BT Search Fail. Failure: BT search fail after disconnected Headset. Root cause: While updating the busy level of Paging or inquiry '10' was used as BL for paging and inquiry,this leads to 1. Ignore the one of them when both of them are active. 2. During ACL disconnection, unexpected inquiry busy level update. Fix: Sending unique busy level for paging related events and inquiry related events, so that each event will be notified. Change-Id: I7bddcb4901061c450555235717b7d49bab922ae8 GAP Write 248 char name length to the chip while BT ON/OFF Use case: Remote device cannot see local name with 248 chars. steps: 1. Turn on BT (Default name will come) 2. Change local name to 248 chars make sure DUT can be successfully searched from remote device. 3. Turn off BT (or phone reboot) 4. Turn on BT After step.4, the 248 chars name comes to GUI on MTP. However device search from remote device having DUT "Default name". Failure: Remote device cannot see local name with 248 chars. Root cause: DUT not supporting for the 248 char local name Fix: Writing the exact 248 character local name to the chip Change-Id: I702af8fa8d0affda509de7a9f17af8922e410286 Failed to re-register APK Configuration for HDP Use case: register/unregister HDP from third party APK Test Steps: 1.Install Any Test APK which internally registers/unregister the HDP. 2.Run Test APK. 3.Do initialization of Test APK which internally registers the HDP. 4.Force stop the Test APK. 5.And rerun the APK by going back test APK menu. 6.Now it never perform the re-register the HDP as part of initialization. Root Cause: HDP registration related counter write operations are done in JNI main thread, and it's been referenced in BTIF thread.Sometimes, if the context switch to BTIF thread doesn't happen immediately after counter increment/decrement, it may not un-register the app if the counter becomes 0. Fix: Fixed it by making all operations related to counter in BTIF thread, so that de-registration happens for all HDP APPs. Change-Id: I71ace68a5f3d39d81b646f5f40c02ce56b9e93f0 Added check for hci_layer status before processing function calls Use case: BT will get crash in SNS testing. Steps: SNS testing BT ON/OFF. Failure: Crash is observed. Root Cause: When hci_layer functions for transmit command and cleanup are called during hci_layer shutdown, they might try to access lists that are already cleared as part of shutdown process. Fix: Added check within functions to check for hci_layer state before processing. Change-Id: I8dbca9893e03dfc500886c5033a79976dc5d23e1 Group BR-EDR related SDP variables under transport Use Case: Random RNR initiated after HOGP Keyboard disconnection. steps: 1. keep madcatz in advertisement mode and scan, pair from DUT. 2. keep dailog Keyboard in advertisement mode and scan, pair from DUT. 3. Take Keyboard out of range to initiate disconnection from remote or initiate disconnection from remote. Failure: DUT trying to do RNR to random device. Root Cause: when the disconnection happened for LE device, it sets the wait_disc to true, that is causing random RNR to go for BR-EDR device. Fix: Group all BR-EDR related SDP variables under transport check so that if some other operation on LE will not corrupt these BR-EDR variables to mislead. Change-Id: Ic9003f2b85bbaaa30b201b8a639a9d9b52055ac5 --- bta/dm/bta_dm_act.c | 13 ++++++++----- btif/src/btif_dm.c | 3 ++- btif/src/btif_hl.c | 4 ++-- btif/src/btif_sock_l2cap.c | 14 ++++++++------ hci/src/hci_hal_h4.c | 2 ++ hci/src/hci_hal_mct.c | 4 ++++ hci/src/hci_layer.c | 17 +++++++++++++++++ stack/btm/btm_acl.c | 11 +++++++---- stack/btm/btm_sec.c | 5 ++--- stack/include/btm_api.h | 3 ++- stack/l2cap/l2c_csm.c | 2 +- 11 files changed, 55 insertions(+), 23 deletions(-) diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c index a6245a847..95bda4ccc 100644 --- a/bta/dm/bta_dm_act.c +++ b/bta/dm/bta_dm_act.c @@ -2314,10 +2314,12 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr) /* check whether connection already exists to the device if connection exists, we don't have to wait for ACL link to go down to start search on next device */ - if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR)) - bta_dm_search_cb.wait_disc = FALSE; - else - bta_dm_search_cb.wait_disc = TRUE; + if (transport == BT_TRANSPORT_BR_EDR) { + if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR)) + bta_dm_search_cb.wait_disc = FALSE; + else + bta_dm_search_cb.wait_disc = TRUE; + } #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) if ( bta_dm_search_cb.p_btm_inq_info ) @@ -3294,7 +3296,8 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) conn.link_down.link_type = p_data->acl_change.transport; #endif - if(bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) + if ((p_data->acl_change.transport == BT_TRANSPORT_BR_EDR) && + bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) { bta_dm_search_cb.wait_disc = FALSE; diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c index c47909f77..25daa63e6 100644 --- a/btif/src/btif_dm.c +++ b/btif/src/btif_dm.c @@ -1234,6 +1234,7 @@ static void btif_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl) break; case HCI_ERR_PAIRING_NOT_ALLOWED: + btif_storage_remove_bonded_device(&bd_addr); status = BT_STATUS_AUTH_REJECTED; break; @@ -1686,7 +1687,7 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param) bt_status_t status; bt_property_t prop; prop.type = BT_PROPERTY_BDNAME; - prop.len = BD_NAME_LEN; + prop.len = BD_NAME_LEN + 1; prop.val = (void*)bdname; status = btif_storage_get_adapter_property(&prop); diff --git a/btif/src/btif_hl.c b/btif/src/btif_hl.c index eec9d3449..316ce7642 100644 --- a/btif/src/btif_hl.c +++ b/btif/src/btif_hl.c @@ -3186,6 +3186,7 @@ static void btif_hl_proc_cb_evt(UINT16 event, char* p_param){ break; case BTIF_HL_REG_APP: + reg_counter++; p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->reg.app_idx); BTIF_TRACE_DEBUG("Rcv BTIF_HL_REG_APP app_idx=%d reg_pending=%d", p_data->reg.app_idx, p_acb->reg_pending); if (btif_hl_get_state() == BTIF_HL_STATE_ENABLED && p_acb->reg_pending) @@ -3207,6 +3208,7 @@ static void btif_hl_proc_cb_evt(UINT16 event, char* p_param){ break; case BTIF_HL_UNREG_APP: + reg_counter--; BTIF_TRACE_DEBUG("Rcv BTIF_HL_UNREG_APP app_idx=%d", p_data->unreg.app_idx ); p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->unreg.app_idx); if (btif_hl_get_state() == BTIF_HL_STATE_ENABLED) @@ -4034,7 +4036,6 @@ static bt_status_t unregister_application(int app_id){ if (btif_hl_find_app_idx(((UINT8)app_id), &app_idx)) { evt_param.unreg.app_idx = app_idx; - reg_counter --; len = sizeof(btif_hl_unreg_t); status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_UNREG_APP, (char*) &evt_param, len, NULL); @@ -4160,7 +4161,6 @@ static bt_status_t register_application(bthl_reg_param_t *p_reg_param, int *app_ evt_param.reg.app_idx = app_idx; len = sizeof(btif_hl_reg_t); p_acb->reg_pending = TRUE; - reg_counter++; BTIF_TRACE_DEBUG("calling btif_transfer_context status=%d app_id=%d", status, *app_id); status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_REG_APP, (char*) &evt_param, len, NULL); diff --git a/btif/src/btif_sock_l2cap.c b/btif/src/btif_sock_l2cap.c index 03c3ef4d1..6c87eeb6a 100644 --- a/btif/src/btif_sock_l2cap.c +++ b/btif/src/btif_sock_l2cap.c @@ -822,19 +822,21 @@ const tL2CAP_ERTM_INFO obex_l2c_etm_opt = * and this function is called with the newly allocated PSM. */ void on_l2cap_psm_assigned(int id, int psm) { - l2cap_socket *sock; /* Setup ETM settings: * mtu will be set below */ pthread_mutex_lock(&state_lock); - sock = btsock_l2cap_find_by_id_l(id); - sock->channel = psm; + l2cap_socket *sock = btsock_l2cap_find_by_id_l(id); - if(btSock_start_l2cap_server_l(sock) != BT_STATUS_SUCCESS) { - btsock_l2cap_free_l(sock); + if (sock) { + sock->channel = psm; + + if (btSock_start_l2cap_server_l(sock) != BT_STATUS_SUCCESS) + btsock_l2cap_free_l(sock); + } else { + APPL_TRACE_ERROR("%s: Error: sock is null", __func__); } pthread_mutex_unlock(&state_lock); - } static bt_status_t btSock_start_l2cap_server_l(l2cap_socket *sock) { diff --git a/hci/src/hci_hal_h4.c b/hci/src/hci_hal_h4.c index 062b6c0a6..811a88fd2 100644 --- a/hci/src/hci_hal_h4.c +++ b/hci/src/hci_hal_h4.c @@ -109,6 +109,8 @@ static void hal_close() { LOG_INFO(LOG_TAG, "%s", __func__); eager_reader_free(uart_stream); + uart_stream = NULL; + vendor->send_command(VENDOR_CLOSE_USERIAL, NULL); uart_fd = INVALID_FD; } diff --git a/hci/src/hci_hal_mct.c b/hci/src/hci_hal_mct.c index 669a9f84c..128beeee9 100644 --- a/hci/src/hci_hal_mct.c +++ b/hci/src/hci_hal_mct.c @@ -119,7 +119,11 @@ static void hal_close() { LOG_INFO(LOG_TAG, "%s", __func__); eager_reader_free(event_stream); + event_stream = NULL; + eager_reader_free(acl_stream); + acl_stream = NULL; + vendor->send_command(VENDOR_CLOSE_USERIAL, NULL); for (int i = 0; i < CH_MAX; i++) diff --git a/hci/src/hci_layer.c b/hci/src/hci_layer.c index d566141fc..7fb5b9f0b 100644 --- a/hci/src/hci_layer.c +++ b/hci/src/hci_layer.c @@ -78,6 +78,11 @@ typedef enum { FINISHED } receive_state_t; +typedef enum { + HCI_SHUTDOWN, + HCI_STARTED +} hci_layer_state; + typedef struct { receive_state_t state; uint16_t bytes_remaining; @@ -138,6 +143,7 @@ static packet_receive_data_t incoming_packets[INBOUND_PACKET_TYPE_COUNT]; // The hand-off point for data going to a higher layer, set by the higher layer static fixed_queue_t *upwards_data_queue; +static int hci_state; static future_t *shut_down(); static void event_finish_startup(void *context); @@ -271,6 +277,7 @@ static future_t *start_up(void) { LOG_DEBUG(LOG_TAG, "%s starting async portion", __func__); thread_post(thread, event_finish_startup, NULL); + hci_state = HCI_STARTED; return local_startup_future; error: @@ -294,6 +301,8 @@ static future_t *shut_down() { thread_join(thread); } + hci_state = HCI_SHUTDOWN; + fixed_queue_free(command_queue, osi_free); command_queue = NULL; fixed_queue_free(packet_queue, buffer_allocator->free); @@ -356,6 +365,11 @@ static void transmit_command( command_complete_cb complete_callback, command_status_cb status_callback, void *context) { + if (hci_state != HCI_STARTED) { + LOG_ERROR("%s Returning, hci_layer not ready", __func__); + return; + } + waiting_command_t *wait_entry = osi_calloc(sizeof(waiting_command_t)); uint8_t *stream = command->data + command->offset; @@ -394,6 +408,9 @@ static void transmit_downward(data_dispatcher_type_t type, void *data) { // TODO(zachoverflow): eliminate this call transmit_command((BT_HDR *)data, NULL, NULL, NULL); LOG_WARN(LOG_TAG, "%s legacy transmit of command. Use transmit_command instead.", __func__); + } else if (hci_state != HCI_STARTED) { + LOG_ERROR("%s Returning, hci_layer not ready", __func__); + return; } else { fixed_queue_enqueue(packet_queue, data); } diff --git a/stack/btm/btm_acl.c b/stack/btm/btm_acl.c index b4a2562ad..6e09fdd21 100644 --- a/stack/btm/btm_acl.c +++ b/stack/btm/btm_acl.c @@ -505,41 +505,44 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event) { case BTM_BLI_ACL_UP_EVT: BTM_TRACE_DEBUG ("BTM_BLI_ACL_UP_EVT"); + busy_level = BTM_GetNumAclLinks(); break; case BTM_BLI_ACL_DOWN_EVT: BTM_TRACE_DEBUG ("BTM_BLI_ACL_DOWN_EVT"); + busy_level = BTM_GetNumAclLinks(); break; case BTM_BLI_PAGE_EVT: BTM_TRACE_DEBUG ("BTM_BLI_PAGE_EVT"); btm_cb.is_paging = TRUE; evt.busy_level_flags= BTM_BL_PAGING_STARTED; + busy_level = BTM_BL_PAGING_STARTED; break; case BTM_BLI_PAGE_DONE_EVT: BTM_TRACE_DEBUG ("BTM_BLI_PAGE_DONE_EVT"); btm_cb.is_paging = FALSE; evt.busy_level_flags = BTM_BL_PAGING_COMPLETE; + busy_level = BTM_BL_PAGING_COMPLETE; break; case BTM_BLI_INQ_EVT: BTM_TRACE_DEBUG ("BTM_BLI_INQ_EVT"); btm_cb.is_inquiry = TRUE; evt.busy_level_flags = BTM_BL_INQUIRY_STARTED; + busy_level = BTM_BL_INQUIRY_STARTED; break; case BTM_BLI_INQ_CANCEL_EVT: BTM_TRACE_DEBUG ("BTM_BLI_INQ_CANCEL_EVT"); btm_cb.is_inquiry = FALSE; evt.busy_level_flags = BTM_BL_INQUIRY_CANCELLED; + busy_level = BTM_BL_INQUIRY_COMPLETE; break; case BTM_BLI_INQ_DONE_EVT: BTM_TRACE_DEBUG ("BTM_BLI_INQ_DONE_EVT"); btm_cb.is_inquiry = FALSE; evt.busy_level_flags = BTM_BL_INQUIRY_COMPLETE; + busy_level = BTM_BL_INQUIRY_COMPLETE; break; } - if (btm_cb.is_paging || btm_cb.is_inquiry) - busy_level = 10; - else - busy_level = BTM_GetNumAclLinks(); if ((busy_level != btm_cb.busy_level) ||(old_inquiry_state != btm_cb.is_inquiry)) { diff --git a/stack/btm/btm_sec.c b/stack/btm/btm_sec.c index 83f6494c4..a381d0896 100644 --- a/stack/btm/btm_sec.c +++ b/stack/btm/btm_sec.c @@ -902,6 +902,7 @@ void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, UINT8 *p_pin, if (trusted_mask) BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask); p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED; + p_dev_rec->pin_code_length = pin_len; if (pin_len >= 16) { p_dev_rec->sec_flags |= BTM_SEC_16_DIGIT_PIN_AUTHED; } @@ -912,7 +913,6 @@ void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, UINT8 *p_pin, { /* This is start of the dedicated bonding if local device is 2.0 */ btm_cb.pin_code_len = pin_len; - p_dev_rec->pin_code_length = pin_len; memcpy (btm_cb.pin_code, p_pin, pin_len); btm_cb.security_mode_changed = TRUE; @@ -4071,7 +4071,7 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status) if (btm_cb.api.p_auth_complete_callback) { /* report the suthentication status */ - if (old_state != BTM_PAIR_STATE_IDLE) + if ((old_state != BTM_PAIR_STATE_IDLE) || (status != HCI_SUCCESS)) (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, status); @@ -4564,7 +4564,6 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) (((status == HCI_ERR_AUTH_FAILURE) || (status == HCI_ERR_KEY_MISSING) || (status == HCI_ERR_HOST_REJECT_SECURITY) || - (status == HCI_ERR_PAIRING_NOT_ALLOWED) || (status == HCI_ERR_UNIT_KEY_USED) || (status == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) || (status == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) || diff --git a/stack/include/btm_api.h b/stack/include/btm_api.h index b3232f47d..26895b4c4 100644 --- a/stack/include/btm_api.h +++ b/stack/include/btm_api.h @@ -835,7 +835,8 @@ typedef struct typedef struct { tBTM_BL_EVENT event; /* The event reported. */ - UINT8 busy_level;/* when paging or inquiring, level is 10. + UINT8 busy_level;/* when paging or inquiring, level is between + 17 to 21 as the max links can be 16. * Otherwise, the number of ACL links. */ UINT8 busy_level_flags; /* Notifies actual inquiry/page activities */ } tBTM_BL_UPDATE_DATA; diff --git a/stack/l2cap/l2c_csm.c b/stack/l2cap/l2c_csm.c index dedffc8a5..01fe1f34a 100644 --- a/stack/l2cap/l2c_csm.c +++ b/stack/l2cap/l2c_csm.c @@ -229,7 +229,7 @@ Event uninit_use_in_call: Using uninitialized value "settings.min" in call to fu p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP; /* Wait for the info resp in this state before sending connect req (if needed) */ - if (!p_ccb->p_lcb->w4_info_rsp) + if ((!p_ccb->p_lcb->w4_info_rsp) || (BT_PSM_SDP == p_ccb->p_rcb->psm)) { /* Need to have at least one compatible channel to continue */ if (!l2c_fcr_chk_chan_modes(p_ccb)) -- 2.11.0