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

Commit 8ecab6c8 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

Cancel GATT Connections in Discovery Client

This change addresses an issue where
the device discovery search GATT client
fails to cancel direct GATT connections
when bonding is removed for a device.

This resulted in app_hold_link leakage and
prevented future connection attempts to the device.

The fix ensures that:

- Direct GATT connections are canceled when a device is removed.
- Explicit disconnection occurs upon
  failed connection attempts to release the associated app_hold_link.

Bug: 356168480
Bug: 336890664
Test: atest BluetoothInstrumenationTests BumbleBluetoothTests
Change-Id: I197a3262b22b7b449291622edb7d4ef4624a640c
parent aca0b594
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@
#include "bta/dm/bta_dm_disc_int.h"
#include "bta/dm/bta_dm_disc_legacy.h"
#include "bta/include/bta_gatt_api.h"
#include "com_android_bluetooth_flags.h"
#include "common/circular_buffer.h"
#include "common/strings.h"
#include "internal_include/bt_target.h"
@@ -172,6 +171,10 @@ void bta_dm_disc_gatt_cancel_open(const RawAddress& bd_addr) {
    return;
  }
  get_gatt_interface().BTA_GATTC_CancelOpen(0, bd_addr, false);
  if (com::android::bluetooth::flags::cancel_open_discovery_client() &&
      bta_dm_discovery_cb.client_if != BTA_GATTS_INVALID_IF) {
    get_gatt_interface().BTA_GATTC_CancelOpen(bta_dm_discovery_cb.client_if, bd_addr, true);
  }
}

void bta_dm_disc_gatt_refresh(const RawAddress& bd_addr) {
@@ -189,7 +192,7 @@ void bta_dm_disc_remove_device(const RawAddress& bd_addr) {
  }
  if (bta_dm_discovery_cb.service_discovery_state == BTA_DM_DISCOVER_ACTIVE &&
      bta_dm_discovery_cb.peer_bdaddr == bd_addr) {
    log::info("Device removed while service discovery was pending, conclude the service disvovery");
    log::info("Device removed while service discovery was pending, conclude the service discovery");
    bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID, (tGATT_STATUS)GATT_ERROR);
  }
}
@@ -536,7 +539,7 @@ static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) {
  if (com::android::bluetooth::flags::bta_dm_discover_both() && sdp_pending && !le_pending) {
    /* LE Service discovery finished, and services were reported, but SDP is not
     * finished yet. gatt_close_timer closed the connection, and we received
     * this callback because of disconnnection */
     * this callback because of disconnection */
    return;
  }

@@ -575,9 +578,13 @@ static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) {
      bta_dm_disc_sm_execute(BTA_DM_DISC_CLOSE_TOUT_EVT, nullptr);
    }
  } else {
    bta_dm_discovery_cb.conn_id = GATT_INVALID_CONN_ID;

    log::info("Discovery complete for invalid conn ID. Will pick up next job");

    if (com::android::bluetooth::flags::cancel_open_discovery_client()) {
      bta_dm_close_gatt_conn();
    } else {
      bta_dm_discovery_cb.conn_id = GATT_INVALID_CONN_ID;
    }
    bta_dm_discovery_set_state(BTA_DM_DISCOVER_IDLE);
    bta_dm_execute_queued_discovery_request();
  }
+10 −4
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@
#include "bta/include/bta_gatt_api.h"
#include "bta/include/bta_sdp_api.h"
#include "btif/include/btif_config.h"
#include "com_android_bluetooth_flags.h"
#include "common/circular_buffer.h"
#include "common/strings.h"
#include "device/include/interop.h"
@@ -196,6 +195,10 @@ void bta_dm_disc_disable_search_and_disc() { bta_dm_disable_search_and_disc(); }

void bta_dm_disc_gatt_cancel_open(const RawAddress& bd_addr) {
  get_gatt_interface().BTA_GATTC_CancelOpen(0, bd_addr, false);
  if (com::android::bluetooth::flags::cancel_open_discovery_client() &&
      bta_dm_search_cb.client_if != BTA_GATTS_INVALID_IF) {
    get_gatt_interface().BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, true);
  }
}

void bta_dm_disc_gatt_refresh(const RawAddress& bd_addr) {
@@ -204,7 +207,7 @@ void bta_dm_disc_gatt_refresh(const RawAddress& bd_addr) {

void bta_dm_disc_remove_device(const RawAddress& bd_addr) {
  if (bta_dm_search_cb.state == BTA_DM_DISCOVER_ACTIVE && bta_dm_search_cb.peer_bdaddr == bd_addr) {
    log::info("Device removed while service discovery was pending, conclude the service disvovery");
    log::info("Device removed while service discovery was pending, conclude the service discovery");
    bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID, (tGATT_STATUS)GATT_ERROR);
  }
}
@@ -1563,9 +1566,12 @@ static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) {
      bta_dm_search_sm_execute(BTA_DM_DISC_CLOSE_TOUT_EVT, nullptr);
    }
  } else {
    bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;

    log::info("Discovery complete for invalid conn ID. Will pick up next job");
    if (com::android::bluetooth::flags::cancel_open_discovery_client()) {
      bta_dm_close_gatt_conn();
    } else {
      bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
    }
    bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
    bta_dm_free_sdp_db();
    bta_dm_execute_queued_request();