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

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

Use std::unordered_set for keeping app_hold_link

Change-Id: Ia8a0c9a2264979c1ff89faa5ddf17a83fcb7c7ce
parent db5fc3de
Loading
Loading
Loading
Loading
+34 −42
Original line number Diff line number Diff line
@@ -1327,57 +1327,49 @@ bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
 *
 ******************************************************************************/
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("GATT_CancelConnect gatt_if=%d", gatt_if);
  GATT_TRACE_API("%s: gatt_if=%d", __func__, 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;
    if (gatt_if) {
      return gatt_cancel_open(gatt_if, bd_addr);
    }

    GATT_TRACE_DEBUG("%s: unconditional", __func__);
    /* 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;
    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;
    }
      } else {
        GATT_TRACE_ERROR("GATT_CancelConnect - no app found");
        status = 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;
    }
    } else {
      status = gatt_cancel_open(gatt_if, bd_addr);

    return true;
  }
  // is not direct

  if (gatt_if) return gatt_remove_bg_dev_for_app(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");
        "%s: no app associated with the bg device for unconditional removal",
        __func__);
    return false;
  }
      return true;
    }
    return gatt_remove_bg_dev_for_app(gatt_if, bd_addr);
  }

  return true;
}

/*******************************************************************************
+1 −4
Original line number Diff line number Diff line
@@ -276,7 +276,7 @@ typedef struct {
  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 */
@@ -518,9 +518,6 @@ extern void gatt_sr_update_cback_cnt(tGATT_TCB& p_tcb, tGATT_IF gatt_if,
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,
+20 −21
Original line number Diff line number Diff line
@@ -266,31 +266,30 @@ bool gatt_disconnect(tGATT_TCB* p_tcb) {
 ******************************************************************************/
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;

  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;
  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;
  }

  GATT_TRACE_DEBUG("%s: gatt_if=%d not found; is_add=%d", __func__, gatt_if,
                   is_add);
  //! 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: removed gatt_if=%d", __func__, gatt_if);
  return true;
}

/*******************************************************************************
 *
 * Function         gatt_update_app_use_link_flag
@@ -327,7 +326,7 @@ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
    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
         */
@@ -361,7 +360,7 @@ bool gatt_act_connect(tGATT_REG* p_reg, BD_ADDR bd_addr,
    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;
@@ -920,7 +919,7 @@ static void gatt_send_conn_cback(tGATT_TCB* p_tcb) {
    }
  }

  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,
+1 −47
Original line number Diff line number Diff line
@@ -1082,27 +1082,6 @@ tGATT_TCB* gatt_find_tcb_by_cid(uint16_t lcid) {
  return p_tcb;
}

/*******************************************************************************
 *
 * 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
@@ -1271,7 +1250,7 @@ bool gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) {
      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);
      }
    }
@@ -1280,31 +1259,6 @@ bool gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) {
  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) {