From b0a9f9f23f7405bc088695e1d91763aced70b9fd Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Wed, 21 Mar 2018 18:46:14 -0700 Subject: [PATCH] Gracefully recover on bad attempt to cancel LE connection According to logs some devices are stuck when in BLE_CONN_CANCEL state. That is they sent "LE Create Connection Cancel" request, and are awaiting "LE Connection Complete" event with invalid handle forever. But they wait and wait, and the event never arrive. That's because "LE Create Connection Cancel" was sent, when connection attempt is not pending. In such case, we should act upon command complete status, and decide to leave BLE_CONN_CANCEL state. To properly fix this issue, one would have to implement a proper queue for managing LE connection attempt state, preferably for scratch. This fix just give option of graceful recovery. Test: sl4a GattConnectTest Bug: 75290221 Change-Id: I7e7a377c789ac0a587390320fbf504267cca8727 --- stack/btm/btm_ble_bgconn.cc | 13 +++++++++++++ stack/btm/btm_int.h | 1 + stack/btu/btu_hcif.cc | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/stack/btm/btm_ble_bgconn.cc b/stack/btm/btm_ble_bgconn.cc index 8dbf6cf65..cb3e05365 100644 --- a/stack/btm/btm_ble_bgconn.cc +++ b/stack/btm/btm_ble_bgconn.cc @@ -344,6 +344,19 @@ void btm_ble_remove_from_white_list_complete(uint8_t* p, BTM_TRACE_EVENT("%s status=%d", __func__, *p); } +void btm_ble_create_conn_cancel_complete(uint8_t* p) { + uint8_t status; + STREAM_TO_UINT8(status, p); + + if (status == HCI_ERR_COMMAND_DISALLOWED) { + /* This is a sign that logic around keeping connection state is broken */ + LOG(ERROR) + << "Attempt to cancel LE connection, when no connection is pending."; + btm_ble_set_conn_st(BLE_CONN_IDLE); + btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, nullptr, status); + } +} + void btm_send_hci_create_connection( uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy, uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own, diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h index d7c9ed23a..8188a8ea7 100644 --- a/stack/btm/btm_int.h +++ b/stack/btm/btm_int.h @@ -184,6 +184,7 @@ extern void btm_ble_add_2_white_list_complete(uint8_t status); extern void btm_ble_remove_from_white_list_complete(uint8_t* p, uint16_t evt_len); extern void btm_ble_clear_white_list_complete(uint8_t* p, uint16_t evt_len); +extern void btm_ble_create_conn_cancel_complete(uint8_t* p); extern bool btm_ble_addr_resolvable(const RawAddress& rpa, tBTM_SEC_DEV_REC* p_dev_rec); extern tBTM_STATUS btm_ble_read_resolving_list_entry( diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc index a95c5ed42..eac71a684 100644 --- a/stack/btu/btu_hcif.cc +++ b/stack/btu/btu_hcif.cc @@ -973,6 +973,10 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p, LOG(ERROR) << "No command complete expected, but received!"; break; + case HCI_BLE_CREATE_CONN_CANCEL: + btm_ble_create_conn_cancel_complete(p); + break; + case HCI_BLE_TRANSMITTER_TEST: case HCI_BLE_RECEIVER_TEST: case HCI_BLE_TEST_END: -- 2.11.0