mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-30 19:19:21 +00:00
Merge branch 'feature/btdm_attr_table' into 'master'
component bt:Added the create attribute table method to the new API GATT Server service table APIs. Have already modify the style and other things as @jeroen suggestion in other MR(the MR have been closed) See merge request !399
This commit is contained in:
@@ -392,7 +392,8 @@ void gap_attr_db_init(void)
|
||||
*/
|
||||
uuid.len = LEN_UUID_16;
|
||||
uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_DEVICE_NAME;
|
||||
p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ);
|
||||
p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ,
|
||||
NULL, NULL);
|
||||
p_db_attr ++;
|
||||
|
||||
/* add Icon characteristic
|
||||
@@ -401,7 +402,8 @@ void gap_attr_db_init(void)
|
||||
p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
|
||||
&uuid,
|
||||
GATT_PERM_READ,
|
||||
GATT_CHAR_PROP_BIT_READ);
|
||||
GATT_CHAR_PROP_BIT_READ,
|
||||
NULL, NULL);
|
||||
p_db_attr ++;
|
||||
|
||||
#if ((defined BTM_PERIPHERAL_ENABLED) && (BTM_PERIPHERAL_ENABLED == TRUE))
|
||||
@@ -416,7 +418,8 @@ void gap_attr_db_init(void)
|
||||
p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
|
||||
&uuid,
|
||||
GATT_PERM_READ,
|
||||
GATT_CHAR_PROP_BIT_READ);
|
||||
GATT_CHAR_PROP_BIT_READ,
|
||||
NULL, NULL);
|
||||
p_db_attr ++;
|
||||
#endif
|
||||
|
||||
@@ -424,7 +427,8 @@ void gap_attr_db_init(void)
|
||||
uuid.len = LEN_UUID_16;
|
||||
uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_CENTRAL_ADDR_RESOL;
|
||||
p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid,
|
||||
GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ);
|
||||
GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ,
|
||||
NULL, NULL);
|
||||
p_db_attr->attr_value.addr_resolution = 0;
|
||||
p_db_attr++;
|
||||
|
||||
|
@@ -151,10 +151,10 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
|
||||
tBT_UUID *p_app_uuid128;
|
||||
|
||||
|
||||
GATT_TRACE_API ("GATTS_CreateService" );
|
||||
GATT_TRACE_API ("GATTS_CreateService\n" );
|
||||
|
||||
if (p_reg == NULL) {
|
||||
GATT_TRACE_ERROR ("Inavlid gatt_if=%d", gatt_if);
|
||||
GATT_TRACE_ERROR ("Inavlid gatt_if=%d\n", gatt_if);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
|
||||
|
||||
if ((p_list = gatt_find_hdl_buffer_by_app_id(p_app_uuid128, p_svc_uuid, svc_inst)) != NULL) {
|
||||
s_hdl = p_list->asgn_range.s_handle;
|
||||
GATT_TRACE_DEBUG ("Service already been created!!");
|
||||
GATT_TRACE_DEBUG ("Service already been created!!\n");
|
||||
} else {
|
||||
if ( (p_svc_uuid->len == LEN_UUID_16) && (p_svc_uuid->uu.uuid16 == UUID_SERVCLASS_GATT_SERVER)) {
|
||||
s_hdl = gatt_cb.hdl_cfg.gatt_start_hdl;
|
||||
@@ -184,13 +184,13 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
|
||||
|
||||
/* check for space */
|
||||
if (num_handles > (0xFFFF - s_hdl + 1)) {
|
||||
GATT_TRACE_ERROR ("GATTS_ReserveHandles: no handles, s_hdl: %u needed: %u", s_hdl, num_handles);
|
||||
GATT_TRACE_ERROR ("GATTS_ReserveHandles: no handles, s_hdl: %u needed: %u\n", s_hdl, num_handles);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ( (p_list = gatt_alloc_hdl_buffer()) == NULL) {
|
||||
/* No free entry */
|
||||
GATT_TRACE_ERROR ("GATTS_ReserveHandles: no free handle blocks");
|
||||
GATT_TRACE_ERROR ("GATTS_ReserveHandles: no free handle blocks\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
|
||||
/* add a pending new service change item to the list */
|
||||
if ( (p_buf = gatt_add_pending_new_srv_start(&p_list->asgn_range)) == NULL) {
|
||||
/* No free entry */
|
||||
GATT_TRACE_ERROR ("gatt_add_pending_new_srv_start: no free blocks");
|
||||
GATT_TRACE_ERROR ("gatt_add_pending_new_srv_start: no free blocks\n");
|
||||
|
||||
if (p_list) {
|
||||
gatt_remove_an_item_from_list(p_list_info, p_list);
|
||||
@@ -219,12 +219,12 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
|
||||
return (0);
|
||||
}
|
||||
|
||||
GATT_TRACE_DEBUG ("Add a new srv chg item");
|
||||
GATT_TRACE_DEBUG ("Add a new srv chg item\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!gatts_init_service_db(&p_list->svc_db, p_svc_uuid, is_pri, s_hdl , num_handles)) {
|
||||
GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed");
|
||||
GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed\n");
|
||||
if (p_list) {
|
||||
gatt_remove_an_item_from_list(p_list_info, p_list);
|
||||
gatt_free_hdl_buffer(p_list);
|
||||
@@ -236,12 +236,6 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
|
||||
return (0);
|
||||
}
|
||||
|
||||
GATT_TRACE_DEBUG ("GATTS_CreateService(success): handles needed:%u s_hdl=%u e_hdl=%u %s[%x] is_primary=%d",
|
||||
num_handles, p_list->asgn_range.s_handle , p_list->asgn_range.e_handle,
|
||||
((p_list->asgn_range.svc_uuid.len == 2) ? "uuid16" : "uuid128" ),
|
||||
p_list->asgn_range.svc_uuid.uu.uuid16,
|
||||
p_list->asgn_range.is_primary);
|
||||
|
||||
return (s_hdl);
|
||||
}
|
||||
|
||||
@@ -295,25 +289,27 @@ UINT16 GATTS_AddIncludeService (UINT16 service_handle, UINT16 include_svc_handle
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
|
||||
tGATT_PERM perm, tGATT_CHAR_PROP property)
|
||||
tGATT_PERM perm, tGATT_CHAR_PROP property,
|
||||
tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
|
||||
{
|
||||
tGATT_HDL_LIST_ELEM *p_decl;
|
||||
|
||||
if ((p_decl = gatt_find_hdl_buffer_by_handle(service_handle)) == NULL) {
|
||||
GATT_TRACE_DEBUG("Service not created");
|
||||
GATT_TRACE_DEBUG("Service not created\n");
|
||||
return 0;
|
||||
}
|
||||
/* data validity checking */
|
||||
if ( ((property & GATT_CHAR_PROP_BIT_AUTH) && !(perm & GATT_WRITE_SIGNED_PERM)) ||
|
||||
((perm & GATT_WRITE_SIGNED_PERM) && !(property & GATT_CHAR_PROP_BIT_AUTH)) ) {
|
||||
GATT_TRACE_DEBUG("Invalid configuration property=0x%x perm=0x%x ", property, perm);
|
||||
GATT_TRACE_DEBUG("Invalid configuration property=0x%x perm=0x%x\n ", property, perm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return gatts_add_characteristic(&p_decl->svc_db,
|
||||
perm,
|
||||
property,
|
||||
p_char_uuid);
|
||||
p_char_uuid,
|
||||
attr_val, control);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -336,7 +332,7 @@ UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
|
||||
*******************************************************************************/
|
||||
UINT16 GATTS_AddCharDescriptor (UINT16 service_handle,
|
||||
tGATT_PERM perm,
|
||||
tBT_UUID *p_descr_uuid)
|
||||
tBT_UUID *p_descr_uuid, tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
|
||||
{
|
||||
tGATT_HDL_LIST_ELEM *p_decl;
|
||||
|
||||
@@ -353,7 +349,8 @@ UINT16 GATTS_AddCharDescriptor (UINT16 service_handle,
|
||||
|
||||
return gatts_add_char_descr(&p_decl->svc_db,
|
||||
perm,
|
||||
p_descr_uuid);
|
||||
p_descr_uuid,
|
||||
attr_val, control);
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
@@ -493,9 +490,9 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle,
|
||||
|
||||
gatt_add_a_srv_to_list(&gatt_cb.srv_list_info, &gatt_cb.srv_list[i_sreg]);
|
||||
|
||||
GATT_TRACE_DEBUG ("allocated i_sreg=%d ", i_sreg);
|
||||
GATT_TRACE_DEBUG ("allocated i_sreg=%d\n", i_sreg);
|
||||
|
||||
GATT_TRACE_DEBUG ("s_hdl=%d e_hdl=%d type=0x%x svc_inst=%d sdp_hdl=0x%x",
|
||||
GATT_TRACE_DEBUG ("s_hdl=%d e_hdl=%d type=0x%x svc_inst=%d sdp_hdl=0x%x\n",
|
||||
p_sreg->s_hdl, p_sreg->e_hdl,
|
||||
p_sreg->type, p_sreg->service_instance,
|
||||
p_sreg->sdp_handle);
|
||||
@@ -676,16 +673,16 @@ tGATT_STATUS GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
|
||||
tGATT_REG *p_reg = gatt_get_regcb(gatt_if);
|
||||
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
|
||||
|
||||
GATT_TRACE_API ("GATTS_SendRsp: conn_id: %u trans_id: %u Status: 0x%04x",
|
||||
GATT_TRACE_API ("GATTS_SendRsp: conn_id: %u trans_id: %u Status: 0x%04x\n",
|
||||
conn_id, trans_id, status);
|
||||
|
||||
if ( (p_reg == NULL) || (p_tcb == NULL)) {
|
||||
GATT_TRACE_ERROR ("GATTS_SendRsp Unknown conn_id: %u ", conn_id);
|
||||
GATT_TRACE_ERROR ("GATTS_SendRsp Unknown conn_id: %u\n", conn_id);
|
||||
return (tGATT_STATUS) GATT_INVALID_CONN_ID;
|
||||
}
|
||||
|
||||
if (p_tcb->sr_cmd.trans_id != trans_id) {
|
||||
GATT_TRACE_ERROR ("GATTS_SendRsp conn_id: %u waiting for op_code = %02x",
|
||||
GATT_TRACE_ERROR ("GATTS_SendRsp conn_id: %u waiting for op_code = %02x\n",
|
||||
conn_id, p_tcb->sr_cmd.op_code);
|
||||
|
||||
return (GATT_WRONG_STATE);
|
||||
@@ -696,6 +693,69 @@ tGATT_STATUS GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
|
||||
return cmd_sent;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GATTS_SetAttributeValue
|
||||
**
|
||||
** Description This function sends to set the attribute value .
|
||||
**
|
||||
** Parameter attr_handle:the attribute handle
|
||||
** length: the attribute length
|
||||
** value: the value to be set to the attribute in the database
|
||||
**
|
||||
** Returns GATT_SUCCESS if successfully sent; otherwise error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value)
|
||||
{
|
||||
tGATT_STATUS status;
|
||||
tGATT_HDL_LIST_ELEM *p_decl = NULL;
|
||||
|
||||
GATT_TRACE_DEBUG("GATTS_SetAttributeValue: attr_handle: %u length: %u \n",
|
||||
attr_handle, length);
|
||||
|
||||
if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
|
||||
GATT_TRACE_DEBUG("Service not created\n");
|
||||
return GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
status = gatts_set_attribute_value(&p_decl->svc_db, attr_handle, length, value);
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GATTS_GetAttributeValue
|
||||
**
|
||||
** Description This function sends to set the attribute value .
|
||||
**
|
||||
** Parameter attr_handle: the attribute handle
|
||||
** length:the attribute value length in the database
|
||||
** value: the attribute value out put
|
||||
**
|
||||
** Returns GATT_SUCCESS if successfully sent; otherwise error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value)
|
||||
{
|
||||
tGATT_STATUS status;
|
||||
tGATT_HDL_LIST_ELEM *p_decl;
|
||||
|
||||
GATT_TRACE_DEBUG("GATTS_GetAttributeValue: attr_handle: %u\n",
|
||||
attr_handle);
|
||||
|
||||
if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
|
||||
GATT_TRACE_ERROR("Service not created\n");
|
||||
return GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
status = gatts_get_attribute_value(&p_decl->svc_db, attr_handle, length, value);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* GATT Profile Srvr Functions */
|
||||
/*******************************************************************************/
|
||||
@@ -1132,7 +1192,7 @@ tGATT_IF GATT_Register (tBT_UUID *p_app_uuid128, tGATT_CBACK *p_cb_info)
|
||||
break;
|
||||
}
|
||||
}
|
||||
GATT_TRACE_API ("allocated gatt_if=%d", gatt_if);
|
||||
GATT_TRACE_API ("allocated gatt_if=%d\n", gatt_if);
|
||||
return gatt_if;
|
||||
}
|
||||
|
||||
|
@@ -279,21 +279,24 @@ void gatt_profile_db_init (void)
|
||||
GATT_StartIf(gatt_cb.gatt_if);
|
||||
|
||||
service_handle = GATTS_CreateService (gatt_cb.gatt_if , &uuid, 0, GATTP_MAX_ATTR_NUM, TRUE);
|
||||
GATT_TRACE_ERROR ("GATTS_CreateService: handle of service handle%x", service_handle);
|
||||
|
||||
/* add Service Changed characteristic
|
||||
*/
|
||||
uuid.uu.uuid16 = gatt_cb.gattp_attr.uuid = GATT_UUID_GATT_SRV_CHGD;
|
||||
gatt_cb.gattp_attr.service_change = 0;
|
||||
gatt_cb.gattp_attr.handle =
|
||||
gatt_cb.handle_of_h_r = GATTS_AddCharacteristic(service_handle, &uuid, 0, GATT_CHAR_PROP_BIT_INDICATE);
|
||||
gatt_cb.handle_of_h_r = GATTS_AddCharacteristic(service_handle, &uuid, 0, GATT_CHAR_PROP_BIT_INDICATE,
|
||||
NULL, NULL);
|
||||
|
||||
GATT_TRACE_DEBUG ("gatt_profile_db_init: handle of service changed%d",
|
||||
gatt_cb.handle_of_h_r );
|
||||
GATT_TRACE_DEBUG ("gatt_profile_db_init: handle of service changed%d\n",
|
||||
gatt_cb.handle_of_h_r);
|
||||
|
||||
/* start service
|
||||
*/
|
||||
status = GATTS_StartService (gatt_cb.gatt_if, service_handle, GATTP_TRANSPORT_SUPPORTED );
|
||||
|
||||
GATT_TRACE_DEBUG ("gatt_profile_db_init: gatt_if=%d start status%d",
|
||||
GATT_TRACE_DEBUG ("gatt_profile_db_init: gatt_if=%d start status%d\n",
|
||||
gatt_cb.gatt_if, status);
|
||||
}
|
||||
|
||||
|
@@ -45,7 +45,7 @@ static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 le
|
||||
|
||||
static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri);
|
||||
static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
UINT16 handle, UINT16 offset, UINT32 trans_id);
|
||||
UINT16 handle, UINT16 offset, UINT32 trans_id, BOOLEAN need_rsp);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -65,12 +65,12 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN
|
||||
GKI_init_q(&p_db->svc_buffer);
|
||||
|
||||
if (!allocate_svc_db_buf(p_db)) {
|
||||
GATT_TRACE_ERROR("gatts_init_service_db failed, no resources");
|
||||
GATT_TRACE_ERROR("gatts_init_service_db failed, no resources\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GATT_TRACE_DEBUG("gatts_init_service_db");
|
||||
GATT_TRACE_DEBUG("s_hdl = %d num_handle = %d", s_hdl, num_handle );
|
||||
GATT_TRACE_DEBUG("gatts_init_service_db\n");
|
||||
GATT_TRACE_DEBUG("s_hdl = %d num_handle = %d\n", s_hdl, num_handle );
|
||||
|
||||
/* update service database information */
|
||||
p_db->next_handle = s_hdl;
|
||||
@@ -94,7 +94,7 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN
|
||||
tBT_UUID *gatts_get_service_uuid (tGATT_SVC_DB *p_db)
|
||||
{
|
||||
if (!p_db || !p_db->p_attr_list) {
|
||||
GATT_TRACE_ERROR("service DB empty");
|
||||
GATT_TRACE_ERROR("service DB empty\n");
|
||||
|
||||
return NULL;
|
||||
} else {
|
||||
@@ -127,28 +127,28 @@ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
|
||||
}
|
||||
|
||||
if (!(perm & GATT_READ_ALLOWED)) {
|
||||
GATT_TRACE_ERROR( "GATT_READ_NOT_PERMIT");
|
||||
GATT_TRACE_ERROR( "GATT_READ_NOT_PERMIT\n");
|
||||
return GATT_READ_NOT_PERMIT;
|
||||
}
|
||||
|
||||
if ((perm & GATT_READ_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) &&
|
||||
!(sec_flag & BTM_SEC_FLAG_ENCRYPTED)) {
|
||||
GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION");
|
||||
GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION\n");
|
||||
return GATT_INSUF_AUTHENTICATION;
|
||||
}
|
||||
|
||||
if ((perm & GATT_READ_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) {
|
||||
GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION: MITM Required");
|
||||
GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION: MITM Required\n");
|
||||
return GATT_INSUF_AUTHENTICATION;
|
||||
}
|
||||
|
||||
if ((perm & GATT_READ_ENCRYPTED_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
|
||||
GATT_TRACE_ERROR( "GATT_INSUF_ENCRYPTION");
|
||||
GATT_TRACE_ERROR( "GATT_INSUF_ENCRYPTION\n");
|
||||
return GATT_INSUF_ENCRYPTION;
|
||||
}
|
||||
|
||||
if ( (perm & GATT_READ_ENCRYPTED_REQUIRED) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) {
|
||||
GATT_TRACE_ERROR( "GATT_INSUF_KEY_SIZE");
|
||||
GATT_TRACE_ERROR( "GATT_INSUF_KEY_SIZE\n");
|
||||
return GATT_INSUF_KEY_SIZE;
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
|
||||
case GATT_UUID_CHAR_CLIENT_CONFIG:
|
||||
case GATT_UUID_CHAR_SRVR_CONFIG:
|
||||
case GATT_UUID_CHAR_PRESENT_FORMAT:
|
||||
GATT_TRACE_ERROR("GATT_NOT_LONG");
|
||||
GATT_TRACE_ERROR("GATT_NOT_LONG\n");
|
||||
return GATT_NOT_LONG;
|
||||
|
||||
default:
|
||||
@@ -206,7 +206,7 @@ static tGATT_STATUS read_attr_value (void *p_attr,
|
||||
tGATT_STATUS status;
|
||||
tGATT_ATTR16 *p_attr16 = (tGATT_ATTR16 *)p_attr;
|
||||
|
||||
GATT_TRACE_DEBUG("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d",
|
||||
GATT_TRACE_DEBUG("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d\n",
|
||||
p_attr16->uuid,
|
||||
p_attr16->permission,
|
||||
sec_flag,
|
||||
@@ -268,7 +268,18 @@ static tGATT_STATUS read_attr_value (void *p_attr,
|
||||
status = GATT_SUCCESS;
|
||||
}
|
||||
} else { /* characteristic description or characteristic value */
|
||||
status = GATT_PENDING;
|
||||
|
||||
if (p_attr16->control.auto_rsp == GATT_RSP_BY_STACK) {
|
||||
if (p_attr16->p_value != NULL && p_attr16->p_value->attr_val.attr_val != NULL) {
|
||||
uint8_t *value = p_attr16->p_value->attr_val.attr_val + offset;
|
||||
len = (mtu >= p_attr16->p_value->attr_val.attr_len) ? (p_attr16->p_value->attr_val.attr_len) : mtu;
|
||||
ARRAY_TO_STREAM(p, value, len);
|
||||
}
|
||||
status = GATT_STACK_RSP;
|
||||
|
||||
} else {
|
||||
status = GATT_PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
*p_len = len;
|
||||
@@ -341,8 +352,9 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb,
|
||||
|
||||
status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len - 2), &len, sec_flag, key_size);
|
||||
|
||||
if (status == GATT_PENDING) {
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id);
|
||||
if (status == GATT_PENDING || status == GATT_STACK_RSP) {
|
||||
BOOLEAN need_rsp = (status != GATT_STACK_RSP);
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id, need_rsp);
|
||||
|
||||
/* one callback at a time */
|
||||
break;
|
||||
@@ -445,12 +457,12 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e
|
||||
*******************************************************************************/
|
||||
UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
|
||||
tGATT_CHAR_PROP property,
|
||||
tBT_UUID *p_char_uuid)
|
||||
tBT_UUID *p_char_uuid, tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
|
||||
{
|
||||
tGATT_ATTR16 *p_char_decl, *p_char_val;
|
||||
tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
|
||||
|
||||
GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property);
|
||||
GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x\n", perm, property);
|
||||
|
||||
if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) {
|
||||
if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL))) {
|
||||
@@ -467,8 +479,30 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
|
||||
|
||||
p_char_decl->p_value->char_decl.property = property;
|
||||
p_char_decl->p_value->char_decl.char_val_handle = p_char_val->handle;
|
||||
if (control != NULL) {
|
||||
p_char_val->control.auto_rsp = control->auto_rsp;
|
||||
} else {
|
||||
p_char_val->control.auto_rsp = GATT_RSP_DEFAULT;
|
||||
|
||||
p_char_val->p_value = NULL;
|
||||
}
|
||||
|
||||
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_val);
|
||||
return 0;
|
||||
}
|
||||
GATT_TRACE_DEBUG("attr_val->attr_len = %x, attr_val->attr_max_len = %x\n", attr_val->attr_len, attr_val->attr_max_len);
|
||||
GATT_TRACE_DEBUG("attribute handle = %x\n", p_char_val->handle);
|
||||
p_char_val->p_value->attr_val.attr_len = attr_val->attr_len;
|
||||
p_char_val->p_value->attr_val.attr_max_len = attr_val->attr_max_len;
|
||||
p_char_val->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len);
|
||||
if (p_char_val->p_value->attr_val.attr_val != NULL) {
|
||||
GATT_TRACE_DEBUG("attribute value not NULL");
|
||||
memcpy(p_char_val->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
|
||||
}
|
||||
} else {
|
||||
p_char_val->p_value = NULL;
|
||||
}
|
||||
|
||||
return p_char_val->handle;
|
||||
}
|
||||
@@ -542,24 +576,227 @@ UINT8 gatt_convertchar_descr_type(tBT_UUID *p_descr_uuid)
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
|
||||
tBT_UUID *p_descr_uuid)
|
||||
tBT_UUID *p_descr_uuid, tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
|
||||
{
|
||||
tGATT_ATTR16 *p_char_dscptr;
|
||||
|
||||
GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16);
|
||||
GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x\n", p_descr_uuid->uu.uuid16);
|
||||
|
||||
/* Add characteristic descriptors */
|
||||
if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db,
|
||||
p_descr_uuid,
|
||||
perm))
|
||||
== NULL) {
|
||||
if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_descr_uuid, perm)) == NULL) {
|
||||
GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors.");
|
||||
return 0;
|
||||
} else {
|
||||
if (control != NULL) {
|
||||
p_char_dscptr->control.auto_rsp = control->auto_rsp;
|
||||
}
|
||||
if (attr_val != NULL) {
|
||||
if (!copy_extra_byte_in_db(p_db, (void **)&p_char_dscptr->p_value, sizeof(tGATT_ATTR_VAL))) {
|
||||
deallocate_attr_in_db(p_db, p_char_dscptr);
|
||||
return 0;
|
||||
}
|
||||
p_char_dscptr->p_value->attr_val.attr_len = attr_val->attr_len;
|
||||
p_char_dscptr->p_value->attr_val.attr_max_len = attr_val->attr_max_len;
|
||||
if (attr_val->attr_val != NULL) {
|
||||
p_char_dscptr->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len);
|
||||
if (p_char_dscptr->p_value->attr_val.attr_val != NULL) {
|
||||
memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len);
|
||||
memcpy(p_char_dscptr->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
return p_char_dscptr->handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gatts_set_attribute_value
|
||||
**
|
||||
** Description This function add the attribute value in the database
|
||||
**
|
||||
** Parameter p_db: database pointer.
|
||||
** attr_handle: the attribute handle
|
||||
** length: the attribute value length
|
||||
** value: the pointer to the data to be set to the attribute value in the database
|
||||
**
|
||||
** Returns Status of the operation.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
||||
UINT16 length, UINT8 *value)
|
||||
{
|
||||
tGATT_ATTR16 *p_cur;
|
||||
|
||||
if (p_db == NULL) {
|
||||
GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db is NULL.\n");
|
||||
return GATT_INVALID_PDU;
|
||||
}
|
||||
if (p_db->p_attr_list == NULL) {
|
||||
GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db->p_attr_list is NULL.\n");
|
||||
return GATT_INVALID_PDU;
|
||||
}
|
||||
|
||||
p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
|
||||
|
||||
while (p_cur != NULL) {
|
||||
if (p_cur->handle == attr_handle) {
|
||||
|
||||
if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) {
|
||||
switch (p_cur->uuid) {
|
||||
case GATT_UUID_PRI_SERVICE:
|
||||
case GATT_UUID_SEC_SERVICE:
|
||||
case GATT_UUID_CHAR_DECLARE:
|
||||
case GATT_UUID_INCLUDE_SERVICE:
|
||||
return GATT_NOT_FOUND;
|
||||
default:
|
||||
if (p_cur->p_value->attr_val.attr_max_len < length) {
|
||||
GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
|
||||
return GATT_INVALID_ATTR_LEN;
|
||||
} else {
|
||||
memcpy(p_cur->p_value->attr_val.attr_val, value, length);
|
||||
p_cur->p_value->attr_val.attr_len = length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (p_cur->p_value->attr_val.attr_max_len < length) {
|
||||
GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
|
||||
} else {
|
||||
memcpy(p_cur->p_value->attr_val.attr_val, value, length);
|
||||
p_cur->p_value->attr_val.attr_len = length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
p_cur = p_cur->p_next;
|
||||
}
|
||||
|
||||
return GATT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gatts_get_attribute_value
|
||||
**
|
||||
** Description This function get the attribute value in the database
|
||||
**
|
||||
** Parameter p_db: database pointer.
|
||||
** attr_handle: the attribute handle
|
||||
** length: the attribute value length
|
||||
** value: the pointer to the data to be get to the attribute value in the database
|
||||
**
|
||||
** Returns Status of the operation.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
||||
UINT16 *length, UINT8 **value)
|
||||
{
|
||||
tGATT_ATTR16 *p_cur;
|
||||
GATT_TRACE_DEBUG("***********%s*************\n", __func__);
|
||||
GATT_TRACE_DEBUG("attr_handle = %x\n", attr_handle);
|
||||
if (p_db == NULL) {
|
||||
GATT_TRACE_ERROR("gatts_get_attribute_value Fail:p_db is NULL.\n");
|
||||
return GATT_INVALID_PDU;
|
||||
}
|
||||
if (p_db->p_attr_list == NULL) {
|
||||
GATT_TRACE_ERROR("gatts_get_attribute_value Fail:p_db->p_attr_list is NULL.\n");
|
||||
return GATT_INVALID_PDU;
|
||||
}
|
||||
|
||||
p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
|
||||
|
||||
while (p_cur != NULL) {
|
||||
LOG_ERROR("p_ur->handle = %x\n", p_cur->handle);
|
||||
if (p_cur->handle == attr_handle) {
|
||||
|
||||
if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) {
|
||||
switch (p_cur->uuid) {
|
||||
case GATT_UUID_CHAR_DECLARE:
|
||||
case GATT_UUID_INCLUDE_SERVICE:
|
||||
break;
|
||||
default:
|
||||
if (p_cur->p_value->attr_val.attr_len != 0) {
|
||||
*length = p_cur->p_value->attr_val.attr_len;
|
||||
*value = p_cur->p_value->attr_val.attr_val;
|
||||
return GATT_SUCCESS;
|
||||
} else {
|
||||
GATT_TRACE_ERROR("gatts_get_attribute_vaule failt:the value length is 0");
|
||||
return GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (p_cur->p_value->attr_val.attr_len != 0) {
|
||||
*length = p_cur->p_value->attr_val.attr_len;
|
||||
*value = p_cur->p_value->attr_val.attr_val;
|
||||
return GATT_SUCCESS;
|
||||
} else {
|
||||
GATT_TRACE_ERROR("gatts_get_attribute_vaule failed:the value length is 0");
|
||||
return GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
p_cur = p_cur->p_next;
|
||||
}
|
||||
|
||||
return GATT_NOT_FOUND;
|
||||
}
|
||||
|
||||
BOOLEAN gatts_is_auto_response(UINT16 attr_handle)
|
||||
{
|
||||
tGATT_HDL_LIST_ELEM *p_decl = NULL;
|
||||
BOOLEAN rsp = FALSE;
|
||||
tGATT_SVC_DB *p_db = NULL;
|
||||
if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
|
||||
GATT_TRACE_DEBUG("Service not created\n");
|
||||
return rsp;
|
||||
}
|
||||
|
||||
p_db = &p_decl->svc_db;
|
||||
|
||||
tGATT_ATTR16 *p_cur, *p_next;
|
||||
|
||||
if (p_db == NULL) {
|
||||
GATT_TRACE_DEBUG("gatts_get_attribute_value Fail:p_db is NULL.\n");
|
||||
return rsp;
|
||||
}
|
||||
if (p_db->p_attr_list == NULL) {
|
||||
GATT_TRACE_DEBUG("gatts_get_attribute_value Fail:p_db->p_attr_list is NULL.\n");
|
||||
return rsp;
|
||||
}
|
||||
|
||||
p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
|
||||
p_next = (tGATT_ATTR16 *) p_cur->p_next;
|
||||
|
||||
for (; p_cur != NULL && p_next != NULL;
|
||||
p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
|
||||
if (p_cur->handle == attr_handle) {
|
||||
if (p_cur->p_value != NULL && p_cur->control.auto_rsp == GATT_RSP_BY_STACK) {
|
||||
rsp = true;
|
||||
return rsp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return rsp;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Service Attribute Database Query Utility Functions */
|
||||
/*******************************************************************************/
|
||||
@@ -605,8 +842,9 @@ tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb,
|
||||
(BOOLEAN)(op_code == GATT_REQ_READ_BLOB),
|
||||
mtu, p_len, sec_flag, key_size);
|
||||
|
||||
if (status == GATT_PENDING) {
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, offset, trans_id);
|
||||
if ((status == GATT_PENDING) || (status == GATT_STACK_RSP)) {
|
||||
BOOLEAN need_rsp = (status != GATT_STACK_RSP);
|
||||
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, offset, trans_id, need_rsp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -614,6 +852,42 @@ tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
|
||||
UINT16 handle, UINT16 offset,
|
||||
UINT8 *p_value, UINT16 len)
|
||||
{
|
||||
tGATT_STATUS status = GATT_NOT_FOUND;
|
||||
tGATT_ATTR16 *p_attr;
|
||||
|
||||
if (p_db && p_db->p_attr_list) {
|
||||
p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
|
||||
|
||||
while (p_attr && handle >= p_attr->handle) {
|
||||
if (p_attr->handle == handle ) {
|
||||
if (p_attr->control.auto_rsp == GATT_RSP_BY_APP) {
|
||||
return GATT_APP_RSP;
|
||||
}
|
||||
|
||||
if (p_attr->p_value != NULL && (p_attr->p_value->attr_val.attr_max_len >=
|
||||
offset + len)) {
|
||||
memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len);
|
||||
p_attr->p_value->attr_val.attr_len = len + offset;
|
||||
return GATT_SUCCESS;
|
||||
} else {
|
||||
return GATT_NOT_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
p_attr = (tGATT_ATTR16 *)p_attr->p_next;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -661,6 +935,8 @@ tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db,
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gatts_write_attr_perm_check
|
||||
@@ -835,7 +1111,7 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PER
|
||||
UINT16 len = sizeof(tGATT_ATTR128);
|
||||
|
||||
if (p_uuid == NULL) {
|
||||
GATT_TRACE_ERROR("illegal UUID");
|
||||
GATT_TRACE_ERROR("illegal UUID\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -845,17 +1121,17 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PER
|
||||
len = sizeof(tGATT_ATTR32);
|
||||
}
|
||||
|
||||
GATT_TRACE_DEBUG("allocate attr %d bytes ", len);
|
||||
GATT_TRACE_DEBUG("allocate attr %d bytes\n", len);
|
||||
|
||||
if (p_db->end_handle <= p_db->next_handle) {
|
||||
GATT_TRACE_DEBUG("handle space full. handle_max = %d next_handle = %d",
|
||||
GATT_TRACE_DEBUG("handle space full. handle_max = %d next_handle = %d\n",
|
||||
p_db->end_handle, p_db->next_handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (p_db->mem_free < len) {
|
||||
if (!allocate_svc_db_buf(p_db)) {
|
||||
GATT_TRACE_ERROR("allocate_attr_in_db failed, no resources");
|
||||
GATT_TRACE_ERROR("allocate_attr_in_db failed, no resources\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -896,19 +1172,21 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PER
|
||||
}
|
||||
|
||||
if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) {
|
||||
GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ",
|
||||
GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x\n",
|
||||
p_attr16->handle, p_attr16->uuid, p_attr16->permission);
|
||||
} else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) {
|
||||
GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ",
|
||||
GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x\n",
|
||||
p_attr32->handle, p_attr32->uuid, p_attr32->permission);
|
||||
} else {
|
||||
GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ",
|
||||
GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x\n",
|
||||
p_attr128->handle, p_attr128->uuid[0], p_attr128->uuid[1],
|
||||
p_attr128->permission);
|
||||
}
|
||||
return (void *)p_attr16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function deallocate_attr_in_db
|
||||
@@ -974,7 +1252,7 @@ static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 le
|
||||
|
||||
if (p_db->mem_free < len) {
|
||||
if (!allocate_svc_db_buf(p_db)) {
|
||||
GATT_TRACE_ERROR("copy_extra_byte_in_db failed, no resources");
|
||||
GATT_TRACE_ERROR("copy_extra_byte_in_db failed, no resources\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1028,7 +1306,7 @@ static BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db)
|
||||
**
|
||||
*******************************************************************************/
|
||||
static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
UINT16 handle, UINT16 offset, UINT32 trans_id)
|
||||
UINT16 handle, UINT16 offset, UINT32 trans_id, BOOLEAN need_rsp)
|
||||
{
|
||||
tGATTS_DATA sr_data;
|
||||
UINT8 i_rcb;
|
||||
@@ -1050,6 +1328,7 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
sr_data.read_req.handle = handle;
|
||||
sr_data.read_req.is_long = (BOOLEAN)(op_code == GATT_REQ_READ_BLOB);
|
||||
sr_data.read_req.offset = offset;
|
||||
sr_data.read_req.need_rsp = need_rsp;
|
||||
|
||||
gatt_sr_send_req_callback(conn_id,
|
||||
trans_id, GATTS_REQ_TYPE_READ, &sr_data);
|
||||
|
@@ -508,7 +508,7 @@ static void gatt_le_data_ind (UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf)
|
||||
GKI_freebuf (p_buf);
|
||||
|
||||
if (p_tcb != NULL) {
|
||||
GATT_TRACE_WARNING ("ATT - Ignored L2CAP data while in state: %d",
|
||||
GATT_TRACE_WARNING ("ATT - Ignored L2CAP data while in state: %d\n",
|
||||
gatt_get_ch_state(p_tcb));
|
||||
}
|
||||
}
|
||||
@@ -906,10 +906,10 @@ void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x", op_code);
|
||||
GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x\n", op_code);
|
||||
}
|
||||
} else {
|
||||
GATT_TRACE_ERROR ("invalid data length, ignore");
|
||||
GATT_TRACE_ERROR ("invalid data length, ignore\n");
|
||||
}
|
||||
|
||||
GKI_freebuf (p_buf);
|
||||
|
@@ -239,7 +239,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if,
|
||||
tGATT_STATUS ret_code = GATT_SUCCESS;
|
||||
UNUSED(trans_id);
|
||||
|
||||
GATT_TRACE_DEBUG("gatt_sr_process_app_rsp gatt_if=%d", gatt_if);
|
||||
GATT_TRACE_DEBUG("gatt_sr_process_app_rsp gatt_if=%d\n", gatt_if);
|
||||
|
||||
gatt_sr_update_cback_cnt(p_tcb, gatt_if, FALSE, FALSE);
|
||||
|
||||
@@ -264,7 +264,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if,
|
||||
if (p_tcb->sr_cmd.p_rsp_msg == NULL) {
|
||||
p_tcb->sr_cmd.p_rsp_msg = attp_build_sr_msg (p_tcb, (UINT8)(op_code + 1), (tGATT_SR_MSG *)p_msg);
|
||||
} else {
|
||||
GATT_TRACE_ERROR("Exception!!! already has respond message");
|
||||
GATT_TRACE_ERROR("Exception!!! already has respond message\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,7 +279,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if,
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
|
||||
GATT_TRACE_DEBUG("gatt_sr_process_app_rsp ret_code=%d", ret_code);
|
||||
GATT_TRACE_DEBUG("gatt_sr_process_app_rsp ret_code=%d\n", ret_code);
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
@@ -371,7 +371,7 @@ void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U
|
||||
|
||||
#if GATT_CONFORMANCE_TESTING == TRUE
|
||||
if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
|
||||
GATT_TRACE_DEBUG("Conformance tst: forced err rspvofr ReadMultiple: error status=%d", gatt_cb.err_status);
|
||||
GATT_TRACE_DEBUG("Conformance tst: forced err rspvofr ReadMultiple: error status=%d\n", gatt_cb.err_status);
|
||||
|
||||
STREAM_TO_UINT16(handle, p);
|
||||
|
||||
@@ -871,7 +871,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
|
||||
** - discover characteristic by UUID
|
||||
** - relationship discovery
|
||||
**
|
||||
** Returns void
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data)
|
||||
@@ -889,10 +889,10 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
|
||||
tGATT_SRV_LIST_ELEM *p_srv = NULL;
|
||||
|
||||
reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl);
|
||||
|
||||
GATT_TRACE_DEBUG("%s, op_code =%x, len = %x\n", __func__, op_code, len);
|
||||
#if GATT_CONFORMANCE_TESTING == TRUE
|
||||
if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
|
||||
GATT_TRACE_DEBUG("Conformance tst: forced err rsp for ReadByType: error status=%d", gatt_cb.err_status);
|
||||
GATT_TRACE_DEBUG("Conformance tst: forced err rsp for ReadByType: error status=%d\n", gatt_cb.err_status);
|
||||
|
||||
gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl, FALSE);
|
||||
|
||||
@@ -902,7 +902,7 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
|
||||
|
||||
if (reason == GATT_SUCCESS) {
|
||||
if ((p_msg = (BT_HDR *)GKI_getbuf(msg_len)) == NULL) {
|
||||
GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.");
|
||||
GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.\n");
|
||||
|
||||
reason = GATT_NO_RESOURCES;
|
||||
} else {
|
||||
@@ -959,7 +959,7 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
|
||||
p_msg->offset = L2CAP_MIN_OFFSET;
|
||||
}
|
||||
}
|
||||
if (reason != GATT_SUCCESS) {
|
||||
if (reason != GATT_SUCCESS && reason != GATT_STACK_RSP) {
|
||||
if (p_msg) {
|
||||
GKI_freebuf(p_msg);
|
||||
}
|
||||
@@ -987,21 +987,34 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
|
||||
void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
|
||||
UINT8 op_code, UINT16 len, UINT8 *p_data)
|
||||
{
|
||||
UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
|
||||
tGATTS_DATA sr_data;
|
||||
UINT32 trans_id;
|
||||
tGATT_STATUS status;
|
||||
UINT8 sec_flag, key_size, *p = p_data;
|
||||
UINT8 sec_flag, key_size, *p = p_data, *p_m;
|
||||
tGATT_SR_REG *p_sreg;
|
||||
UINT16 conn_id;
|
||||
|
||||
UINT16 conn_id, offset = 0;
|
||||
BT_HDR *p_msg = NULL;
|
||||
memset(&sr_data, 0, sizeof(tGATTS_DATA));
|
||||
|
||||
if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
|
||||
GATT_TRACE_ERROR("gatts_process_write_req failed. no resources.\n");
|
||||
}
|
||||
|
||||
memset(p_msg, 0, buf_len);
|
||||
p_m = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET;
|
||||
*p_m ++ = op_code + 1;
|
||||
p_msg->len = 1;
|
||||
buf_len = p_tcb->payload_size - 1;
|
||||
|
||||
switch (op_code) {
|
||||
case GATT_REQ_PREPARE_WRITE:
|
||||
sr_data.write_req.is_prep = TRUE;
|
||||
STREAM_TO_UINT16(sr_data.write_req.offset, p);
|
||||
UINT16_TO_STREAM(p_m, sr_data.write_req.is_prep);
|
||||
offset = sr_data.write_req.offset;
|
||||
len -= 2;
|
||||
/* fall through */
|
||||
/* fall through */
|
||||
case GATT_SIGN_CMD_WRITE:
|
||||
if (op_code == GATT_SIGN_CMD_WRITE) {
|
||||
GATT_TRACE_DEBUG("Write CMD with data sigining" );
|
||||
@@ -1012,11 +1025,16 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
|
||||
case GATT_REQ_WRITE:
|
||||
if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) {
|
||||
sr_data.write_req.need_rsp = TRUE;
|
||||
if(op_code == GATT_REQ_PREPARE_WRITE){
|
||||
memcpy(p_m, p, len);
|
||||
p_msg->len += len;
|
||||
}
|
||||
}
|
||||
sr_data.write_req.handle = handle;
|
||||
sr_data.write_req.len = len;
|
||||
if (len != 0 && p != NULL) {
|
||||
memcpy (sr_data.write_req.value, p, len);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1039,48 +1057,64 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
|
||||
if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) {
|
||||
p_sreg = &gatt_cb.sr_reg[i_rcb];
|
||||
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
|
||||
gatt_sr_send_req_callback(conn_id,
|
||||
trans_id,
|
||||
GATTS_REQ_TYPE_WRITE,
|
||||
&sr_data);
|
||||
status = gatts_write_attr_value_by_handle(gatt_cb.sr_reg[i_rcb].p_db,
|
||||
handle, offset, p, len);
|
||||
if((sr_data.write_req.need_rsp == TRUE) && (status == GATT_APP_RSP)){
|
||||
sr_data.write_req.need_rsp = TRUE;
|
||||
status = GATT_PENDING;
|
||||
}
|
||||
|
||||
else{
|
||||
sr_data.write_req.need_rsp = FALSE;
|
||||
}
|
||||
|
||||
gatt_sr_send_req_callback(conn_id,
|
||||
trans_id,
|
||||
GATTS_REQ_TYPE_WRITE,
|
||||
&sr_data);
|
||||
|
||||
if(status == GATT_SUCCESS){
|
||||
attp_send_sr_msg(p_tcb, p_msg);
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
|
||||
status = GATT_PENDING;
|
||||
} else {
|
||||
GATT_TRACE_ERROR("max pending command, send error");
|
||||
GATT_TRACE_ERROR("max pending command, send error\n");
|
||||
status = GATT_BUSY; /* max pending command, application error */
|
||||
}
|
||||
}
|
||||
|
||||
/* in theroy BUSY is not possible(should already been checked), protected check */
|
||||
if (status != GATT_PENDING && status != GATT_BUSY &&
|
||||
if (status != GATT_PENDING && status != GATT_BUSY && status != GATT_SUCCESS &&
|
||||
(op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_REQ_WRITE)) {
|
||||
gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE);
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gatts_process_read_req
|
||||
**
|
||||
** Description This function is called to process the read request
|
||||
** from client.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
**
|
||||
** Function gatts_process_read_req
|
||||
**
|
||||
** Description This function is called to process the read request
|
||||
** from client.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code,
|
||||
UINT16 handle, UINT16 len, UINT8 *p_data)
|
||||
{
|
||||
UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
|
||||
tGATT_STATUS reason;
|
||||
BT_HDR *p_msg = NULL;
|
||||
UINT8 sec_flag, key_size, *p;
|
||||
UINT16 offset = 0, value_len = 0;
|
||||
UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
|
||||
tGATT_STATUS reason;
|
||||
BT_HDR *p_msg = NULL;
|
||||
UINT8 sec_flag, key_size, *p;
|
||||
UINT16 offset = 0, value_len = 0;
|
||||
|
||||
UNUSED (len);
|
||||
if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
|
||||
GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.");
|
||||
GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.\n");
|
||||
|
||||
reason = GATT_NO_RESOURCES;
|
||||
} else {
|
||||
@@ -1114,17 +1148,20 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8
|
||||
p_msg->len += value_len;
|
||||
}
|
||||
|
||||
if (reason != GATT_SUCCESS) {
|
||||
|
||||
if (reason != GATT_SUCCESS && reason != GATT_PENDING && reason != GATT_STACK_RSP) {
|
||||
if (p_msg) {
|
||||
GKI_freebuf(p_msg);
|
||||
}
|
||||
|
||||
/* in theroy BUSY is not possible(should already been checked), protected check */
|
||||
if (reason != GATT_PENDING && reason != GATT_BUSY) {
|
||||
if (reason != GATT_BUSY) {
|
||||
gatt_send_error_rsp (p_tcb, reason, op_code, handle, FALSE);
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
} else {
|
||||
attp_send_sr_msg(p_tcb, p_msg);
|
||||
gatt_dequeue_sr_cmd(p_tcb);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1149,7 +1186,7 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
tGATT_ATTR16 *p_attr;
|
||||
|
||||
if (len < 2) {
|
||||
GATT_TRACE_ERROR("Illegal PDU length, discard request");
|
||||
GATT_TRACE_ERROR("Illegal PDU length, discard request\n");
|
||||
status = GATT_INVALID_PDU;
|
||||
} else {
|
||||
STREAM_TO_UINT16(handle, p);
|
||||
@@ -1159,7 +1196,7 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
#if GATT_CONFORMANCE_TESTING == TRUE
|
||||
gatt_cb.handle = handle;
|
||||
if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
|
||||
GATT_TRACE_DEBUG("Conformance tst: forced err rsp: error status=%d", gatt_cb.err_status);
|
||||
GATT_TRACE_DEBUG("Conformance tst: forced err rsp: error status=%d\n", gatt_cb.err_status);
|
||||
|
||||
gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle, FALSE);
|
||||
|
||||
@@ -1350,24 +1387,24 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
/* otherwise, ignore the pkt */
|
||||
} else {
|
||||
switch (op_code) {
|
||||
case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
|
||||
case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
|
||||
case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
|
||||
case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
|
||||
gatts_process_primary_service_req (p_tcb, op_code, len, p_data);
|
||||
break;
|
||||
|
||||
case GATT_REQ_FIND_INFO:/* discover char descrptor */
|
||||
case GATT_REQ_FIND_INFO: /* discover char descrptor */
|
||||
gatts_process_find_info(p_tcb, op_code, len, p_data);
|
||||
break;
|
||||
|
||||
case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */
|
||||
case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */
|
||||
/* discover characteristic, discover char by UUID */
|
||||
gatts_process_read_by_type_req(p_tcb, op_code, len, p_data);
|
||||
break;
|
||||
|
||||
|
||||
case GATT_REQ_READ: /* read char/char descriptor value */
|
||||
case GATT_REQ_READ: /* read char/char descriptor value */
|
||||
case GATT_REQ_READ_BLOB:
|
||||
case GATT_REQ_WRITE: /* write char/char descriptor value */
|
||||
case GATT_REQ_WRITE: /* write char/char descriptor value */
|
||||
case GATT_CMD_WRITE:
|
||||
case GATT_SIGN_CMD_WRITE:
|
||||
case GATT_REQ_PREPARE_WRITE:
|
||||
|
@@ -318,6 +318,34 @@ tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gatt_find_hdl_buffer_by_attr_handle
|
||||
**
|
||||
** Description Find handle range buffer by attribute handle.
|
||||
**
|
||||
** Returns Pointer to the buffer, NULL no buffer available
|
||||
**
|
||||
*******************************************************************************/
|
||||
tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle)
|
||||
{
|
||||
tGATT_HDL_LIST_INFO *p_list_info = &gatt_cb.hdl_list_info;
|
||||
tGATT_HDL_LIST_ELEM *p_list = NULL;
|
||||
|
||||
p_list = p_list_info->p_first;
|
||||
|
||||
while (p_list != NULL) {
|
||||
if (p_list->in_use && (p_list->asgn_range.s_handle <= attr_handle)
|
||||
&& (p_list->asgn_range.e_handle >= attr_handle)) {
|
||||
return (p_list);
|
||||
}
|
||||
p_list = p_list->p_next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gatt_find_hdl_buffer_by_app_id
|
||||
@@ -1476,7 +1504,7 @@ tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if)
|
||||
p_reg = &gatt_cb.cl_rcb[ii - 1];
|
||||
|
||||
if (!p_reg->in_use) {
|
||||
GATT_TRACE_WARNING("gatt_if found but not in use.");
|
||||
GATT_TRACE_WARNING("gatt_if found but not in use.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@@ -35,7 +35,10 @@
|
||||
#define GATT_GET_GATT_IF(conn_id) ((tGATT_IF)((UINT8) (conn_id)))
|
||||
|
||||
#define GATT_GET_SR_REG_PTR(index) (&gatt_cb.sr_reg[(UINT8) (index)]);
|
||||
#define GATT_TRANS_ID_MAX 0x0fffffff /* 4 MSB is reserved */
|
||||
#define GATT_TRANS_ID_MAX 0x0fffffff /* 4 MSB is reserved */
|
||||
#define GATT_RSP_BY_APP 0x00
|
||||
#define GATT_RSP_BY_STACK 0x01
|
||||
#define GATT_RSP_DEFAULT GATT_RSP_BY_APP //need to rsp by the app.
|
||||
|
||||
/* security action for GATT write and read request */
|
||||
#define GATT_SEC_NONE 0
|
||||
@@ -61,16 +64,16 @@ typedef UINT8 tGATT_SEC_ACTION;
|
||||
#define GATT_ATTR_OP_SPT_PREP_WRITE (0x00000001 << 10)
|
||||
#define GATT_ATTR_OP_SPT_EXE_WRITE (0x00000001 << 11)
|
||||
#define GATT_ATTR_OP_SPT_HDL_VALUE_CONF (0x00000001 << 12)
|
||||
#define GATT_ATTR_OP_SP_SIGN_WRITE (0x00000001 << 13)
|
||||
#define GATT_ATTR_OP_SP_SIGN_WRITE (0x00000001 << 13)
|
||||
|
||||
#define GATT_INDEX_INVALID 0xff
|
||||
#define GATT_INDEX_INVALID 0xff
|
||||
|
||||
#define GATT_PENDING_REQ_NONE 0
|
||||
#define GATT_PENDING_REQ_NONE 0
|
||||
|
||||
|
||||
#define GATT_WRITE_CMD_MASK 0xc0 /*0x1100-0000*/
|
||||
#define GATT_AUTH_SIGN_MASK 0x80 /*0x1000-0000*/
|
||||
#define GATT_AUTH_SIGN_LEN 12
|
||||
#define GATT_WRITE_CMD_MASK 0xc0 /*0x1100-0000*/
|
||||
#define GATT_AUTH_SIGN_MASK 0x80 /*0x1000-0000*/
|
||||
#define GATT_AUTH_SIGN_LEN 12
|
||||
|
||||
#define GATT_HDR_SIZE 3 /* 1B opcode + 2B handle */
|
||||
|
||||
@@ -154,7 +157,7 @@ typedef union {
|
||||
tBT_UUID uuid; /* service declaration */
|
||||
tGATT_CHAR_DECL char_decl; /* characteristic declaration */
|
||||
tGATT_INCL_SRVC incl_handle; /* included service */
|
||||
|
||||
tGATT_ATTR_VAL attr_val;
|
||||
} tGATT_ATTR_VALUE;
|
||||
|
||||
/* Attribute UUID type
|
||||
@@ -167,50 +170,49 @@ typedef UINT8 tGATT_ATTR_UUID_TYPE;
|
||||
/* 16 bits UUID Attribute in server database
|
||||
*/
|
||||
typedef struct {
|
||||
void *p_next; /* pointer to the next attribute,
|
||||
either tGATT_ATTR16 or tGATT_ATTR128 */
|
||||
tGATT_ATTR_VALUE *p_value;
|
||||
tGATT_ATTR_UUID_TYPE uuid_type;
|
||||
tGATT_PERM permission;
|
||||
UINT16 handle;
|
||||
UINT16 uuid;
|
||||
void *p_next; /* pointer to the next attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
|
||||
tGATT_ATTR_VALUE *p_value;
|
||||
tGATT_ATTR_UUID_TYPE uuid_type;
|
||||
tGATT_PERM permission;
|
||||
tGATTS_ATTR_CONTROL control;
|
||||
UINT16 handle;
|
||||
UINT16 uuid;
|
||||
} tGATT_ATTR16;
|
||||
|
||||
/* 32 bits UUID Attribute in server database
|
||||
*/
|
||||
typedef struct {
|
||||
void *p_next; /* pointer to the next attribute,
|
||||
either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */
|
||||
tGATT_ATTR_VALUE *p_value;
|
||||
tGATT_ATTR_UUID_TYPE uuid_type;
|
||||
tGATT_PERM permission;
|
||||
UINT16 handle;
|
||||
UINT32 uuid;
|
||||
void *p_next; /* pointer to the next attribute, either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */
|
||||
tGATT_ATTR_VALUE *p_value;
|
||||
tGATT_ATTR_UUID_TYPE uuid_type;
|
||||
tGATT_PERM permission;
|
||||
tGATTS_ATTR_CONTROL control;
|
||||
UINT16 handle;
|
||||
UINT32 uuid;
|
||||
} tGATT_ATTR32;
|
||||
|
||||
|
||||
/* 128 bits UUID Attribute in server database
|
||||
*/
|
||||
typedef struct {
|
||||
void *p_next; /* pointer to the next attribute,
|
||||
either tGATT_ATTR16 or tGATT_ATTR128 */
|
||||
tGATT_ATTR_VALUE *p_value;
|
||||
tGATT_ATTR_UUID_TYPE uuid_type;
|
||||
tGATT_PERM permission;
|
||||
UINT16 handle;
|
||||
UINT8 uuid[LEN_UUID_128];
|
||||
void *p_next; /* pointer to the next attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
|
||||
tGATT_ATTR_VALUE *p_value;
|
||||
tGATT_ATTR_UUID_TYPE uuid_type;
|
||||
tGATT_PERM permission;
|
||||
tGATTS_ATTR_CONTROL control;
|
||||
UINT16 handle;
|
||||
UINT8 uuid[LEN_UUID_128];
|
||||
} tGATT_ATTR128;
|
||||
|
||||
/* Service Database definition
|
||||
*/
|
||||
typedef struct {
|
||||
void *p_attr_list; /* pointer to the first attribute,
|
||||
either tGATT_ATTR16 or tGATT_ATTR128 */
|
||||
UINT8 *p_free_mem; /* Pointer to free memory */
|
||||
BUFFER_Q svc_buffer; /* buffer queue used for service database */
|
||||
UINT32 mem_free; /* Memory still available */
|
||||
UINT16 end_handle; /* Last handle number */
|
||||
UINT16 next_handle; /* Next usable handle value */
|
||||
void *p_attr_list; /* pointer to the first attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
|
||||
UINT8 *p_free_mem; /* Pointer to free memory */
|
||||
BUFFER_Q svc_buffer; /* buffer queue used for service database */
|
||||
UINT32 mem_free; /* Memory still available */
|
||||
UINT16 end_handle; /* Last handle number */
|
||||
UINT16 next_handle; /* Next usable handle value */
|
||||
} tGATT_SVC_DB;
|
||||
|
||||
/* Data Structure used for GATT server */
|
||||
@@ -218,14 +220,14 @@ typedef struct {
|
||||
/* A service registration information record consists of beginning and ending */
|
||||
/* attribute handle, service UUID and a set of GATT server callback. */
|
||||
typedef struct {
|
||||
tGATT_SVC_DB *p_db; /* pointer to the service database */
|
||||
tGATT_SVC_DB *p_db; /* pointer to the service database */
|
||||
tBT_UUID app_uuid; /* applicatino UUID */
|
||||
UINT32 sdp_handle; /* primamry service SDP handle */
|
||||
UINT32 sdp_handle; /* primamry service SDP handle */
|
||||
UINT16 service_instance; /* service instance number */
|
||||
UINT16 type; /* service type UUID, primary or secondary */
|
||||
UINT16 s_hdl; /* service starting handle */
|
||||
UINT16 e_hdl; /* service ending handle */
|
||||
tGATT_IF gatt_if; /* this service is belong to which application */
|
||||
UINT16 type; /* service type UUID, primary or secondary */
|
||||
UINT16 s_hdl; /* service starting handle */
|
||||
UINT16 e_hdl; /* service ending handle */
|
||||
tGATT_IF gatt_if; /* this service is belong to which application */
|
||||
BOOLEAN in_use;
|
||||
} tGATT_SR_REG;
|
||||
|
||||
@@ -340,7 +342,7 @@ typedef struct {
|
||||
tGATT_CH_STATE ch_state;
|
||||
UINT8 ch_flags;
|
||||
|
||||
tGATT_IF app_hold_link[GATT_MAX_APPS];
|
||||
tGATT_IF app_hold_link[GATT_MAX_APPS];
|
||||
|
||||
/* server needs */
|
||||
/* server response data */
|
||||
@@ -350,13 +352,13 @@ typedef struct {
|
||||
|
||||
TIMER_LIST_ENT conf_timer_ent; /* peer confirm to indication timer */
|
||||
|
||||
UINT8 prep_cnt[GATT_MAX_APPS];
|
||||
UINT8 ind_count;
|
||||
UINT8 prep_cnt[GATT_MAX_APPS];
|
||||
UINT8 ind_count;
|
||||
|
||||
tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB];
|
||||
TIMER_LIST_ENT ind_ack_timer_ent; /* local app confirm to indication timer */
|
||||
UINT8 pending_cl_req;
|
||||
UINT8 next_slot_inq; /* index of next available slot in queue */
|
||||
tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB];
|
||||
TIMER_LIST_ENT ind_ack_timer_ent; /* local app confirm to indication timer */
|
||||
UINT8 pending_cl_req;
|
||||
UINT8 next_slot_inq; /* index of next available slot in queue */
|
||||
|
||||
BOOLEAN in_use;
|
||||
UINT8 tcb_idx;
|
||||
@@ -579,6 +581,7 @@ extern BOOLEAN gatt_cl_send_next_cmd_inq(tGATT_TCB *p_tcb);
|
||||
/* reserved handle list */
|
||||
extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst);
|
||||
extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle);
|
||||
extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle);
|
||||
extern tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void);
|
||||
extern void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p);
|
||||
extern BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value);
|
||||
@@ -664,12 +667,27 @@ extern void gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act);
|
||||
/* gatt_db.c */
|
||||
extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle);
|
||||
extern UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, tBT_UUID service);
|
||||
extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tGATT_CHAR_PROP property, tBT_UUID *p_char_uuid);
|
||||
extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID *p_dscp_uuid);
|
||||
extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
|
||||
tGATT_CHAR_PROP property,
|
||||
tBT_UUID *p_char_uuid, tGATT_ATTR_VAL *attr_val,
|
||||
tGATTS_ATTR_CONTROL *control);
|
||||
extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
|
||||
tBT_UUID *p_dscp_uuid, tGATT_ATTR_VAL *attr_val,
|
||||
tGATTS_ATTR_CONTROL *control);
|
||||
|
||||
extern tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
||||
UINT16 length, UINT8 *value);
|
||||
|
||||
extern tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
|
||||
UINT16 *length, UINT8 **value);
|
||||
extern BOOLEAN gatts_is_auto_response(UINT16 attr_handle);
|
||||
extern tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, BT_HDR *p_rsp, UINT16 s_handle,
|
||||
UINT16 e_handle, tBT_UUID type, UINT16 *p_len, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id, UINT16 *p_cur_handle);
|
||||
extern tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset,
|
||||
UINT8 *p_value, UINT16 *p_len, UINT16 mtu, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id);
|
||||
extern tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
|
||||
UINT16 handle, UINT16 offset,
|
||||
UINT8 *p_value, UINT16 len);
|
||||
extern tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset, UINT8 *p_data,
|
||||
UINT16 len, tGATT_SEC_FLAG sec_flag, UINT8 key_size);
|
||||
extern tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db, BOOLEAN is_long, UINT16 handle, tGATT_SEC_FLAG sec_flag, UINT8 key_size);
|
||||
|
@@ -63,6 +63,8 @@
|
||||
#define GATT_ENCRYPED_NO_MITM 0x8d
|
||||
#define GATT_NOT_ENCRYPTED 0x8e
|
||||
#define GATT_CONGESTED 0x8f
|
||||
#define GATT_STACK_RSP 0x90
|
||||
#define GATT_APP_RSP 0x91
|
||||
|
||||
/* 0xE0 ~ 0xFC reserved for future use */
|
||||
#define GATT_CCC_CFG_ERR 0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */
|
||||
@@ -117,36 +119,36 @@ typedef UINT16 tGATT_DISCONN_REASON;
|
||||
/* MAX GATT MTU size
|
||||
*/
|
||||
#ifndef GATT_MAX_MTU_SIZE
|
||||
#define GATT_MAX_MTU_SIZE 517
|
||||
#define GATT_MAX_MTU_SIZE 517
|
||||
#endif
|
||||
|
||||
/* max legth of an attribute value
|
||||
*/
|
||||
#ifndef GATT_MAX_ATTR_LEN
|
||||
#define GATT_MAX_ATTR_LEN 600
|
||||
#define GATT_MAX_ATTR_LEN 600
|
||||
#endif
|
||||
|
||||
/* default GATT MTU size over LE link
|
||||
*/
|
||||
#define GATT_DEF_BLE_MTU_SIZE 23
|
||||
#define GATT_DEF_BLE_MTU_SIZE 23
|
||||
|
||||
/* invalid connection ID
|
||||
*/
|
||||
#define GATT_INVALID_CONN_ID 0xFFFF
|
||||
#define GATT_INVALID_CONN_ID 0xFFFF
|
||||
|
||||
#ifndef GATT_CL_MAX_LCB
|
||||
#define GATT_CL_MAX_LCB 12 // 22
|
||||
#define GATT_CL_MAX_LCB 12 // 22
|
||||
#endif
|
||||
|
||||
#ifndef GATT_MAX_SCCB
|
||||
#define GATT_MAX_SCCB 10
|
||||
#define GATT_MAX_SCCB 10
|
||||
#endif
|
||||
|
||||
|
||||
/* GATT notification caching timer, default to be three seconds
|
||||
*/
|
||||
#ifndef GATTC_NOTIF_TIMEOUT
|
||||
#define GATTC_NOTIF_TIMEOUT 3
|
||||
#define GATTC_NOTIF_TIMEOUT 3
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -155,22 +157,22 @@ typedef UINT16 tGATT_DISCONN_REASON;
|
||||
|
||||
/* Attribute permissions
|
||||
*/
|
||||
#define GATT_PERM_READ (1 << 0) /* bit 0 */
|
||||
#define GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 */
|
||||
#define GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 */
|
||||
#define GATT_PERM_WRITE (1 << 4) /* bit 4 */
|
||||
#define GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 */
|
||||
#define GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 */
|
||||
#define GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 */
|
||||
#define GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 */
|
||||
#define GATT_PERM_READ (1 << 0) /* bit 0 */
|
||||
#define GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 */
|
||||
#define GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 */
|
||||
#define GATT_PERM_WRITE (1 << 4) /* bit 4 */
|
||||
#define GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 */
|
||||
#define GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 */
|
||||
#define GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 */
|
||||
#define GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 */
|
||||
typedef UINT16 tGATT_PERM;
|
||||
|
||||
#define GATT_ENCRYPT_KEY_SIZE_MASK (0xF000) /* the MS nibble of tGATT_PERM; key size 7=0; size 16=9 */
|
||||
|
||||
#define GATT_READ_ALLOWED (GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
|
||||
#define GATT_READ_AUTH_REQUIRED (GATT_PERM_READ_ENCRYPTED)
|
||||
#define GATT_READ_MITM_REQUIRED (GATT_PERM_READ_ENC_MITM)
|
||||
#define GATT_READ_ENCRYPTED_REQUIRED (GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
|
||||
#define GATT_READ_ALLOWED (GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
|
||||
#define GATT_READ_AUTH_REQUIRED (GATT_PERM_READ_ENCRYPTED)
|
||||
#define GATT_READ_MITM_REQUIRED (GATT_PERM_READ_ENC_MITM)
|
||||
#define GATT_READ_ENCRYPTED_REQUIRED (GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
|
||||
|
||||
|
||||
#define GATT_WRITE_ALLOWED (GATT_PERM_WRITE | GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM | \
|
||||
@@ -312,6 +314,16 @@ typedef struct {
|
||||
UINT8 value[GATT_MAX_ATTR_LEN]; /* the actual attribute value */
|
||||
} tGATT_VALUE;
|
||||
|
||||
typedef struct{
|
||||
UINT16 attr_max_len;
|
||||
UINT16 attr_len;
|
||||
UINT8 *attr_val;
|
||||
}tGATT_ATTR_VAL;
|
||||
|
||||
typedef struct{
|
||||
uint8_t auto_rsp;
|
||||
}tGATTS_ATTR_CONTROL;
|
||||
|
||||
/* Union of the event data which is used in the server respond API to carry the server response information
|
||||
*/
|
||||
typedef union {
|
||||
@@ -337,6 +349,7 @@ typedef struct {
|
||||
UINT16 handle;
|
||||
UINT16 offset;
|
||||
BOOLEAN is_long;
|
||||
BOOLEAN need_rsp;
|
||||
} tGATT_READ_REQ;
|
||||
|
||||
/* write request data */
|
||||
@@ -740,8 +753,9 @@ extern UINT16 GATTS_AddIncludeService (UINT16 service_handle,
|
||||
** characteristic failed.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *char_uuid,
|
||||
tGATT_PERM perm, tGATT_CHAR_PROP property);
|
||||
extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
|
||||
tGATT_PERM perm, tGATT_CHAR_PROP property,
|
||||
tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -763,7 +777,8 @@ extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *char_uui
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern UINT16 GATTS_AddCharDescriptor (UINT16 service_handle, tGATT_PERM perm,
|
||||
tBT_UUID *p_descr_uuid);
|
||||
tBT_UUID *p_descr_uuid, tGATT_ATTR_VAL *attr_val,
|
||||
tGATTS_ATTR_CONTROL *control);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -866,6 +881,39 @@ extern tGATT_STATUS GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
|
||||
tGATT_STATUS status, tGATTS_RSP *p_msg);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GATTS_SetAttributeValue
|
||||
**
|
||||
** Description This function sends to set the attribute value .
|
||||
**
|
||||
** Parameter attr_handle:the attribute handle
|
||||
** length: the attribute length
|
||||
** value: the value to be set to the attribute in the database
|
||||
**
|
||||
** Returns GATT_SUCCESS if sucessfully sent; otherwise error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GATTS_GetAttributeValue
|
||||
**
|
||||
** Description This function sends to set the attribute value .
|
||||
**
|
||||
** Parameter attr_handle: the attribute handle
|
||||
** length:the attribute value length in the database
|
||||
** value: the attribute value out put
|
||||
**
|
||||
** Returns GATT_SUCCESS if sucessfully sent; otherwise error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value);
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* GATT Profile Client Functions */
|
||||
/*******************************************************************************/
|
||||
|
@@ -419,7 +419,7 @@ static const UINT8 smp_master_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS]
|
||||
static const UINT8 smp_slave_entry_map[][SMP_STATE_MAX] = {
|
||||
/* state name: Idle WaitApp SecReq Pair Wait Confirm Rand PublKey SCPhs1 Wait Wait SCPhs2 Wait DHKChk Enc Bond CrLocSc
|
||||
Rsp Pend ReqRsp Cfm Exch Strt Cmtm Nonce Strt DHKChk Pend Pend OobData */
|
||||
/* PAIR_REQ */{ 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* PAIR_REQ */{ 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* PAIR_RSP */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CONFIRM */{ 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* RAND */{ 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
||||
|
Reference in New Issue
Block a user