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

Commit eb9e79fc authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Łukasz Rymanowski (xWF)
Browse files

gatt: Fix cancel connect

With new approach, when gatt_reconnect_on_bt_on_fix is on, p_tcb is
created when connection is created.
This patch make sure that device is removed from accept list when cancel
connect is requested and there is no active background connect done by
other application.

Bug: 352816647
Bug: 325595120
Test: atest net_test_stack_gatt_native
Flag: com::android::bluetooth::flags::gatt_reconnect_on_bt_on_fix
Change-Id: I8dc47b38f9cf9cd69ee2a7b8d820c5e7582125b0
parent 86f579fb
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -366,7 +366,11 @@ bool background_connect_remove(uint8_t app_id, const RawAddress& address) {
}

bool is_background_connection(const RawAddress& address) {
  return bgconn_dev.find(address) != bgconn_dev.end();
  auto it = bgconn_dev.find(address);
  if (it == bgconn_dev.end()) {
    return false;
  }
  return it->second.is_in_accept_list;
}

/** deregister all related background connetion device. */
+1 −0
Original line number Diff line number Diff line
@@ -461,6 +461,7 @@ void gatt_set_err_rsp(bool enable, uint8_t req_op_code, uint8_t err_status);

/* from gatt_main.cc */
bool gatt_disconnect(tGATT_TCB* p_tcb);
void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport);
bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr, tBT_TRANSPORT transport,
                      int8_t initiating_phys);
bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
+34 −16
Original line number Diff line number Diff line
@@ -235,6 +235,39 @@ bool gatt_connect(const RawAddress& rem_bda, tGATT_TCB* p_tcb, tBT_TRANSPORT tra
                  uint8_t initiating_phys, tGATT_IF gatt_if) {
  return gatt_connect(rem_bda, BLE_ADDR_PUBLIC, p_tcb, transport, initiating_phys, gatt_if);
}

/*******************************************************************************
 *
 * Function         gatt_cancel_connect
 *
 * Description      This will remove device from allow list and cancel connection
 *
 * Parameter        bd_addr: peer device address.
 *                  transport: transport
 *
 *
 ******************************************************************************/
void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
  /* This shall be call only when device is not connected */
  log::debug("{}, transport {}", bd_addr, transport);

  if (bluetooth::common::init_flags::use_unified_connection_manager_is_enabled()) {
    // TODO(aryarahul): this might not be necessary now that the connection
    // manager handles GATT client closure correctly in GATT_Deregister
    bluetooth::connection::GetConnectionManager().stop_all_connections_to_device(
            bluetooth::connection::ResolveRawAddress(bd_addr));
  } else {
    if (!connection_manager::direct_connect_remove(CONN_MGR_ID_L2CAP, bd_addr)) {
      BTM_AcceptlistRemove(bd_addr);
      log::info(
              "GATT connection manager has no record but removed filter "
              "acceptlist gatt_if:{} peer:{}",
              static_cast<uint8_t>(CONN_MGR_ID_L2CAP), bd_addr);
    }
  }
  gatt_cleanup_upon_disc(bd_addr, GATT_CONN_TERMINATE_LOCAL_HOST, transport);
}

/*******************************************************************************
 *
 * Function         gatt_disconnect
@@ -269,22 +302,7 @@ bool gatt_disconnect(tGATT_TCB* p_tcb) {
      }
      gatt_set_ch_state(p_tcb, GATT_CH_CLOSING);
    } else {
      if (bluetooth::common::init_flags::use_unified_connection_manager_is_enabled()) {
        // TODO(aryarahul): this might not be necessary now that the connection
        // manager handles GATT client closure correctly in GATT_Deregister
        bluetooth::connection::GetConnectionManager().stop_all_connections_to_device(
                bluetooth::connection::ResolveRawAddress(p_tcb->peer_bda));
      } else {
        if (!connection_manager::direct_connect_remove(CONN_MGR_ID_L2CAP, p_tcb->peer_bda)) {
          BTM_AcceptlistRemove(p_tcb->peer_bda);
          log::info(
                  "GATT connection manager has no record but removed filter "
                  "acceptlist gatt_if:{} peer:{}",
                  static_cast<uint8_t>(CONN_MGR_ID_L2CAP), p_tcb->peer_bda);
        }
      }

      gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_TERMINATE_LOCAL_HOST, p_tcb->transport);
      gatt_cancel_connect(p_tcb->peer_bda, p_tcb->transport);
    }
  } else {
    if ((ch_state == GATT_CH_OPEN) || (ch_state == GATT_CH_CFG)) {
+19 −0
Original line number Diff line number Diff line
@@ -1518,6 +1518,22 @@ void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if, bool is_inc, bool
  }
}

static bool gatt_is_anybody_interested_in_connection(const RawAddress& bda) {
  if (connection_manager::is_background_connection(bda)) {
    log::debug("{} is in background connection", bda);
    return true;
  }

  for (size_t i = 1; i <= GATT_MAX_APPS; i++) {
    tGATT_REG* p_reg = &gatt_cb.cl_rcb[i - 1];
    if (p_reg->in_use && p_reg->direct_connect_request.count(bda) > 0) {
      log::debug("gatt_if {} interested in connection to {}", i, bda);
      return true;
    }
  }
  return false;
}

/** Cancel LE Create Connection request */
bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) {
  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
@@ -1535,6 +1551,9 @@ bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) {
        log::info("Removing {} from direct list", bda);
        p_reg->direct_connect_request.erase(bda);
      }
      if (!gatt_is_anybody_interested_in_connection(bda)) {
        gatt_cancel_connect(bda, static_cast<tBT_TRANSPORT>(BT_TRANSPORT_LE));
      }
      return true;
    }

+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_msg) { ret

void gatt_act_discovery(tGATT_CLCB* p_clcb) {}
bool gatt_disconnect(tGATT_TCB* p_tcb) { return false; }
void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport) {}
tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) { return GATT_CH_CLOSE; }
tGATT_STATUS gatts_db_read_attr_value_by_type(tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db,
                                              uint8_t op_code, BT_HDR* p_rsp, uint16_t s_handle,
Loading