summaryrefslogtreecommitdiffstats
path: root/stack/gatt/gatt_db.c
diff options
context:
space:
mode:
Diffstat (limited to 'stack/gatt/gatt_db.c')
-rw-r--r--stack/gatt/gatt_db.c136
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 */