diff options
Diffstat (limited to 'stack/gatt/gatt_db.c')
-rw-r--r-- | stack/gatt/gatt_db.c | 136 |
1 files changed, 96 insertions, 40 deletions
diff --git a/stack/gatt/gatt_db.c b/stack/gatt/gatt_db.c index 268bc7d78..a1b0a8aa7 100644 --- a/stack/gatt/gatt_db.c +++ b/stack/gatt/gatt_db.c @@ -27,6 +27,7 @@ #if BLE_INCLUDED == TRUE #include "bt_trace.h" +#include "bt_utils.h" #include <stdio.h> #include <string.h> @@ -38,11 +39,11 @@ ** L O C A L F U N C T I O N P R O T O T Y P E S * *********************************************************************************/ static BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db); -static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *p_uuid128, tGATT_PERM perm); +static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm); static BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr); static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len); -static void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri); +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); @@ -58,7 +59,7 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code, ** Returns Status of te operation. ** *******************************************************************************/ -BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri, +BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle) { if (!allocate_svc_db_buf(p_db)) @@ -74,9 +75,7 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is p_db->next_handle = s_hdl; p_db->end_handle = s_hdl + num_handle; - gatts_db_add_service_declaration(p_db, service, is_pri); - - return TRUE; + return gatts_db_add_service_declaration(p_db, p_service, is_pri); } /******************************************************************************* @@ -115,6 +114,7 @@ tBT_UUID * gatts_get_service_uuid (tGATT_SVC_DB *p_db) ** *******************************************************************************/ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr, + UINT16 offset, BOOLEAN read_long, tGATT_SEC_FLAG sec_flag, UINT8 key_size) @@ -122,6 +122,7 @@ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr, UINT16 min_key_size; tGATT_PERM perm = p_attr->permission; + UNUSED(offset); min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12)); if (min_key_size != 0 ) { @@ -223,14 +224,14 @@ static tGATT_STATUS read_attr_value (void *p_attr, offset, read_long); - status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, read_long, sec_flag, key_size); - - if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) - uuid16 = p_attr16->uuid; + status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, offset, read_long, sec_flag, key_size); if (status != GATT_SUCCESS) return status; + if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) + uuid16 = p_attr16->uuid; + status = GATT_NO_RESOURCES; if (read_long && @@ -261,6 +262,12 @@ static tGATT_STATUS read_attr_value (void *p_attr, { UINT16_TO_STREAM(p, ((tGATT_ATTR16 *)(p_attr16->p_next))->uuid); } + /* convert a 32bits UUID to 128 bits */ + else if (((tGATT_ATTR32 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_32) + { + gatt_convert_uuid32_to_uuid128 (p, ((tGATT_ATTR32 *)(p_attr16->p_next))->uuid); + p += LEN_UUID_128; + } else { ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *)(p_attr16->p_next))->uuid, LEN_UUID_128); @@ -271,13 +278,17 @@ static tGATT_STATUS read_attr_value (void *p_attr, } else if (uuid16 == GATT_UUID_INCLUDE_SERVICE) { - len = (p_attr16->p_value->incl_handle.service_type.len == 2) ? 6 : 4; + if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16) + len = 6; + else + len = 4; + if (mtu >= len) { UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.s_handle); UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.e_handle); - if (p_attr16->p_value->incl_handle.service_type.len == 2) + if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16) { UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.service_type.uu.uuid16); } @@ -345,6 +356,11 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb, attr_uuid.len = LEN_UUID_16; attr_uuid.uu.uuid16 = p_attr->uuid; } + else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32) + { + attr_uuid.len = LEN_UUID_32; + attr_uuid.uu.uuid32 = ((tGATT_ATTR32 *)p_attr)->uuid; + } else { attr_uuid.len = LEN_UUID_128; @@ -436,6 +452,7 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e tBT_UUID service) { tGATT_ATTR16 *p_attr; + tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_INCLUDE_SERVICE}}; GATT_TRACE_DEBUG3("gatts_add_included_service: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x", s_handle, e_handle, service.uu.uuid16); @@ -446,7 +463,7 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e return 0; } - if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, GATT_UUID_INCLUDE_SERVICE, NULL, GATT_PERM_READ)) != NULL) + if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) { if (copy_extra_byte_in_db(p_db, (void **)&p_attr->p_value, sizeof(tGATT_INCL_SRVC))) { @@ -485,11 +502,11 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID * p_char_uuid) { tGATT_ATTR16 *p_char_decl, *p_char_val; - UINT16 uuid16 = (p_char_uuid->len == LEN_UUID_16) ? p_char_uuid->uu.uuid16 : 0; + tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}}; GATT_TRACE_DEBUG2("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property); - if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, GATT_UUID_CHAR_DECLARE, NULL, GATT_PERM_READ)) != NULL) + 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))) { @@ -497,7 +514,7 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, return 0; } - p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, uuid16, p_char_uuid->uu.uuid128, perm); + p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_char_uuid, perm); if (p_char_val == NULL) { @@ -578,14 +595,12 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID * p_descr_uuid) { tGATT_ATTR16 *p_char_dscptr; - UINT16 uuid16 = (p_descr_uuid->len == LEN_UUID_16)? p_descr_uuid->uu.uuid16 : 0; GATT_TRACE_DEBUG1("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16); /* Add characteristic descriptors */ if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, - uuid16, - p_descr_uuid->uu.uuid128, + p_descr_uuid, perm)) == NULL) { @@ -695,7 +710,7 @@ tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db, { if (p_attr->handle == handle) { - status = gatts_check_attr_readability (p_attr, + status = gatts_check_attr_readability (p_attr, 0, is_long, sec_flag, key_size); break; @@ -812,7 +827,8 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE"); } /* LE security mode 2 attribute */ - else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) + else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED) + && (perm & GATT_WRITE_ALLOWED) == 0) { status = GATT_INSUF_AUTHENTICATION; GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required"); @@ -842,7 +858,8 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, break; } } - else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128) + else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 || + p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32) { status = GATT_SUCCESS; } @@ -897,25 +914,32 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, ** ** ** Parameter p_db : database pointer. +** p_uuid: pointer to attribute UUID ** service : type of attribute to be added. ** ** Returns pointer to the newly allocated attribute. ** *******************************************************************************/ -static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid128, tGATT_PERM perm) +static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm) { tGATT_ATTR16 *p_attr16 = NULL, *p_last; + tGATT_ATTR32 *p_attr32 = NULL; tGATT_ATTR128 *p_attr128 = NULL; - UINT16 len = (uuid16 == 0) ? sizeof(tGATT_ATTR128): sizeof(tGATT_ATTR16); + UINT16 len = sizeof(tGATT_ATTR128); - GATT_TRACE_DEBUG1("allocate attr %d bytes ",len); - - if (uuid16 == GATT_ILLEGAL_UUID && uuid128 == NULL) + if (p_uuid == NULL) { GATT_TRACE_ERROR0("illegal UUID"); return NULL; } + if (p_uuid->len == LEN_UUID_16) + len = sizeof(tGATT_ATTR16); + else if (p_uuid->len == LEN_UUID_32) + len = sizeof(tGATT_ATTR32); + + GATT_TRACE_DEBUG1("allocate attr %d bytes ",len); + if (p_db->end_handle <= p_db->next_handle) { GATT_TRACE_DEBUG2("handle space full. handle_max = %d next_handle = %d", @@ -931,21 +955,25 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid1 return NULL; } } - + memset(p_db->p_free_mem, 0, len); p_attr16 = (tGATT_ATTR16 *) p_db->p_free_mem; - p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem; - - memset(p_attr16, 0, len); - if (uuid16 != GATT_ILLEGAL_UUID) + if (p_uuid->len == LEN_UUID_16 && p_uuid->uu.uuid16 != GATT_ILLEGAL_UUID) { p_attr16->uuid_type = GATT_ATTR_UUID_TYPE_16; - p_attr16->uuid = uuid16; + p_attr16->uuid = p_uuid->uu.uuid16; } - else + else if (p_uuid->len == LEN_UUID_32) { + p_attr32 = (tGATT_ATTR32 *) p_db->p_free_mem; + p_attr32->uuid_type = GATT_ATTR_UUID_TYPE_32; + p_attr32->uuid = p_uuid->uu.uuid32; + } + else if (p_uuid->len == LEN_UUID_128) + { + p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem; p_attr128->uuid_type = GATT_ATTR_UUID_TYPE_128; - memcpy(p_attr128->uuid, uuid128, LEN_UUID_128); + memcpy(p_attr128->uuid, p_uuid->uu.uuid128, LEN_UUID_128); } p_db->p_free_mem += len; @@ -970,9 +998,14 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid1 if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) { - GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid = [0x%04x] perm=0x%02x ", + GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ", p_attr16->handle, p_attr16->uuid, p_attr16->permission); } + else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) + { + GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ", + p_attr32->handle, p_attr32->uuid, p_attr32->permission); + } else { GATT_TRACE_DEBUG4("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ", @@ -1151,21 +1184,44 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code, ** Returns void ** *******************************************************************************/ -static void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri) +static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri) { tGATT_ATTR16 *p_attr; - UINT16 service_type = is_pri ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE; + tBT_UUID uuid = {LEN_UUID_16, {0}}; + BOOLEAN rt = FALSE; GATT_TRACE_DEBUG0( "add_service_declaration"); + if (is_pri) + uuid.uu.uuid16 = GATT_UUID_PRI_SERVICE; + else + uuid.uu.uuid16 = GATT_UUID_SEC_SERVICE; + /* add service declration record */ - if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, service_type, NULL, GATT_PERM_READ))) != NULL) + if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ))) != NULL) { if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID))) { - memcpy (&p_attr->p_value->uuid, &service, sizeof(tBT_UUID)); + if (p_service->len == LEN_UUID_16) + { + p_attr->p_value->uuid.len = LEN_UUID_16; + p_attr->p_value->uuid.uu.uuid16 = p_service->uu.uuid16; + } + else if (p_service->len == LEN_UUID_32) + { + p_attr->p_value->uuid.len = LEN_UUID_128; + gatt_convert_uuid32_to_uuid128(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid32); + } + else + { + p_attr->p_value->uuid.len = LEN_UUID_128; + memcpy(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid128, LEN_UUID_128); + } + rt = TRUE; } + } + return rt; } #endif /* BLE_INCLUDED */ |