mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(ble/bluedroid): fix GATT protocol and database operation issues
- Fix GATTC read by type length error and rsp pdu format check
- Fix p_cur_handle update in gatts_db_read_attr_value_by_type
- Fix len calculation error in calculate_database_info_size
- Replace gatt_find_the_connected_bda with p_tcb_list iteration
- Send cmd reject if cid is invalid
- Fix param_len check in smp_rand_back
- Remove duplicate uuid compare functions
(cherry picked from commit 6242e0244c)
Co-authored-by: zhiweijian <zhiweijian@espressif.com>
This commit is contained in:
@@ -775,6 +775,7 @@ BOOLEAN gap_ble_accept_cl_operation(BD_ADDR peer_bda, UINT16 uuid, tGAP_BLE_CMPL
|
||||
{
|
||||
tGAP_CLCB *p_clcb;
|
||||
BOOLEAN started = FALSE;
|
||||
BOOLEAN is_new_clcb = FALSE;
|
||||
|
||||
if (p_cback == NULL && uuid != GATT_UUID_GAP_PREF_CONN_PARAM) {
|
||||
return (started);
|
||||
@@ -785,6 +786,7 @@ BOOLEAN gap_ble_accept_cl_operation(BD_ADDR peer_bda, UINT16 uuid, tGAP_BLE_CMPL
|
||||
GAP_TRACE_ERROR("gap_ble_accept_cl_operation max connection reached");
|
||||
return started;
|
||||
}
|
||||
is_new_clcb = TRUE;
|
||||
}
|
||||
|
||||
GAP_TRACE_EVENT ("%s() - BDA: %08x%04x cl_op_uuid: 0x%04x",
|
||||
@@ -798,11 +800,25 @@ BOOLEAN gap_ble_accept_cl_operation(BD_ADDR peer_bda, UINT16 uuid, tGAP_BLE_CMPL
|
||||
|
||||
/* hold the link here */
|
||||
if (!GATT_Connect(gap_cb.gatt_if, p_clcb->bda, BLE_ADDR_UNKNOWN_TYPE, TRUE, BT_TRANSPORT_LE, FALSE, FALSE, 0xFF, 0xFF)) {
|
||||
if (is_new_clcb) {
|
||||
gap_ble_dealloc_clcb(p_clcb);
|
||||
}
|
||||
return started;
|
||||
}
|
||||
|
||||
/* enqueue the request */
|
||||
gap_ble_enqueue_request(p_clcb, uuid, p_cback);
|
||||
if (gap_ble_enqueue_request(p_clcb, uuid, p_cback) == FALSE) {
|
||||
GAP_TRACE_ERROR("gap_ble_accept_cl_operation enqueue request failed");
|
||||
if (is_new_clcb) {
|
||||
if (p_clcb->connected) {
|
||||
GATT_Disconnect(p_clcb->conn_id);
|
||||
} else {
|
||||
GATT_CancelConnect(gap_cb.gatt_if, p_clcb->bda, TRUE);
|
||||
}
|
||||
gap_ble_dealloc_clcb(p_clcb);
|
||||
}
|
||||
return started;
|
||||
}
|
||||
|
||||
if (p_clcb->connected && p_clcb->cl_op_uuid == 0) {
|
||||
started = gap_ble_send_cl_read_request(p_clcb);
|
||||
|
||||
@@ -166,6 +166,11 @@ BT_HDR *attp_build_read_by_type_value_cmd (UINT16 payload_size, tGATT_FIND_TYPE_
|
||||
UINT8 *p;
|
||||
UINT16 len = p_value_type->value_len;
|
||||
|
||||
if (payload_size < GATT_DEF_BLE_MTU_SIZE) {
|
||||
// never build packet smaller than default MTU size
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((p_buf = (BT_HDR *)osi_malloc((UINT16)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET))) != NULL) {
|
||||
p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
|
||||
|
||||
|
||||
@@ -1029,6 +1029,12 @@ tGATT_STATUS GATTC_Read (UINT16 conn_id, tGATT_READ_TYPE type, tGATT_READ_PARAM
|
||||
p_clcb->s_handle = 0;
|
||||
/* copy multiple handles in CB */
|
||||
p_read_multi = (tGATT_READ_MULTI *)osi_malloc(sizeof(tGATT_READ_MULTI));
|
||||
if (p_read_multi == NULL) {
|
||||
GATT_TRACE_ERROR("GATTC_Read no resources for multiple read");
|
||||
status = GATT_NO_RESOURCES;
|
||||
gatt_clcb_dealloc(p_clcb);
|
||||
return status;
|
||||
}
|
||||
p_clcb->p_attr_buf = (UINT8 *)p_read_multi;
|
||||
memcpy (p_read_multi, &p_read->read_multiple, sizeof(tGATT_READ_MULTI));
|
||||
case GATT_READ_BY_HANDLE:
|
||||
@@ -1382,7 +1388,8 @@ void GATT_Deregister (tGATT_IF gatt_if)
|
||||
(p_clcb->p_tcb->tcb_idx == p_tcb->tcb_idx)) {
|
||||
btu_stop_timer(&p_clcb->rsp_timer_ent);
|
||||
gatt_clcb_dealloc (p_clcb);
|
||||
break;
|
||||
// Removed break to ensure all CLCBs are cleaned up
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1394,6 +1401,10 @@ void GATT_Deregister (tGATT_IF gatt_if)
|
||||
memset (p_reg, 0, sizeof(tGATT_REG));
|
||||
}
|
||||
|
||||
void gatt_start_if_conn_cb(UINT8 tcb_idx, tBT_TRANSPORT transport, BD_ADDR bda)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -1412,21 +1423,19 @@ void GATT_StartIf (tGATT_IF gatt_if)
|
||||
{
|
||||
tGATT_REG *p_reg;
|
||||
tGATT_TCB *p_tcb;
|
||||
BD_ADDR bda;
|
||||
UINT8 start_idx, found_idx;
|
||||
UINT16 conn_id;
|
||||
tGATT_TRANSPORT transport ;
|
||||
list_node_t *p_node = NULL;
|
||||
|
||||
GATT_TRACE_API ("GATT_StartIf gatt_if=%d", gatt_if);
|
||||
if ((p_reg = gatt_get_regcb(gatt_if)) != NULL) {
|
||||
start_idx = 0;
|
||||
while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) {
|
||||
p_tcb = gatt_find_tcb_by_addr(bda, transport);
|
||||
if (p_reg->app_cb.p_conn_cb && p_tcb) {
|
||||
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if);
|
||||
(*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, TRUE, 0, transport);
|
||||
for (p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
|
||||
p_tcb = list_node(p_node);
|
||||
if (p_tcb->in_use && p_tcb->ch_state == GATT_CH_OPEN) {
|
||||
if (p_reg->app_cb.p_conn_cb && p_tcb) {
|
||||
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if);
|
||||
(*p_reg->app_cb.p_conn_cb)(gatt_if, p_tcb->peer_bda, conn_id, TRUE, 0, p_tcb->transport);
|
||||
}
|
||||
}
|
||||
start_idx = ++found_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1593,11 +1602,10 @@ tGATT_STATUS GATT_Disconnect (UINT16 conn_id)
|
||||
*******************************************************************************/
|
||||
tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr)
|
||||
{
|
||||
UINT8 start_idx, found_idx;
|
||||
BOOLEAN srv_chg_ind_pending = FALSE;
|
||||
tGATT_TCB *p_tcb;
|
||||
tBT_TRANSPORT transport;
|
||||
tGATT_STATUS status = GATT_NOT_FOUND;
|
||||
list_node_t *p_node = NULL;
|
||||
|
||||
if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) {
|
||||
status = GATT_WRONG_STATE;
|
||||
@@ -1608,19 +1616,17 @@ tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr)
|
||||
if(bd_addr) {
|
||||
status = gatt_send_srv_chg_ind(bd_addr);
|
||||
} else {
|
||||
start_idx = 0;
|
||||
BD_ADDR addr;
|
||||
while (gatt_find_the_connected_bda(start_idx, addr, &found_idx, &transport)) {
|
||||
p_tcb = gatt_get_tcb_by_idx(found_idx);
|
||||
srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb);
|
||||
|
||||
if (!srv_chg_ind_pending) {
|
||||
status = gatt_send_srv_chg_ind(addr);
|
||||
} else {
|
||||
status = GATT_BUSY;
|
||||
GATT_TRACE_DEBUG("discard srv chg - already has one in the queue");
|
||||
for (p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
|
||||
p_tcb = list_node(p_node);
|
||||
if (p_tcb->in_use && p_tcb->ch_state == GATT_CH_OPEN) {
|
||||
srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb);
|
||||
if (!srv_chg_ind_pending) {
|
||||
status = gatt_send_srv_chg_ind(p_tcb->peer_bda);
|
||||
} else {
|
||||
status = GATT_BUSY;
|
||||
GATT_TRACE_DEBUG("discard srv chg - already has one in the queue");
|
||||
}
|
||||
}
|
||||
start_idx = ++found_idx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,8 @@ static BOOLEAN gatt_sign_data (tGATT_CLCB *p_clcb)
|
||||
}
|
||||
|
||||
osi_free(p_data);
|
||||
} else {
|
||||
gatt_end_operation(p_clcb, GATT_NO_RESOURCES, NULL);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -449,7 +449,7 @@ void gatt_process_find_type_value_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UIN
|
||||
void gatt_process_read_info_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
|
||||
UINT16 len, UINT8 *p_data)
|
||||
{
|
||||
tGATT_DISC_RES result;
|
||||
tGATT_DISC_RES result = {0};
|
||||
UINT8 *p = p_data, uuid_len = 0, type;
|
||||
|
||||
UNUSED(p_tcb);
|
||||
@@ -472,6 +472,10 @@ void gatt_process_read_info_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_c
|
||||
uuid_len = LEN_UUID_16;
|
||||
} else if (type == GATT_INFO_TYPE_PAIR_128) {
|
||||
uuid_len = LEN_UUID_128;
|
||||
} else {
|
||||
GATT_TRACE_ERROR("invalid Info Response PDU format: %d", type);
|
||||
gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
while (len >= uuid_len + 2) {
|
||||
@@ -796,7 +800,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
|
||||
if ((value_len > (p_tcb->payload_size - 2)) || (value_len > (len - 1)) ) {
|
||||
/* this is an error case that server's response containing a value length which is larger than MTU-2
|
||||
or value_len > message total length -1 */
|
||||
GATT_TRACE_ERROR("gatt_process_read_by_type_rsp: Discard response op_code=%d vale_len=%d > (MTU-2=%d or msg_len-1=%d)",
|
||||
GATT_TRACE_ERROR("gatt_process_read_by_type_rsp: Discard response op_code=%d value_len=%d > (MTU-2=%d or msg_len-1=%d)",
|
||||
op_code, value_len, (p_tcb->payload_size - 2), (len - 1));
|
||||
gatt_end_operation(p_clcb, GATT_ERROR, NULL);
|
||||
return;
|
||||
@@ -884,7 +888,8 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
|
||||
}
|
||||
/* read by type */
|
||||
else if (p_clcb->operation == GATTC_OPTYPE_READ && p_clcb->op_subtype == GATT_READ_BY_TYPE) {
|
||||
p_clcb->counter = len - 2;
|
||||
/* value_len is the length of current record's value; use it to avoid overread when multiple records present */
|
||||
p_clcb->counter = value_len;
|
||||
p_clcb->s_handle = handle;
|
||||
if ( p_clcb->counter == (p_clcb->p_tcb->payload_size - 4)) {
|
||||
p_clcb->op_subtype = GATT_READ_BY_HANDLE;
|
||||
@@ -916,7 +921,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
|
||||
|
||||
/* UUID not matching */
|
||||
if (!gatt_uuid_compare(record_value.dclr_value.char_uuid, p_clcb->uuid)) {
|
||||
len -= (value_len + 2);
|
||||
len -= (value_len + handle_len);
|
||||
continue; /* skip the result, and look for next one */
|
||||
} else if (p_clcb->operation == GATTC_OPTYPE_READ)
|
||||
/* UUID match for read characteristic value */
|
||||
@@ -1000,7 +1005,7 @@ void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
|
||||
gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p_clcb->p_attr_buf);
|
||||
}
|
||||
} else { /* exception, should not happen */
|
||||
GATT_TRACE_ERROR("attr offset = %d p_attr_buf = %p ", offset, p_clcb->p_attr_buf);
|
||||
GATT_TRACE_ERROR("attr offset = %d p_attr_buf = %p ", offset, p_clcb->p_attr_buf ? p_clcb->p_attr_buf:0);
|
||||
gatt_end_operation(p_clcb, GATT_NO_RESOURCES, (void *)p_clcb->p_attr_buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,6 +363,7 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb,
|
||||
|
||||
if (p_attr->handle >= s_handle && gatt_uuid_compare(type, attr_uuid)) {
|
||||
if (*p_len <= 2) {
|
||||
*p_cur_handle = p_attr->handle;
|
||||
status = GATT_NO_RESOURCES;
|
||||
break;
|
||||
}
|
||||
@@ -375,15 +376,19 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb,
|
||||
|
||||
need_rsp = TRUE;
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id, need_rsp);
|
||||
|
||||
if (status != GATT_PENDING) {
|
||||
*p_cur_handle = p_attr->handle;
|
||||
}
|
||||
/* one callback at a time */
|
||||
break;
|
||||
} else if (status == GATT_SUCCESS || status == GATT_STACK_RSP) {
|
||||
if (status == GATT_STACK_RSP){
|
||||
need_rsp = FALSE;
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id, need_rsp);
|
||||
if(status == GATT_BUSY)
|
||||
if (status != GATT_STACK_RSP) {
|
||||
*p_cur_handle = p_attr->handle;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!have_send_request){
|
||||
have_send_request = true;
|
||||
@@ -400,6 +405,7 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb,
|
||||
*p_len -= (len + 2);
|
||||
} else {
|
||||
GATT_TRACE_WARNING("format mismatch");
|
||||
*p_cur_handle = p_attr->handle;
|
||||
status = GATT_NO_RESOURCES;
|
||||
break;
|
||||
}
|
||||
@@ -546,6 +552,7 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
|
||||
|
||||
if (attr_val != NULL) {
|
||||
if (!copy_extra_byte_in_db(p_db, (void **)&p_char_val->p_value, sizeof(tGATT_ATTR_VAL))) {
|
||||
deallocate_attr_in_db(p_db, p_char_decl);
|
||||
deallocate_attr_in_db(p_db, p_char_val);
|
||||
return 0;
|
||||
}
|
||||
@@ -733,7 +740,7 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
||||
}
|
||||
|
||||
p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
|
||||
|
||||
BOOLEAN found = FALSE;
|
||||
while (p_cur != NULL) {
|
||||
if (p_cur->handle == attr_handle) {
|
||||
/* for characteristic should not be set, return GATT_NOT_FOUND */
|
||||
@@ -758,13 +765,14 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
||||
} else{
|
||||
memcpy(p_cur->p_value->attr_val.attr_val, value, length);
|
||||
p_cur->p_value->attr_val.attr_len = length;
|
||||
found = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
p_cur = p_cur->p_next;
|
||||
}
|
||||
|
||||
return GATT_SUCCESS;
|
||||
return found ? GATT_SUCCESS : GATT_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -1205,8 +1213,8 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
|
||||
GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION,handle %04x,perm %04x", handle, perm);
|
||||
}
|
||||
/* LE security mode 2 attribute */
|
||||
else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)
|
||||
&& (perm & GATT_WRITE_ALLOWED) == 0) {
|
||||
else if ((perm & GATT_WRITE_SIGNED_PERM) && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)
|
||||
&& !(perm & (GATT_PERM_WRITE | GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM))) {
|
||||
status = GATT_INSUF_AUTHENTICATION;
|
||||
GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required,handle %04x,perm %04x", handle, perm);
|
||||
} else { /* writable: must be char value declaration or char descriptors */
|
||||
|
||||
@@ -1174,27 +1174,25 @@ void gatt_init_srv_chg (void)
|
||||
#if (GATTS_INCLUDED == TRUE)
|
||||
void gatt_proc_srv_chg (void)
|
||||
{
|
||||
UINT8 start_idx, found_idx;
|
||||
BD_ADDR bda;
|
||||
BOOLEAN srv_chg_ind_pending = FALSE;
|
||||
tGATT_TCB *p_tcb;
|
||||
tBT_TRANSPORT transport;
|
||||
list_node_t *p_node = NULL;
|
||||
|
||||
GATT_TRACE_DEBUG ("gatt_proc_srv_chg");
|
||||
|
||||
if (gatt_cb.cb_info.p_srv_chg_callback && gatt_cb.handle_of_h_r) {
|
||||
gatt_set_srv_chg();
|
||||
start_idx = 0;
|
||||
while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) {
|
||||
p_tcb = gatt_get_tcb_by_idx(found_idx);
|
||||
srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb);
|
||||
|
||||
if (!srv_chg_ind_pending) {
|
||||
gatt_send_srv_chg_ind(bda);
|
||||
} else {
|
||||
GATT_TRACE_DEBUG ("discard srv chg - already has one in the queue");
|
||||
for (p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) {
|
||||
p_tcb = list_node(p_node);
|
||||
if (p_tcb->in_use && p_tcb->ch_state == GATT_CH_OPEN) {
|
||||
srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb);
|
||||
if (!srv_chg_ind_pending) {
|
||||
gatt_send_srv_chg_ind(p_tcb->peer_bda);
|
||||
} else {
|
||||
GATT_TRACE_DEBUG ("discard srv chg - already has one in the queue");
|
||||
}
|
||||
}
|
||||
start_idx = ++found_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +166,12 @@ static BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status,
|
||||
|
||||
GATT_TRACE_DEBUG ("process_read_multi_rsp status=%d mtu=%d", status, mtu);
|
||||
|
||||
if (!p_msg) {
|
||||
p_cmd->status = GATT_INVALID_PDU;
|
||||
GATT_TRACE_ERROR("process_read_multi_rsp - invalid p_msg");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (p_cmd->multi_rsp_q == NULL) {
|
||||
p_cmd->multi_rsp_q = fixed_queue_new(QUEUE_SIZE_MAX);
|
||||
}
|
||||
@@ -287,6 +293,12 @@ static BOOLEAN process_read_multi_var_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS sta
|
||||
|
||||
GATT_TRACE_DEBUG ("process_read_multi_var rsp status=%d mtu=%d", status, mtu);
|
||||
|
||||
if (!p_msg) {
|
||||
GATT_TRACE_ERROR("process_read_multi_var_rsp - invalid p_msg");
|
||||
p_cmd->status = GATT_INVALID_PDU;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (p_cmd->multi_rsp_q == NULL) {
|
||||
p_cmd->multi_rsp_q = fixed_queue_new(QUEUE_SIZE_MAX);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,15 @@ static void attr_uuid_to_bt_uuid(void *p_attr, tBT_UUID *p_uuid)
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 get_uuid_stream_len(tBT_UUID uuid)
|
||||
{
|
||||
// gatt_build_uuid_to_stream always converts 32-bit UUID to 128-bit UUID
|
||||
if (uuid.len == LEN_UUID_32) {
|
||||
return LEN_UUID_128;
|
||||
}
|
||||
return uuid.len;
|
||||
}
|
||||
|
||||
static size_t calculate_database_info_size(void)
|
||||
{
|
||||
UINT8 i;
|
||||
@@ -71,17 +80,17 @@ static size_t calculate_database_info_size(void)
|
||||
if (p_attr->uuid == GATT_UUID_PRI_SERVICE ||
|
||||
p_attr->uuid == GATT_UUID_SEC_SERVICE) {
|
||||
// Service declaration
|
||||
len += 4 + p_attr->p_value->uuid.len;
|
||||
len += 4 + get_uuid_stream_len(p_attr->p_value->uuid);
|
||||
} else if (p_attr->uuid == GATT_UUID_INCLUDE_SERVICE) {
|
||||
// Included service declaration
|
||||
len += 8 + p_attr->p_value->incl_handle.service_type.len;
|
||||
len += 8 + get_uuid_stream_len(p_attr->p_value->incl_handle.service_type);
|
||||
} else if (p_attr->uuid == GATT_UUID_CHAR_DECLARE) {
|
||||
tBT_UUID char_uuid = {0};
|
||||
// Characteristic declaration
|
||||
p_attr = (tGATT_ATTR16 *)p_attr->p_next;
|
||||
attr_uuid_to_bt_uuid((void *)p_attr, &char_uuid);
|
||||
// Increment 1 to fetch characteristic uuid from value declaration attribute
|
||||
len += 7 + char_uuid.len;
|
||||
len += 7 + get_uuid_stream_len(char_uuid);
|
||||
} else if (p_attr->uuid == GATT_UUID_CHAR_DESCRIPTION ||
|
||||
p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG ||
|
||||
p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG ||
|
||||
|
||||
@@ -74,7 +74,7 @@ const char *const op_code_name[] = {
|
||||
"ATT_OP_CODE_MAX"
|
||||
};
|
||||
|
||||
static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
|
||||
const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
|
||||
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
@@ -216,11 +216,12 @@ tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid128, tB
|
||||
list_t *list = fixed_queue_get_list(gatt_cb.pending_new_srv_start_q);
|
||||
for (const list_node_t *node = list_begin(list); node != list_end(list);
|
||||
node = list_next(node)) {
|
||||
p_buf = (tGATTS_PENDING_NEW_SRV_START *)list_node(node);
|
||||
tGATTS_HNDL_RANGE *p = p_buf->p_new_srv_start;
|
||||
tGATTS_PENDING_NEW_SRV_START *p_temp = (tGATTS_PENDING_NEW_SRV_START *)list_node(node);
|
||||
tGATTS_HNDL_RANGE *p = p_temp->p_new_srv_start;
|
||||
if (gatt_uuid_compare(*p_app_uuid128, p->app_uuid128)
|
||||
&& gatt_uuid_compare (*p_svc_uuid, p->svc_uuid)
|
||||
&& (svc_inst == p->svc_inst)) {
|
||||
p_buf = p_temp;
|
||||
GATT_TRACE_DEBUG("gatt_sr_is_new_srv_chg: Yes");
|
||||
break;
|
||||
}
|
||||
@@ -449,19 +450,17 @@ void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p)
|
||||
void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id)
|
||||
{
|
||||
tGATT_HDL_LIST_ELEM *p_elem = &gatt_cb.hdl_list[0];
|
||||
tGATT_HDL_LIST_INFO *p_list_info = &gatt_cb.hdl_list_info;
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < GATT_MAX_SR_PROFILES; i ++, p_elem ++) {
|
||||
if (memcmp(p_app_id, &p_elem->asgn_range.app_uuid128, sizeof(tBT_UUID)) == 0) {
|
||||
/* Remove from linked list first */
|
||||
gatt_remove_an_item_from_list(p_list_info, p_elem);
|
||||
/* Free attribute value buffers */
|
||||
gatt_free_attr_value_buffer(p_elem);
|
||||
while (!fixed_queue_is_empty(p_elem->svc_db.svc_buffer)) {
|
||||
osi_free(fixed_queue_dequeue(p_elem->svc_db.svc_buffer, 0));
|
||||
}
|
||||
fixed_queue_free(p_elem->svc_db.svc_buffer, NULL);
|
||||
p_elem->svc_db.svc_buffer = NULL;
|
||||
|
||||
p_elem->svc_db.mem_free = 0;
|
||||
p_elem->svc_db.p_attr_list = p_elem->svc_db.p_free_mem = NULL;
|
||||
/* Free the handle buffer completely (including svc_buffer and setting in_use = FALSE) */
|
||||
gatt_free_hdl_buffer(p_elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -631,7 +630,17 @@ BOOLEAN gatt_remove_a_srv_from_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_
|
||||
p_remove->p_next->p_prev = p_remove->p_prev;
|
||||
p_remove->p_prev->p_next = p_remove->p_next;
|
||||
}
|
||||
p_list->count--;
|
||||
// If the list is now empty, update p_last to NULL
|
||||
if(p_list->p_first == NULL) {
|
||||
p_list->p_last = NULL;
|
||||
}
|
||||
if (p_list->count) {
|
||||
p_list->count --;
|
||||
} else {
|
||||
GATT_TRACE_ERROR("Error: p_list->count is already zero");
|
||||
}
|
||||
|
||||
|
||||
gatt_update_last_pri_srv_info(p_list);
|
||||
return TRUE;
|
||||
|
||||
@@ -722,46 +731,20 @@ BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIS
|
||||
p_remove->p_next->p_prev = p_remove->p_prev;
|
||||
p_remove->p_prev->p_next = p_remove->p_next;
|
||||
}
|
||||
p_list->count--;
|
||||
// If the list is now empty, update p_last to NULL
|
||||
if (p_list->p_first == NULL) {
|
||||
p_list->p_last = NULL;
|
||||
}
|
||||
|
||||
if(p_list->count > 0) {
|
||||
p_list->count--;
|
||||
} else {
|
||||
GATT_TRACE_ERROR("Error: p_list->count is already zero");
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gatt_find_the_connected_bda
|
||||
**
|
||||
** Description This function find the connected bda
|
||||
**
|
||||
** Returns TRUE if found
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx,
|
||||
tBT_TRANSPORT *p_transport)
|
||||
{
|
||||
BOOLEAN found = FALSE;
|
||||
GATT_TRACE_DEBUG("gatt_find_the_connected_bda start_idx=%d", start_idx);
|
||||
tGATT_TCB *p_tcb = NULL;
|
||||
list_node_t *p_node = NULL;
|
||||
p_tcb = gatt_get_tcb_by_idx(start_idx);
|
||||
if (p_tcb) {
|
||||
for(p_node = list_get_node(gatt_cb.p_tcb_list, p_tcb); p_node; p_node = list_next(p_node)) {
|
||||
p_tcb = list_node(p_node);
|
||||
if (p_tcb->in_use && p_tcb->ch_state == GATT_CH_OPEN) {
|
||||
memcpy( bda, p_tcb->peer_bda, BD_ADDR_LEN);
|
||||
*p_found_idx = p_tcb->tcb_idx;
|
||||
*p_transport = p_tcb->transport;
|
||||
found = TRUE;
|
||||
GATT_TRACE_DEBUG("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x",
|
||||
bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
GATT_TRACE_DEBUG("gatt_find_the_connected_bda found=%d found_idx=%d", found, p_tcb->tcb_idx);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
#if (GATTS_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -1736,14 +1719,18 @@ tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id)
|
||||
if (list_length(gatt_cb.p_clcb_list) < GATT_CL_MAX_LCB) {
|
||||
p_clcb = (tGATT_CLCB *)osi_malloc(sizeof(tGATT_CLCB));
|
||||
if (p_clcb) {
|
||||
list_append(gatt_cb.p_clcb_list, p_clcb);
|
||||
memset(p_clcb, 0, sizeof(tGATT_CLCB));
|
||||
p_clcb->in_use = TRUE;
|
||||
p_clcb->conn_id = conn_id;
|
||||
//Add index of the clcb same as conn_id
|
||||
p_clcb->clcb_idx = conn_id;
|
||||
p_clcb->p_reg = p_reg;
|
||||
p_clcb->p_tcb = p_tcb;
|
||||
if (!list_append(gatt_cb.p_clcb_list, p_clcb)) {
|
||||
osi_free(p_clcb);
|
||||
GATT_TRACE_ERROR("gatt_clcb_alloc: could not add clcb to list");
|
||||
return NULL;
|
||||
}
|
||||
memset(p_clcb, 0, sizeof(tGATT_CLCB));
|
||||
p_clcb->in_use = TRUE;
|
||||
p_clcb->conn_id = conn_id;
|
||||
//Add index of the clcb same as conn_id
|
||||
p_clcb->clcb_idx = conn_id;
|
||||
p_clcb->p_reg = p_reg;
|
||||
p_clcb->p_tcb = p_tcb;
|
||||
}
|
||||
}
|
||||
return p_clcb;
|
||||
@@ -1761,6 +1748,10 @@ tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id)
|
||||
void gatt_clcb_dealloc (tGATT_CLCB *p_clcb)
|
||||
{
|
||||
if (p_clcb && p_clcb->in_use) {
|
||||
if (p_clcb->p_attr_buf) {
|
||||
osi_free(p_clcb->p_attr_buf);
|
||||
p_clcb->p_attr_buf = NULL;
|
||||
}
|
||||
btu_free_timer(&p_clcb->rsp_timer_ent);
|
||||
memset(p_clcb, 0, sizeof(tGATT_CLCB));
|
||||
list_remove(gatt_cb.p_clcb_list, p_clcb);
|
||||
@@ -2265,6 +2256,7 @@ void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data)
|
||||
|
||||
if (p_clcb->p_attr_buf) {
|
||||
osi_free(p_clcb->p_attr_buf);
|
||||
p_clcb->p_attr_buf = NULL;
|
||||
}
|
||||
|
||||
#if !CONFIG_BT_STACK_NO_LOG
|
||||
|
||||
@@ -603,6 +603,8 @@ extern void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 err_status
|
||||
}
|
||||
#endif
|
||||
|
||||
extern const UINT8 base_uuid[LEN_UUID_128];
|
||||
|
||||
/* internal functions */
|
||||
extern void gatt_init (void);
|
||||
extern void gatt_free(void);
|
||||
@@ -658,7 +660,6 @@ extern tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid
|
||||
extern BOOLEAN 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);
|
||||
|
||||
extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, tBT_TRANSPORT *p_transport);
|
||||
extern void gatt_set_srv_chg(void);
|
||||
extern void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr);
|
||||
extern tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start( tGATTS_HNDL_RANGE *p_new_srv_start);
|
||||
|
||||
Reference in New Issue
Block a user