You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/07/13 20:55:20 UTC
[07/50] [abbrv] incubator-mynewt-core git commit: BLE Host - Lookup
svc, chr, dsc handles by UUID.
BLE Host - Lookup svc,chr,dsc handles by UUID.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/787463b5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/787463b5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/787463b5
Branch: refs/heads/develop
Commit: 787463b5aac59a6d089621c00be14649cb3a97d5
Parents: 2997fff
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Jun 29 10:10:57 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Mon Jul 11 16:43:32 2016 -0700
----------------------------------------------------------------------
net/nimble/host/include/host/ble_gatt.h | 7 +
net/nimble/host/src/ble_att_priv.h | 5 +-
net/nimble/host/src/ble_att_svr.c | 20 +-
net/nimble/host/src/ble_gatts.c | 253 ++++++++++++++++++---
net/nimble/host/src/test/ble_gatts_reg_test.c | 252 +++++++++++++++++++-
5 files changed, 483 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/787463b5/net/nimble/host/include/host/ble_gatt.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gatt.h b/net/nimble/host/include/host/ble_gatt.h
index d805590..e69e59b 100644
--- a/net/nimble/host/include/host/ble_gatt.h
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -356,6 +356,13 @@ typedef void ble_gatt_register_fn(uint8_t op,
int ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs,
ble_gatt_register_fn *register_cb,
void *cb_arg);
+
void ble_gatts_chr_updated(uint16_t chr_def_handle);
+int ble_gatts_find_svc(const void *uuid128, uint16_t *out_handle);
+int ble_gatts_find_chr(const void *svc_uuid128, const void *chr_uuid128,
+ uint16_t *out_def_handle, uint16_t *out_val_handle);
+int ble_gatts_find_dsc(const void *svc_uuid128, const void *chr_uuid128,
+ const void *dsc_uuid128, uint16_t *out_dsc_handle);
+
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/787463b5/net/nimble/host/src/ble_att_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_priv.h b/net/nimble/host/src/ble_att_priv.h
index 5506c58..c1da676 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -156,9 +156,12 @@ int ble_att_init(void);
/*** @svr */
struct ble_att_svr_entry *
-ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at, uint8_t *uuid);
+ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at,
+ const uint8_t *uuid,
+ uint16_t end_handle);
uint16_t ble_att_svr_prev_handle(void);
int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **om);
+struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id);
int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
int ble_att_svr_rx_find_type_value(uint16_t conn_handle,
struct os_mbuf **rxom);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/787463b5/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index f7a5d36..8e57452 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -25,7 +25,9 @@
#include "host/ble_uuid.h"
#include "ble_hs_priv.h"
-static STAILQ_HEAD(, ble_att_svr_entry) ble_att_svr_list;
+STAILQ_HEAD(ble_att_svr_entry_list, ble_att_svr_entry);
+static struct ble_att_svr_entry_list ble_att_svr_list;
+
static uint16_t ble_att_svr_id;
static void *ble_att_svr_entry_mem;
@@ -159,7 +161,7 @@ ble_att_svr_find_by_handle(uint16_t handle_id)
* Find a host attribute by UUID.
*
* @param uuid The ble_uuid_t to search for
- * @param ha_ptr On input: Indicates the starting point of the
+ * @param prev On input: Indicates the starting point of the
* walk; null means start at the beginning of
* the list, non-null means start at the
* following entry.
@@ -170,7 +172,8 @@ ble_att_svr_find_by_handle(uint16_t handle_id)
* @return 0 on success; BLE_HS_ENOENT on not found.
*/
struct ble_att_svr_entry *
-ble_att_svr_find_by_uuid(struct ble_att_svr_entry *prev, uint8_t *uuid)
+ble_att_svr_find_by_uuid(struct ble_att_svr_entry *prev, const uint8_t *uuid,
+ uint16_t end_handle)
{
struct ble_att_svr_entry *entry;
@@ -180,7 +183,10 @@ ble_att_svr_find_by_uuid(struct ble_att_svr_entry *prev, uint8_t *uuid)
entry = STAILQ_NEXT(prev, ha_next);
}
- for (; entry != NULL; entry = STAILQ_NEXT(entry, ha_next)) {
+ for (;
+ entry != NULL && entry->ha_handle_id <= end_handle;
+ entry = STAILQ_NEXT(entry, ha_next)) {
+
if (memcmp(entry->ha_uuid, uuid, sizeof entry->ha_uuid) == 0) {
return entry;
}
@@ -1247,16 +1253,12 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle,
/* Find all matching attributes, writing a record for each. */
entry = NULL;
while (1) {
- entry = ble_att_svr_find_by_uuid(entry, uuid128);
+ entry = ble_att_svr_find_by_uuid(entry, uuid128, req->batq_end_handle);
if (entry == NULL) {
rc = BLE_HS_ENOENT;
break;
}
- if (entry->ha_handle_id > req->batq_end_handle) {
- break;
- }
-
if (entry->ha_handle_id >= req->batq_start_handle) {
ctxt.read.offset = 0;
rc = ble_att_svr_read(conn_handle, entry, &ctxt, att_err);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/787463b5/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
index 0665758..82f21b2 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -35,7 +35,7 @@ struct ble_gatts_svc_entry {
};
static struct ble_gatts_svc_entry *ble_gatts_svc_entries;
-static int ble_gatts_num_svc_entries;
+static uint16_t ble_gatts_num_svc_entries;
static os_membuf_t *ble_gatts_clt_cfg_mem;
static struct os_mempool ble_gatts_clt_cfg_pool;
@@ -95,8 +95,6 @@ ble_gatts_inc_access(uint16_t conn_handle, uint16_t attr_handle,
uint8_t *uuid128, uint8_t op,
struct ble_att_svr_access_ctxt *ctxt, void *arg)
{
- static uint8_t buf[BLE_GATTS_INCLUDE_SZ];
-
const struct ble_gatts_svc_entry *entry;
uint16_t uuid16;
@@ -106,18 +104,17 @@ ble_gatts_inc_access(uint16_t conn_handle, uint16_t attr_handle,
entry = arg;
- htole16(buf + 0, entry->handle);
- htole16(buf + 2, entry->end_group_handle);
+ htole16(ctxt->read.buf + 0, entry->handle);
+ htole16(ctxt->read.buf + 2, entry->end_group_handle);
/* Only include the service UUID if it has a 16-bit representation. */
uuid16 = ble_uuid_128_to_16(entry->svc->uuid128);
if (uuid16 != 0) {
- htole16(buf + 4, uuid16);
+ htole16(ctxt->read.buf + 4, uuid16);
ctxt->read.len = 6;
} else {
ctxt->read.len = 4;
}
- ctxt->read.data = buf;
return 0;
}
@@ -323,7 +320,7 @@ ble_gatts_chr_val_access(uint16_t conn_handle, uint16_t attr_handle,
}
static int
-ble_gatts_find_svc(const struct ble_gatt_svc_def *svc)
+ble_gatts_find_svc_entry_idx(const struct ble_gatt_svc_def *svc)
{
int i;
@@ -348,7 +345,7 @@ ble_gatts_svc_incs_satisfied(const struct ble_gatt_svc_def *svc)
}
for (i = 0; svc->includes[i] != NULL; i++) {
- idx = ble_gatts_find_svc(svc->includes[i]);
+ idx = ble_gatts_find_svc_entry_idx(svc->includes[i]);
if (idx == -1 || ble_gatts_svc_entries[idx].handle == 0) {
return 0;
}
@@ -462,8 +459,9 @@ ble_gatts_dsc_is_sane(const struct ble_gatt_dsc_def *dsc)
}
static int
-ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc,
+ble_gatts_register_dsc(const struct ble_gatt_svc_def *svc,
const struct ble_gatt_chr_def *chr,
+ const struct ble_gatt_dsc_def *dsc,
uint16_t chr_def_handle,
ble_gatt_register_fn *register_cb, void *cb_arg)
{
@@ -482,11 +480,10 @@ ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc,
}
if (register_cb != NULL) {
- register_ctxt.dsc.dsc_handle = dsc_handle;
- register_ctxt.dsc.dsc_def = dsc;
- register_ctxt.dsc.chr_def_handle = chr_def_handle;
- register_ctxt.dsc.chr_val_handle = chr_def_handle + 1;
+ register_ctxt.dsc.handle = dsc_handle;
+ register_ctxt.dsc.svc_def = svc;
register_ctxt.dsc.chr_def = chr;
+ register_ctxt.dsc.dsc_def = dsc;
register_cb(BLE_GATT_REGISTER_OP_DSC, ®ister_ctxt, cb_arg);
}
@@ -695,6 +692,13 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
return BLE_HS_EINVAL;
}
+ if (ble_gatts_chr_clt_cfg_allowed(chr) != 0) {
+ if (ble_gatts_num_cfgable_chrs > ble_hs_cfg.max_client_configs) {
+ return BLE_HS_ENOMEM;
+ }
+ ble_gatts_num_cfgable_chrs++;
+ }
+
/* Register characteristic definition attribute (cast away const on
* callback arg).
*/
@@ -723,7 +727,7 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
if (register_cb != NULL) {
register_ctxt.chr.def_handle = def_handle;
register_ctxt.chr.val_handle = val_handle;
- register_ctxt.svc.svc_def = svc;
+ register_ctxt.chr.svc_def = svc;
register_ctxt.chr.chr_def = chr;
register_cb(BLE_GATT_REGISTER_OP_CHR, ®ister_ctxt, cb_arg);
}
@@ -739,7 +743,7 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
/* Register each descriptor. */
if (chr->descriptors != NULL) {
for (dsc = chr->descriptors; dsc->uuid128 != NULL; dsc++) {
- rc = ble_gatts_register_dsc(dsc, chr, def_handle, register_cb,
+ rc = ble_gatts_register_dsc(svc, chr, dsc, def_handle, register_cb,
cb_arg);
if (rc != 0) {
return rc;
@@ -829,7 +833,7 @@ ble_gatts_register_svc(const struct ble_gatt_svc_def *svc,
/* Register each include. */
if (svc->includes != NULL) {
for (i = 0; svc->includes[i] != NULL; i++) {
- idx = ble_gatts_find_svc(svc->includes[i]);
+ idx = ble_gatts_find_svc_entry_idx(svc->includes[i]);
BLE_HS_DBG_ASSERT_EVAL(idx != -1);
rc = ble_gatts_register_inc(ble_gatts_svc_entries + idx);
@@ -879,7 +883,7 @@ ble_gatts_register_round(int *out_num_registered, ble_gatt_register_fn *cb,
case BLE_HS_EAGAIN:
/* Service could not be registered due to unsatisfied includes.
- * Try again on the next itereation.
+ * Try again on the next iteration.
*/
break;
@@ -959,26 +963,10 @@ ble_gatts_start(void)
int idx;
int rc;
- rc = ble_uuid_16_to_128(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
- BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-
- /* Count the number of client-configurable characteristics. */
- ble_gatts_num_cfgable_chrs = 0;
- ha = NULL;
- while ((ha = ble_att_svr_find_by_uuid(ha, uuid128)) != NULL) {
- chr = ha->ha_cb_arg;
- if (ble_gatts_chr_clt_cfg_allowed(chr) != 0) {
- ble_gatts_num_cfgable_chrs++;
- }
- }
if (ble_gatts_num_cfgable_chrs == 0) {
return 0;
}
- if (ble_gatts_num_cfgable_chrs > ble_hs_cfg.max_client_configs) {
- return BLE_HS_ENOMEM;
- }
-
/* Initialize client-configuration memory pool. */
num_elems = ble_hs_cfg.max_client_configs / ble_gatts_num_cfgable_chrs;
rc = os_mempool_init(&ble_gatts_clt_cfg_pool, num_elems,
@@ -997,9 +985,11 @@ ble_gatts_start(void)
}
/* Fill the cache. */
+ rc = ble_uuid_16_to_128(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
+ BLE_HS_DBG_ASSERT_EVAL(rc == 0);
idx = 0;
ha = NULL;
- while ((ha = ble_att_svr_find_by_uuid(ha, uuid128)) != NULL) {
+ while ((ha = ble_att_svr_find_by_uuid(ha, uuid128, 0xffff)) != NULL) {
chr = ha->ha_cb_arg;
allowed_flags = ble_gatts_chr_clt_cfg_allowed(chr);
if (allowed_flags != 0) {
@@ -1403,6 +1393,199 @@ ble_gatts_bonding_restored(uint16_t conn_handle)
}
}
+static struct ble_gatts_svc_entry *
+ble_gatts_find_svc_entry(const void *uuid128)
+{
+ struct ble_gatts_svc_entry *entry;
+ int i;
+
+ for (i = 0; i < ble_gatts_num_svc_entries; i++) {
+ entry = ble_gatts_svc_entries + i;
+ if (memcmp(uuid128, entry->svc->uuid128, 16) == 0) {
+ return entry;
+ }
+ }
+
+ return NULL;
+}
+
+static int
+ble_gatts_find_svc_chr_attr(const void *svc_uuid128, const void *chr_uuid128,
+ struct ble_gatts_svc_entry **out_svc_entry,
+ struct ble_att_svr_entry **out_att_chr)
+{
+ struct ble_gatts_svc_entry *svc_entry;
+ struct ble_att_svr_entry *att_svc;
+ struct ble_att_svr_entry *next;
+ struct ble_att_svr_entry *cur;
+ uint16_t uuid16;
+
+ svc_entry = ble_gatts_find_svc_entry(svc_uuid128);
+ if (svc_entry == NULL) {
+ return BLE_HS_ENOENT;
+ }
+
+ att_svc = ble_att_svr_find_by_handle(svc_entry->handle);
+ if (att_svc == NULL) {
+ return BLE_HS_EUNKNOWN;
+ }
+
+ cur = STAILQ_NEXT(att_svc, ha_next);
+ while (1) {
+ if (cur == NULL) {
+ /* Reached end of attribute list without a match. */
+ return BLE_HS_ENOENT;
+ }
+ next = STAILQ_NEXT(cur, ha_next);
+
+ if (cur->ha_handle_id == svc_entry->end_group_handle) {
+ /* Reached end of service without a match. */
+ return BLE_HS_ENOENT;
+ }
+
+ uuid16 = ble_uuid_128_to_16(cur->ha_uuid);
+ if (uuid16 == BLE_ATT_UUID_CHARACTERISTIC &&
+ next != NULL &&
+ memcmp(next->ha_uuid, chr_uuid128, 16) == 0) {
+
+ if (out_svc_entry != NULL) {
+ *out_svc_entry = svc_entry;
+ }
+ if (out_att_chr != NULL) {
+ *out_att_chr = next;
+ }
+ return 0;
+ }
+
+ cur = next;
+ }
+}
+
+/**
+ * Retrieves the attribute handle associated with a local GATT service.
+ *
+ * @param uuid128 The UUID of the service to look up.
+ * @param out_handle On success, populated with the handle of the
+ * service attribute. Pass null if you don't
+ * need this value.
+ *
+ * @return 0 on success;
+ * BLE_HS_ENOENT if the specified service could
+ * not be found.
+ */
+int
+ble_gatts_find_svc(const void *uuid128, uint16_t *out_handle)
+{
+ struct ble_gatts_svc_entry *entry;
+
+ entry = ble_gatts_find_svc_entry(uuid128);
+ if (entry == NULL) {
+ return BLE_HS_ENOENT;
+ }
+
+ if (out_handle != NULL) {
+ *out_handle = entry->handle;
+ }
+ return 0;
+}
+
+/**
+ * Retrieves the pair of attribute handles associated with a local GATT
+ * characteristic.
+ *
+ * @param svc_uuid128 The UUID of the parent service.
+ * @param chr_uuid128 The UUID of the characteristic to look up.
+ * @param out_def_handle On success, populated with the handle
+ * of the characteristic definition attribute.
+ * Pass null if you don't need this value.
+ * @param out_val_handle On success, populated with the handle
+ * of the characteristic value attribute.
+ * Pass null if you don't need this value.
+ *
+ * @return 0 on success;
+ * BLE_HS_ENOENT if the specified service or
+ * characteristic could not be found.
+ */
+int
+ble_gatts_find_chr(const void *svc_uuid128, const void *chr_uuid128,
+ uint16_t *out_def_handle, uint16_t *out_val_handle)
+{
+ struct ble_att_svr_entry *att_chr;
+ int rc;
+
+ rc = ble_gatts_find_svc_chr_attr(svc_uuid128, chr_uuid128, NULL, &att_chr);
+ if (rc != 0) {
+ return rc;
+ }
+
+ if (out_def_handle) {
+ *out_def_handle = att_chr->ha_handle_id - 1;
+ }
+ if (out_val_handle) {
+ *out_val_handle = att_chr->ha_handle_id;
+ }
+ return 0;
+}
+
+/**
+ * Retrieves the attribute handle associated with a local GATT descriptor.
+ *
+ * @param svc_uuid128 The UUID of the grandparent service.
+ * @param chr_uuid128 The UUID of the parent characteristic.
+ * @param dsc_uuid128 The UUID of the descriptor ro look up.
+ * @param out_handle On success, populated with the handle
+ * of the descripytor attribute. Pass null if
+ * you don't need this value.
+ *
+ * @return 0 on success;
+ * BLE_HS_ENOENT if the specified service,
+ * characteristic, or descriptor could not be
+ * found.
+ */
+int
+ble_gatts_find_dsc(const void *svc_uuid128, const void *chr_uuid128,
+ const void *dsc_uuid128, uint16_t *out_handle)
+{
+ struct ble_gatts_svc_entry *svc_entry;
+ struct ble_att_svr_entry *att_chr;
+ struct ble_att_svr_entry *cur;
+ uint16_t uuid16;
+ int rc;
+
+ rc = ble_gatts_find_svc_chr_attr(svc_uuid128, chr_uuid128, &svc_entry,
+ &att_chr);
+ if (rc != 0) {
+ return rc;
+ }
+
+ cur = STAILQ_NEXT(att_chr, ha_next);
+ while (1) {
+ if (cur == NULL) {
+ /* Reached end of attribute list without a match. */
+ return BLE_HS_ENOENT;
+ }
+
+ if (cur->ha_handle_id == svc_entry->end_group_handle) {
+ /* Reached end of service without a match. */
+ return BLE_HS_ENOENT;
+ }
+
+ uuid16 = ble_uuid_128_to_16(cur->ha_uuid);
+ if (uuid16 == BLE_ATT_UUID_CHARACTERISTIC) {
+ /* Reached end of characteristic without a match. */
+ return BLE_HS_ENOENT;
+ }
+
+ if (memcmp(cur->ha_uuid, dsc_uuid128, 16) == 0) {
+ if (out_handle != NULL) {
+ *out_handle = cur->ha_handle_id;
+ return 0;
+ }
+ }
+ cur = STAILQ_NEXT(cur, ha_next);
+ }
+}
+
static void
ble_gatts_free_mem(void)
{
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/787463b5/net/nimble/host/src/test/ble_gatts_reg_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatts_reg_test.c b/net/nimble/host/src/test/ble_gatts_reg_test.c
index f6e5841..ff96f74 100644
--- a/net/nimble/host/src/test/ble_gatts_reg_test.c
+++ b/net/nimble/host/src/test/ble_gatts_reg_test.c
@@ -30,6 +30,12 @@
struct ble_gatts_reg_test_entry {
uint8_t op;
uint8_t uuid128[16];
+ uint16_t handle;
+ uint16_t val_handle; /* If a characteristic. */
+
+ const struct ble_gatt_svc_def *svc;
+ const struct ble_gatt_chr_def *chr;
+ const struct ble_gatt_dsc_def *dsc;
};
static struct ble_gatts_reg_test_entry
@@ -54,19 +60,197 @@ ble_gatts_reg_test_misc_reg_cb(uint8_t op, union ble_gatt_register_ctxt *ctxt,
BLE_GATTS_REG_TEST_MAX_ENTRIES);
entry = ble_gatts_reg_test_entries + ble_gatts_reg_test_num_entries++;
+ memset(entry, 0, sizeof *entry);
entry->op = op;
switch (op) {
case BLE_GATT_REGISTER_OP_SVC:
memcpy(entry->uuid128, ctxt->svc.svc_def->uuid128, 16);
+ entry->handle = ctxt->svc.handle;
+ entry->svc = ctxt->svc.svc_def;
break;
case BLE_GATT_REGISTER_OP_CHR:
memcpy(entry->uuid128, ctxt->chr.chr_def->uuid128, 16);
+ entry->handle = ctxt->chr.def_handle;
+ entry->val_handle = ctxt->chr.val_handle;
+ entry->svc = ctxt->chr.svc_def;
+ entry->chr = ctxt->chr.chr_def;
break;
case BLE_GATT_REGISTER_OP_DSC:
memcpy(entry->uuid128, ctxt->dsc.dsc_def->uuid128, 16);
+ entry->handle = ctxt->dsc.handle;
+ entry->svc = ctxt->dsc.svc_def;
+ entry->chr = ctxt->dsc.chr_def;
+ entry->dsc = ctxt->dsc.dsc_def;
+ break;
+
+ default:
+ TEST_ASSERT(0);
+ break;
+ }
+}
+
+static void
+ble_gatts_reg_test_misc_lookup_good(struct ble_gatts_reg_test_entry *entry)
+{
+ uint16_t chr_def_handle;
+ uint16_t chr_val_handle;
+ uint16_t svc_handle;
+ uint16_t dsc_handle;
+ int rc;
+
+ switch (entry->op) {
+ case BLE_GATT_REGISTER_OP_SVC:
+ rc = ble_gatts_find_svc(entry->uuid128, &svc_handle);
+ TEST_ASSERT_FATAL(rc == 0);
+ TEST_ASSERT(svc_handle == entry->handle);
+ break;
+
+ case BLE_GATT_REGISTER_OP_CHR:
+ rc = ble_gatts_find_chr(entry->svc->uuid128, entry->chr->uuid128,
+ &chr_def_handle, &chr_val_handle);
+ TEST_ASSERT_FATAL(rc == 0);
+ TEST_ASSERT(chr_def_handle == entry->handle);
+ TEST_ASSERT(chr_val_handle == entry->val_handle);
+ break;
+
+ case BLE_GATT_REGISTER_OP_DSC:
+ rc = ble_gatts_find_dsc(entry->svc->uuid128, entry->chr->uuid128,
+ entry->dsc->uuid128, &dsc_handle);
+ break;
+
+ default:
+ TEST_ASSERT(0);
+ break;
+ }
+}
+
+static void
+ble_gatts_reg_test_misc_lookup_bad(struct ble_gatts_reg_test_entry *entry)
+{
+ struct ble_gatts_reg_test_entry *cur;
+ uint8_t wrong_uuid[16];
+ int rc;
+ int i;
+
+ switch (entry->op) {
+ case BLE_GATT_REGISTER_OP_SVC:
+ /* Wrong service UUID. */
+ memcpy(wrong_uuid, entry->svc->uuid128, 16);
+ wrong_uuid[15]++;
+ rc = ble_gatts_find_svc(wrong_uuid, NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+ break;
+
+ case BLE_GATT_REGISTER_OP_CHR:
+ /* Correct service UUID, wrong characteristic UUID. */
+ memcpy(wrong_uuid, entry->chr->uuid128, 16);
+ wrong_uuid[15]++;
+ rc = ble_gatts_find_chr(entry->svc->uuid128, wrong_uuid, NULL, NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+
+ /* Incorrect service UUID, correct characteristic UUID. */
+ memcpy(wrong_uuid, entry->svc->uuid128, 16);
+ wrong_uuid[15]++;
+ rc = ble_gatts_find_chr(wrong_uuid, entry->chr->uuid128, NULL, NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+
+ /* Existing (but wrong) service, correct characteristic UUID. */
+ for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
+ cur = ble_gatts_reg_test_entries + i;
+ switch (cur->op) {
+ case BLE_GATT_REGISTER_OP_SVC:
+ if (cur->svc != entry->svc) {
+ rc = ble_gatts_find_chr(cur->svc->uuid128,
+ entry->chr->uuid128,
+ NULL, NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+ }
+ break;
+
+ case BLE_GATT_REGISTER_OP_CHR:
+ /* Characteristic that isn't in this service. */
+ if (cur->svc != entry->svc) {
+ rc = ble_gatts_find_chr(entry->svc->uuid128,
+ cur->chr->uuid128,
+ NULL, NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+ }
+ break;
+
+ case BLE_GATT_REGISTER_OP_DSC:
+ /* Use descriptor UUID instead of characteristic UUID. */
+ rc = ble_gatts_find_chr(entry->svc->uuid128,
+ cur->dsc->uuid128,
+ NULL, NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+ break;
+
+ default:
+ TEST_ASSERT(0);
+ break;
+ }
+ }
+ break;
+
+ case BLE_GATT_REGISTER_OP_DSC:
+ /* Correct svc/chr UUID, wrong dsc UUID. */
+ memcpy(wrong_uuid, entry->dsc->uuid128, 16);
+ wrong_uuid[15]++;
+ rc = ble_gatts_find_dsc(entry->svc->uuid128, entry->chr->uuid128,
+ wrong_uuid, NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+
+ /* Incorrect svc UUID, correct chr/dsc UUID. */
+ memcpy(wrong_uuid, entry->svc->uuid128, 16);
+ wrong_uuid[15]++;
+ rc = ble_gatts_find_dsc(wrong_uuid, entry->chr->uuid128,
+ entry->dsc->uuid128, NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+
+ for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
+ cur = ble_gatts_reg_test_entries + i;
+ switch (cur->op) {
+ case BLE_GATT_REGISTER_OP_SVC:
+ /* Existing (but wrong) svc, correct chr/dsc UUID. */
+ if (cur->svc != entry->svc) {
+ rc = ble_gatts_find_dsc(cur->svc->uuid128,
+ entry->chr->uuid128,
+ entry->dsc->uuid128,
+ NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+ }
+ break;
+
+ case BLE_GATT_REGISTER_OP_CHR:
+ /* Existing (but wrong) svc/chr, correct dsc UUID. */
+ if (cur->chr != entry->chr) {
+ rc = ble_gatts_find_dsc(cur->svc->uuid128,
+ cur->chr->uuid128,
+ entry->dsc->uuid128,
+ NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+ }
+ break;
+
+ case BLE_GATT_REGISTER_OP_DSC:
+ /* Descriptor that isn't in this characteristic. */
+ if (cur->chr != entry->chr) {
+ rc = ble_gatts_find_dsc(cur->svc->uuid128,
+ cur->chr->uuid128,
+ entry->dsc->uuid128,
+ NULL);
+ TEST_ASSERT(rc == BLE_HS_ENOENT);
+ }
+ break;
+
+ default:
+ TEST_ASSERT(0);
+ break;
+ }
+ }
break;
default:
@@ -84,11 +268,25 @@ ble_gatts_reg_test_misc_verify_entry(uint8_t op, const uint8_t *uuid128)
for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
entry = ble_gatts_reg_test_entries + i;
if (entry->op == op && memcmp(entry->uuid128, uuid128, 16) == 0) {
- return;
+ break;
}
}
+ TEST_ASSERT_FATAL(entry != NULL);
- TEST_ASSERT(0);
+ /* Verify that characteristic value handle was properly assigned at
+ * registration.
+ */
+ if (op == BLE_GATT_REGISTER_OP_CHR) {
+ TEST_ASSERT(*entry->chr->val_handle == entry->val_handle);
+ }
+
+ /* Verify that the entry can be looked up. */
+ ble_gatts_reg_test_misc_lookup_good(entry);
+
+ /* Verify that "barely incorrect" UUID information doesn't retrieve any
+ * handles.
+ */
+ ble_gatts_reg_test_misc_lookup_bad(entry);
}
static int
@@ -337,6 +535,8 @@ TEST_CASE(ble_gatts_reg_test_svc_cb)
TEST_CASE(ble_gatts_reg_test_chr_cb)
{
+ uint16_t val_handles[16];
+
/*** 1 characteristic. */
ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
.type = BLE_GATT_SVC_TYPE_PRIMARY,
@@ -345,6 +545,7 @@ TEST_CASE(ble_gatts_reg_test_chr_cb)
.uuid128 = BLE_UUID16(0x1111),
.access_cb = ble_gatts_reg_test_misc_dummy_access,
.flags = BLE_GATT_CHR_F_READ,
+ .val_handle = val_handles + 0,
}, {
0
} },
@@ -360,10 +561,12 @@ TEST_CASE(ble_gatts_reg_test_chr_cb)
.uuid128 = BLE_UUID16(0x1111),
.access_cb = ble_gatts_reg_test_misc_dummy_access,
.flags = BLE_GATT_CHR_F_READ,
+ .val_handle = val_handles + 0,
}, {
.uuid128 = BLE_UUID16(0x2222),
.access_cb = ble_gatts_reg_test_misc_dummy_access,
.flags = BLE_GATT_CHR_F_WRITE,
+ .val_handle = val_handles + 1,
}, {
0
} },
@@ -374,6 +577,7 @@ TEST_CASE(ble_gatts_reg_test_chr_cb)
.uuid128 = BLE_UUID16(0x3333),
.access_cb = ble_gatts_reg_test_misc_dummy_access,
.flags = BLE_GATT_CHR_F_READ,
+ .val_handle = val_handles + 2,
}, {
0
} },
@@ -384,6 +588,8 @@ TEST_CASE(ble_gatts_reg_test_chr_cb)
TEST_CASE(ble_gatts_reg_test_dsc_cb)
{
+ uint16_t val_handles[16];
+
/*** 1 descriptor. */
ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
.type = BLE_GATT_SVC_TYPE_PRIMARY,
@@ -392,8 +598,9 @@ TEST_CASE(ble_gatts_reg_test_dsc_cb)
.uuid128 = BLE_UUID16(0x1111),
.access_cb = ble_gatts_reg_test_misc_dummy_access,
.flags = BLE_GATT_CHR_F_READ,
+ .val_handle = val_handles + 0,
.descriptors = (struct ble_gatt_dsc_def[]) { {
- .uuid128 = BLE_UUID16(0xaaaa),
+ .uuid128 = BLE_UUID16(0x111a),
.att_flags = 5,
.access_cb = ble_gatts_reg_test_misc_dummy_access,
}, {
@@ -406,7 +613,7 @@ TEST_CASE(ble_gatts_reg_test_dsc_cb)
0
} });
- /*** 5 descriptors. */
+ /*** 5+ descriptors. */
ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid128 = BLE_UUID16(0x1234),
@@ -414,8 +621,9 @@ TEST_CASE(ble_gatts_reg_test_dsc_cb)
.uuid128 = BLE_UUID16(0x1111),
.access_cb = ble_gatts_reg_test_misc_dummy_access,
.flags = BLE_GATT_CHR_F_READ,
+ .val_handle = val_handles + 0,
.descriptors = (struct ble_gatt_dsc_def[]) { {
- .uuid128 = BLE_UUID16(0xaaaa),
+ .uuid128 = BLE_UUID16(0x111a),
.att_flags = 5,
.access_cb = ble_gatts_reg_test_misc_dummy_access,
}, {
@@ -425,6 +633,7 @@ TEST_CASE(ble_gatts_reg_test_dsc_cb)
.uuid128 = BLE_UUID16(0x2222),
.access_cb = ble_gatts_reg_test_misc_dummy_access,
.flags = BLE_GATT_CHR_F_WRITE,
+ .val_handle = val_handles + 1,
}, {
0
} },
@@ -435,20 +644,45 @@ TEST_CASE(ble_gatts_reg_test_dsc_cb)
.uuid128 = BLE_UUID16(0x3333),
.access_cb = ble_gatts_reg_test_misc_dummy_access,
.flags = BLE_GATT_CHR_F_READ,
+ .val_handle = val_handles + 2,
+ .descriptors = (struct ble_gatt_dsc_def[]) { {
+ .uuid128 = BLE_UUID16(0x333a),
+ .att_flags = 5,
+ .access_cb = ble_gatts_reg_test_misc_dummy_access,
+ }, {
+ .uuid128 = BLE_UUID16(0x333b),
+ .att_flags = 5,
+ .access_cb = ble_gatts_reg_test_misc_dummy_access,
+ }, {
+ .uuid128 = BLE_UUID16(0x333c),
+ .att_flags = 5,
+ .access_cb = ble_gatts_reg_test_misc_dummy_access,
+ }, {
+ .uuid128 = BLE_UUID16(0x333e),
+ .att_flags = 5,
+ .access_cb = ble_gatts_reg_test_misc_dummy_access,
+ }, {
+ 0
+ } },
+ }, {
+ .uuid128 = BLE_UUID16(0x4444),
+ .access_cb = ble_gatts_reg_test_misc_dummy_access,
+ .flags = BLE_GATT_CHR_F_READ,
+ .val_handle = val_handles + 3,
.descriptors = (struct ble_gatt_dsc_def[]) { {
- .uuid128 = BLE_UUID16(0xaaab),
+ .uuid128 = BLE_UUID16(0x444a),
.att_flags = 5,
.access_cb = ble_gatts_reg_test_misc_dummy_access,
}, {
- .uuid128 = BLE_UUID16(0xaaac),
+ .uuid128 = BLE_UUID16(0x444b),
.att_flags = 5,
.access_cb = ble_gatts_reg_test_misc_dummy_access,
}, {
- .uuid128 = BLE_UUID16(0xaaad),
+ .uuid128 = BLE_UUID16(0x444c),
.att_flags = 5,
.access_cb = ble_gatts_reg_test_misc_dummy_access,
}, {
- .uuid128 = BLE_UUID16(0xaaae),
+ .uuid128 = BLE_UUID16(0x444e),
.att_flags = 5,
.access_cb = ble_gatts_reg_test_misc_dummy_access,
}, {