Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a363b7f2 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

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
parent 9b9ee65e
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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,
+1 −0
Original line number Diff line number Diff line
@@ -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(
+4 −0
Original line number Diff line number Diff line
@@ -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: