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

Commit 133fc588 authored by Arman Uguray's avatar Arman Uguray
Browse files

Properly disconnect GATT connection during noisy scans

This patch fixes an issue that is reproducible in highly noisy environments
(massive deployment of BLE beacons), through repeated connect/disconnect
attempts on a remote peripheral while scanning for beacons in the background.
The state machine in bta/gatt has a special control flow for handling disconnect
requests during discovery, which in this case failed to resolve the original
request by issuing an HCI_Disconnect command. This is now fixed by always
explicitly triggering the connection close sequence once the discovery state has
been cleaned up.

This patch also includes a fix for a crash that occurred as a side-effect of the
scenario described above.

Bug: 22350508
Change-Id: Ie9cbd3c8f54239b142bfb8dde80d9581ae70ed43
parent 6cefe2c6
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -858,11 +858,23 @@ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS statu
*******************************************************************************/
void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
    APPL_TRACE_DEBUG("Discovery cancel conn_id=%d",p_clcb->bta_conn_id);
    APPL_TRACE_DEBUG("%s: Discovery cancel conn_id=%d", __func__,
                     p_clcb->bta_conn_id);

    if (p_clcb->disc_active)
        bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
    else
        p_clcb->state = BTA_GATTC_CONN_ST;

    // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
    // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
    // connection itself still needs to be closed to resolve the original event.
    if (p_clcb->state == BTA_GATTC_CONN_ST)
    {
        APPL_TRACE_DEBUG("State is back to BTA_GATTC_CONN_ST. "
                         "Trigger connection close");
        bta_gattc_close(p_clcb, p_data);
    }
}
/*******************************************************************************
**
+6 −1
Original line number Diff line number Diff line
@@ -597,6 +597,11 @@ BOOLEAN bta_sys_is_register(UINT8 id)
*******************************************************************************/
void bta_sys_sendmsg(void *p_msg)
{
    // There is a race condition that occurs if the stack is shut down while
    // there is a procedure in progress that can schedule a task via this
    // message queue. This causes |btu_bta_msg_queue| to get cleaned up before
    // it gets used here; hence we check for NULL before using it.
    if (btu_bta_msg_queue)
        fixed_queue_enqueue(btu_bta_msg_queue, p_msg);
}