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

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

Use std::queue for pending_enc_clcb

Test: 62188929
Change-Id: Ide07f15c5e5b6bc8b93ac350081b7bef7c7b3938
parent 3ec5bad6
Loading
Loading
Loading
Loading
+59 −79
Original line number Diff line number Diff line
@@ -128,8 +128,7 @@ void gatt_verify_signature(tGATT_TCB* p_tcb, BT_HDR* p_buf) {
 ******************************************************************************/
void gatt_sec_check_complete(bool sec_check_ok, tGATT_CLCB* p_clcb,
                             uint8_t sec_act) {
  if (p_clcb && p_clcb->p_tcb &&
      fixed_queue_is_empty(p_clcb->p_tcb->pending_enc_clcb)) {
  if (p_clcb && p_clcb->p_tcb && p_clcb->p_tcb->pending_enc_clcb.empty()) {
    gatt_set_sec_act(p_clcb->p_tcb, GATT_SEC_NONE);
  }

@@ -152,21 +151,27 @@ void gatt_sec_check_complete(bool sec_check_ok, tGATT_CLCB* p_clcb,
 ******************************************************************************/
void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport,
                         UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) {
  tGATT_TCB* p_tcb;
  uint8_t sec_flag;
  bool status = false;

  GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
  p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
  if (p_tcb != NULL) {
  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
  if (!p_tcb) {
    GATT_TRACE_ERROR("%s: enc callback for unknown bd_addr", __func__);
    return;
  }

  if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) return;

    tGATT_PENDING_ENC_CLCB* p_buf =
        (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
            p_tcb->pending_enc_clcb);
    if (p_buf != NULL) {
  if (p_tcb->pending_enc_clcb.empty()) {
    GATT_TRACE_ERROR("%s: no operation waiting for encrypting", __func__);
    return;
  }

  tGATT_CLCB* p_clcb = p_tcb->pending_enc_clcb.front();
  p_tcb->pending_enc_clcb.pop();

  bool status = false;
  if (result == BTM_SUCCESS) {
    if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM) {
      uint8_t sec_flag = 0;
      BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);

      if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) {
@@ -176,24 +181,14 @@ void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport,
      status = true;
    }
  }
      gatt_sec_check_complete(status, p_buf->p_clcb, p_tcb->sec_act);
      osi_free(p_buf);

  gatt_sec_check_complete(status, p_clcb, p_tcb->sec_act);

  /* start all other pending operation in queue */
      for (size_t count = fixed_queue_length(p_tcb->pending_enc_clcb);
           count > 0; count--) {
        p_buf = (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
            p_tcb->pending_enc_clcb);
        if (p_buf != NULL) {
          gatt_security_check_start(p_buf->p_clcb);
          osi_free(p_buf);
        } else
          break;
      }
    } else {
      GATT_TRACE_ERROR("Unknown operation encryption completed");
    }
  } else {
    GATT_TRACE_ERROR("enc callback for unknown bd_addr");
  while (!p_tcb->pending_enc_clcb.empty()) {
    tGATT_CLCB* p_clcb = p_tcb->pending_enc_clcb.front();
    p_tcb->pending_enc_clcb.pop();
    gatt_security_check_start(p_clcb);
  }
}

@@ -208,12 +203,13 @@ void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport,
 *
 ******************************************************************************/
void gatt_notify_enc_cmpl(BD_ADDR bd_addr) {
  tGATT_TCB* p_tcb;
  uint8_t i = 0;
  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
  if (!p_tcb) {
    GATT_TRACE_DEBUG("notify GATT for encryption completion of unknown device");
    return;
  }

  p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
  if (p_tcb != NULL) {
    for (i = 0; i < GATT_MAX_APPS; i++) {
  for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
    if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb) {
      (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if,
                                                bd_addr);
@@ -223,22 +219,12 @@ void gatt_notify_enc_cmpl(BD_ADDR bd_addr) {
  if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) {
    gatt_set_sec_act(p_tcb, GATT_SEC_NONE);

      size_t count = fixed_queue_length(p_tcb->pending_enc_clcb);
      for (; count > 0; count--) {
        tGATT_PENDING_ENC_CLCB* p_buf =
            (tGATT_PENDING_ENC_CLCB*)fixed_queue_try_dequeue(
                p_tcb->pending_enc_clcb);
        if (p_buf != NULL) {
          gatt_security_check_start(p_buf->p_clcb);
          osi_free(p_buf);
        } else
          break;
    while (!p_tcb->pending_enc_clcb.empty()) {
      tGATT_CLCB* p_clcb = p_tcb->pending_enc_clcb.front();
      p_tcb->pending_enc_clcb.pop();
      gatt_security_check_start(p_clcb);
    }
  }
  } else {
    GATT_TRACE_DEBUG("notify GATT for encryption completion of unknown device");
  }
  return;
}
/*******************************************************************************
 *
@@ -270,16 +256,10 @@ tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB* p_tcb) {
  }
  return sec_act;
}
/*******************************************************************************
 *
 * Function         gatt_determine_sec_act
 *
 * Description      This routine determine the security action based on
 *                  auth_request and current link status
 *
 * Returns          tGATT_SEC_ACTION security action
 *
 ******************************************************************************/
/**
 * This routine determine the security action based on auth_request and current
 * link status. Returns tGATT_SEC_ACTION (security action)
 */
tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB* p_clcb) {
  tGATT_SEC_ACTION act = GATT_SEC_OK;
  uint8_t sec_flag;
@@ -455,10 +435,10 @@ bool gatt_security_check_start(tGATT_CLCB* p_clcb) {
          status = false;
        }
      }
      if (status) gatt_add_pending_enc_channel_clcb(p_tcb, p_clcb);
      if (status) p_tcb->pending_enc_clcb.push(p_clcb);
      break;
    case GATT_SEC_ENC_PENDING:
      gatt_add_pending_enc_channel_clcb(p_tcb, p_clcb);
      p_tcb->pending_enc_clcb.push(p_clcb);
      /* wait for link encrypotion to finish */
      break;
    default:
+5 −8
Original line number Diff line number Diff line
@@ -260,8 +260,10 @@ typedef struct {
  bool is_primary;
} tGATT_SRV_LIST_ELEM;

struct tGATT_CLCB;

typedef struct {
  fixed_queue_t* pending_enc_clcb; /* pending encryption channel q */
  std::queue<tGATT_CLCB*> pending_enc_clcb; /* pending encryption channel q */
  tGATT_SEC_ACTION sec_act;
  BD_ADDR peer_bda;
  tBT_TRANSPORT transport;
@@ -302,7 +304,7 @@ typedef struct {
  tGATT_DISC_RES result;
  bool wait_for_read_rsp;
} tGATT_READ_INC_UUID128;
typedef struct {
struct tGATT_CLCB {
  tGATT_TCB* p_tcb; /* associated TCB of this CLCB */
  tGATT_REG* p_reg; /* owner of this CLCB */
  uint8_t sccb_idx;
@@ -323,10 +325,7 @@ typedef struct {
  bool in_use;
  alarm_t* gatt_rsp_timer_ent; /* peer response timer */
  uint8_t retry_count;

} tGATT_CLCB;

typedef struct { tGATT_CLCB* p_clcb; } tGATT_PENDING_ENC_CLCB;
};

typedef struct {
  uint16_t handle;
@@ -458,8 +457,6 @@ extern tGATT_STATUS gatt_send_error_rsp(tGATT_TCB* p_tcb, uint8_t err_code,
                                        uint8_t op_code, uint16_t handle,
                                        bool deq);
extern void gatt_dbg_display_uuid(tBT_UUID bt_uuid);
extern tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(
    tGATT_TCB* p_tcb, tGATT_CLCB* p_clcb);

extern bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb);
extern tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(BD_ADDR bda);
+3 −5
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ void gatt_init(void) {

  GATT_TRACE_DEBUG("gatt_init()");

  memset(&gatt_cb, 0, sizeof(tGATT_CB));
  gatt_cb = tGATT_CB();
  memset(&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));

#if defined(GATT_INITIAL_TRACE_LEVEL)
@@ -158,8 +158,7 @@ void gatt_free(void) {
  fixed_queue_free(gatt_cb.srv_chg_clt_q, NULL);
  gatt_cb.srv_chg_clt_q = NULL;
  for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
    fixed_queue_free(gatt_cb.tcb[i].pending_enc_clcb, NULL);
    gatt_cb.tcb[i].pending_enc_clcb = NULL;
    gatt_cb.tcb[i].pending_enc_clcb = std::queue<tGATT_CLCB*>();

    fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL);
    gatt_cb.tcb[i].pending_ind_q = NULL;
@@ -375,9 +374,8 @@ bool gatt_act_connect(tGATT_REG* p_reg, BD_ADDR bd_addr,
    if (p_tcb != NULL) {
      if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys)) {
        GATT_TRACE_ERROR("gatt_connect failed");
        fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
        fixed_queue_free(p_tcb->pending_ind_q, NULL);
        memset(p_tcb, 0, sizeof(tGATT_TCB));
        *p_tcb = tGATT_TCB();
      } else
        ret = true;
    } else {
+19 −88
Original line number Diff line number Diff line
@@ -100,27 +100,6 @@ void gatt_free_pending_ind(tGATT_TCB* p_tcb) {
  p_tcb->pending_ind_q = NULL;
}

/*******************************************************************************
 *
 * Function         gatt_free_pending_enc_queue
 *
 * Description       Free all buffers in pending encyption queue
 *
 * Returns       None
 *
 ******************************************************************************/
void gatt_free_pending_enc_queue(tGATT_TCB* p_tcb) {
  GATT_TRACE_DEBUG("%s", __func__);

  if (p_tcb->pending_enc_clcb == NULL) return;

  /* release all queued indications */
  while (!fixed_queue_is_empty(p_tcb->pending_enc_clcb))
    osi_free(fixed_queue_try_dequeue(p_tcb->pending_enc_clcb));
  fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
  p_tcb->pending_enc_clcb = NULL;
}

/*******************************************************************************
 *
 * Function         gatt_delete_dev_from_srv_chg_clt_list
@@ -449,26 +428,7 @@ tGATT_TCB* gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) {

  return p_tcb;
}
/*******************************************************************************
 *
 * Function         gatt_find_i_tcb_free
 *
 * Description      Search for an empty tcb entry, and return the index.
 *
 * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
 *
 ******************************************************************************/
uint8_t gatt_find_i_tcb_free(void) {
  uint8_t i = 0, j = GATT_INDEX_INVALID;

  for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
    if (!gatt_cb.tcb[i].in_use) {
      j = i;
      break;
    }
  }
  return j;
}
/*******************************************************************************
 *
 * Function         gatt_allocate_tcb_by_bdaddr
@@ -479,35 +439,30 @@ uint8_t gatt_find_i_tcb_free(void) {
 *
 ******************************************************************************/
tGATT_TCB* gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) {
  uint8_t i = 0;
  bool allocated = false;
  tGATT_TCB* p_tcb = NULL;

  /* search for existing tcb with matching bda    */
  i = gatt_find_i_tcb_by_addr(bda, transport);
  uint8_t j = gatt_find_i_tcb_by_addr(bda, transport);
  if (j != GATT_INDEX_INVALID) return &gatt_cb.tcb[j];

  /* find free tcb */
  if (i == GATT_INDEX_INVALID) {
    i = gatt_find_i_tcb_free();
    allocated = true;
  }
  if (i != GATT_INDEX_INVALID) {
    p_tcb = &gatt_cb.tcb[i];
  for (int i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
    tGATT_TCB* p_tcb = &gatt_cb.tcb[i];
    if (p_tcb->in_use) continue;

    *p_tcb = tGATT_TCB();

    if (allocated) {
      memset(p_tcb, 0, sizeof(tGATT_TCB));
      p_tcb->pending_enc_clcb = fixed_queue_new(SIZE_MAX);
    p_tcb->pending_ind_q = fixed_queue_new(SIZE_MAX);
    p_tcb->conf_timer = alarm_new("gatt.conf_timer");
    p_tcb->ind_ack_timer = alarm_new("gatt.ind_ack_timer");
    p_tcb->in_use = true;
    p_tcb->tcb_idx = i;
    p_tcb->transport = transport;
    }
    memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
  }
    return p_tcb;
  }

  return NULL;
}

/*******************************************************************************
 *
 * Function         gatt_convert_uuid16_to_uuid128
@@ -1608,7 +1563,6 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, uint16_t reason,
    alarm_free(p_tcb->conf_timer);
    p_tcb->conf_timer = NULL;
    gatt_free_pending_ind(p_tcb);
    gatt_free_pending_enc_queue(p_tcb);
    fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
    p_tcb->sr_cmd.multi_rsp_q = NULL;

@@ -1622,7 +1576,7 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, uint16_t reason,
                                   transport);
      }
    }
    memset(p_tcb, 0, sizeof(tGATT_TCB));
    *p_tcb = tGATT_TCB();
  }
  GATT_TRACE_DEBUG("exit gatt_cleanup_upon_disc ");
}
@@ -1991,26 +1945,3 @@ bool gatt_update_auto_connect_dev(tGATT_IF gatt_if, bool add, BD_ADDR bd_addr) {
  }
  return ret;
}

/*******************************************************************************
 *
 * Function     gatt_add_pending_new_srv_start
 *
 * Description  Add a pending new srv start to the new service start queue
 *
 * Returns    Pointer to the new service start buffer, NULL no buffer available
 *
 ******************************************************************************/
tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB* p_tcb,
                                                          tGATT_CLCB* p_clcb) {
  tGATT_PENDING_ENC_CLCB* p_buf =
      (tGATT_PENDING_ENC_CLCB*)osi_malloc(sizeof(tGATT_PENDING_ENC_CLCB));

  GATT_TRACE_DEBUG("%s", __func__);
  GATT_TRACE_DEBUG("enqueue a new pending encryption channel clcb");

  p_buf->p_clcb = p_clcb;
  fixed_queue_enqueue(p_tcb->pending_enc_clcb, p_buf);

  return p_buf;
}