*
******************************************************************************/
bool GATT_CancelConnect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct) {
- tGATT_REG* p_reg;
- tGATT_TCB* p_tcb;
- bool status = true;
- tGATT_IF temp_gatt_if;
- uint8_t start_idx, found_idx;
+ GATT_TRACE_API("%s: gatt_if=%d", __func__, gatt_if);
- GATT_TRACE_API("GATT_CancelConnect gatt_if=%d", gatt_if);
-
- if (gatt_if != 0) {
- p_reg = gatt_get_regcb(gatt_if);
- if (p_reg == NULL) {
- GATT_TRACE_ERROR("GATT_CancelConnect - gatt_if =%d is not registered",
- gatt_if);
- return (false);
- }
+ if (gatt_if && !gatt_get_regcb(gatt_if)) {
+ GATT_TRACE_ERROR("%s: gatt_if =%d is not registered", __func__, gatt_if);
+ return false;
}
if (is_direct) {
- if (!gatt_if) {
- GATT_TRACE_DEBUG("GATT_CancelConnect - unconditional");
- start_idx = 0;
- /* only LE connection can be cancelled */
- p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
- if (p_tcb && gatt_num_apps_hold_link(p_tcb)) {
- while (status && gatt_find_app_hold_link(p_tcb, start_idx, &found_idx,
- &temp_gatt_if)) {
- status = gatt_cancel_open(temp_gatt_if, bd_addr);
- start_idx = ++found_idx;
- }
- } else {
- GATT_TRACE_ERROR("GATT_CancelConnect - no app found");
- status = false;
- }
- } else {
- status = gatt_cancel_open(gatt_if, bd_addr);
+ if (gatt_if) {
+ return gatt_cancel_open(gatt_if, bd_addr);
}
- return status;
- } else {
- if (!gatt_if) {
- if (!gatt_clear_bg_dev_for_addr(bd_addr)) {
- GATT_TRACE_ERROR(
- "GATT_CancelConnect -no app associated with the bg device for "
- "unconditional removal");
- return false;
- }
- return true;
+ GATT_TRACE_DEBUG("%s: unconditional", __func__);
+ /* only LE connection can be cancelled */
+ tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
+ if (!p_tcb || p_tcb->app_hold_link.empty()) {
+ GATT_TRACE_ERROR("%s: no app found", __func__);
+ return false;
+ }
+
+ for (auto it = p_tcb->app_hold_link.begin();
+ it != p_tcb->app_hold_link.end();) {
+ auto next = std::next(it);
+ // gatt_cancel_open modifies the app_hold_link.
+ if (!gatt_cancel_open(*it, bd_addr)) return false;
+
+ it = next;
}
- return gatt_remove_bg_dev_for_app(gatt_if, bd_addr);
+
+ return true;
}
+ // is not direct
+ if (gatt_if) return gatt_remove_bg_dev_for_app(gatt_if, bd_addr);
+
+ if (!gatt_clear_bg_dev_for_addr(bd_addr)) {
+ GATT_TRACE_ERROR(
+ "%s: no app associated with the bg device for unconditional removal",
+ __func__);
+ return false;
+ }
+
+ return true;
}
/*******************************************************************************
tGATT_CH_STATE ch_state;
uint8_t ch_flags;
- tGATT_IF app_hold_link[GATT_MAX_APPS];
+ std::unordered_set<uint8_t> app_hold_link;
/* server needs */
/* server response data */
extern void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if,
bool is_inc, bool is_reset_first);
-extern bool gatt_find_app_hold_link(tGATT_TCB* p_tcb, uint8_t start_idx,
- uint8_t* p_found_idx, tGATT_IF* p_gatt_if);
-extern uint8_t gatt_num_apps_hold_link(tGATT_TCB* p_tcb);
extern uint8_t gatt_num_clcb_by_bd_addr(BD_ADDR bda);
extern tGATT_TCB* gatt_find_tcb_by_cid(uint16_t lcid);
extern tGATT_TCB* gatt_allocate_tcb_by_bdaddr(BD_ADDR bda,
******************************************************************************/
bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
bool is_add) {
- for (int i = 0; i < GATT_MAX_APPS; i++) {
- if (p_tcb->app_hold_link[i] == gatt_if && is_add) {
- GATT_TRACE_DEBUG("%s: gatt_if %d already exists at idx %d", __func__,
- gatt_if, i);
- return true;
+ auto& holders = p_tcb->app_hold_link;
+
+ if (is_add) {
+ auto ret = holders.insert(gatt_if);
+ if (ret.second) {
+ GATT_TRACE_DEBUG("%s: added gatt_if=%d", __func__, gatt_if);
+ } else {
+ GATT_TRACE_DEBUG("%s: attempt to add already existing gatt_if=%d",
+ __func__, gatt_if);
}
+ return true;
}
- for (int i = 0; i < GATT_MAX_APPS; i++) {
- if (p_tcb->app_hold_link[i] == 0 && is_add) {
- p_tcb->app_hold_link[i] = gatt_if;
- GATT_TRACE_DEBUG("%s: added gatt_if=%d idx=%d ", __func__, gatt_if, i);
- return true;
- } else if (p_tcb->app_hold_link[i] == gatt_if && !is_add) {
- p_tcb->app_hold_link[i] = 0;
- GATT_TRACE_DEBUG("%s: removed gatt_if=%d idx=%d", __func__, gatt_if, i);
- return true;
- }
+ //! is_add
+ if (!holders.erase(gatt_if)) {
+ GATT_TRACE_DEBUG("%s: attempt to remove nonexisting gatt_if=%d", __func__,
+ gatt_if);
+ return false;
}
- GATT_TRACE_DEBUG("%s: gatt_if=%d not found; is_add=%d", __func__, gatt_if,
- is_add);
- return false;
+ GATT_TRACE_DEBUG("%s: removed gatt_if=%d", __func__, gatt_if);
+ return true;
}
/*******************************************************************************
GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT,
p_tcb->transport);
} else {
- if (!gatt_num_apps_hold_link(p_tcb)) {
+ if (p_tcb->app_hold_link.empty()) {
/* acl link is connected but no application needs to use the link
so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds
*/
st = gatt_get_ch_state(p_tcb);
/* before link down, another app try to open a GATT connection */
- if (st == GATT_CH_OPEN && gatt_num_apps_hold_link(p_tcb) == 0 &&
+ if (st == GATT_CH_OPEN && p_tcb->app_hold_link.empty() &&
transport == BT_TRANSPORT_LE) {
if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys))
ret = false;
}
}
- if (gatt_num_apps_hold_link(p_tcb) && p_tcb->att_lcid == L2CAP_ATT_CID) {
+ if (!p_tcb->app_hold_link.empty() && p_tcb->att_lcid == L2CAP_ATT_CID) {
/* disable idle timeout if one or more clients are holding the link disable
* the idle timer */
GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT,
/*******************************************************************************
*
- * Function gatt_num_apps_hold_link
- *
- * Description The function find the number of applcaitions is holding the
- * link
- *
- * Returns total number of applications holding this acl link.
- *
- ******************************************************************************/
-uint8_t gatt_num_apps_hold_link(tGATT_TCB* p_tcb) {
- uint8_t i, num = 0;
-
- for (i = 0; i < GATT_MAX_APPS; i++) {
- if (p_tcb->app_hold_link[i]) num++;
- }
-
- GATT_TRACE_DEBUG("gatt_num_apps_hold_link num=%d", num);
- return num;
-}
-
-/*******************************************************************************
- *
* Function gatt_num_clcb_by_bd_addr
*
* Description The function searches all LCB with macthing bd address
status = false;
} else {
gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false);
- if (!gatt_num_apps_hold_link(p_tcb)) {
+ if (p_tcb->app_hold_link.empty()) {
gatt_disconnect(p_tcb);
}
}
return status;
}
-/*******************************************************************************
- *
- * Function gatt_find_app_hold_link
- *
- * Description find the applicaiton that is holding the specified link
- *
- * Returns Boolean
- *
- ******************************************************************************/
-bool gatt_find_app_hold_link(tGATT_TCB* p_tcb, uint8_t start_idx,
- uint8_t* p_found_idx, tGATT_IF* p_gatt_if) {
- uint8_t i;
- bool found = false;
-
- for (i = start_idx; i < GATT_MAX_APPS; i++) {
- if (p_tcb->app_hold_link[i]) {
- *p_gatt_if = gatt_cb.clcb[i].p_reg->gatt_if;
- *p_found_idx = i;
- found = true;
- break;
- }
- }
- return found;
-}
-
/** Enqueue this command */
void gatt_cmd_enq(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, bool to_send,
uint8_t op_code, BT_HDR* p_buf) {