void gatt_verify_signature(tGATT_TCB* p_tcb, BT_HDR* p_buf) {
uint16_t cmd_len;
uint8_t op_code;
- uint8_t *p, *p_orig = (uint8_t *)(p_buf + 1) + p_buf->offset;
+ uint8_t *p, *p_orig = (uint8_t*)(p_buf + 1) + p_buf->offset;
uint32_t counter;
if (p_buf->len < GATT_AUTH_SIGN_LEN + 4) {
******************************************************************************/
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);
}
******************************************************************************/
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;
+ GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
+ 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;
+
+ 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);
- GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
- p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
- if (p_tcb != NULL) {
- 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 (result == BTM_SUCCESS) {
- if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM) {
- BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);
-
- if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) {
- status = true;
- }
- } else {
- status = true;
- }
- }
- gatt_sec_check_complete(status, p_buf->p_clcb, p_tcb->sec_act);
- osi_free(p_buf);
- /* 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;
+ if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) {
+ status = true;
}
} else {
- GATT_TRACE_ERROR("Unknown operation encryption completed");
+ status = true;
}
- } else {
- GATT_TRACE_ERROR("enc callback for unknown bd_addr");
+ }
+
+ gatt_sec_check_complete(status, p_clcb, p_tcb->sec_act);
+
+ /* start all other pending operation in queue */
+ 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);
}
}
*
******************************************************************************/
void gatt_notify_enc_cmpl(BD_ADDR bd_addr) {
- tGATT_TCB* p_tcb;
- uint8_t i = 0;
-
- p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
- if (p_tcb != NULL) {
- for (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);
- }
+ 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;
+ }
+
+ 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);
}
+ }
- 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;
- }
+ if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) {
+ gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
+
+ 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;
}
/*******************************************************************************
*
}
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;
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:
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;
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;
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;
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);
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)
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;
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 {
/*******************************************************************************
*
- * 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
*
* Description Delete a device from the service changed client lit
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
*
******************************************************************************/
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];
-
- 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;
- }
+ 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();
+
+ 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 p_tcb;
+
+ return NULL;
}
/*******************************************************************************
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;
transport);
}
}
- memset(p_tcb, 0, sizeof(tGATT_TCB));
+ *p_tcb = tGATT_TCB();
}
GATT_TRACE_DEBUG("exit gatt_cleanup_upon_disc ");
}
}
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;
-}