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 2015/12/24 01:45:50 UTC
incubator-mynewt-larva git commit: GATT server
Repository: incubator-mynewt-larva
Updated Branches:
refs/heads/master ba4a7ed2b -> cc55da90a
GATT server
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/cc55da90
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/cc55da90
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/cc55da90
Branch: refs/heads/master
Commit: cc55da90aa35933dd456a4f2038fb69e31779fff
Parents: ba4a7ed
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Dec 23 16:45:23 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Dec 23 16:45:23 2015 -0800
----------------------------------------------------------------------
net/nimble/host/include/host/ble_gatt.h | 11 +-
net/nimble/host/src/ble_gatts.c | 190 +++++++++++++++++++++++++--
2 files changed, 185 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cc55da90/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 665b138..fbba391 100644
--- a/net/nimble/host/include/host/ble_gatt.h
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -72,15 +72,18 @@ int ble_gatt_exchange_mtu(uint16_t conn_handle);
int ble_gatt_init(void);
/*** @server. */
-struct ble_gatt_desc_def {
+struct ble_gatt_dsc_def {
uint8_t *uuid128;
+ uint8_t att_flags;
ble_att_svr_access_fn *access_cb;
+ void *arg;
};
-struct ble_gatt_char_def {
- uint8_t properties;
+struct ble_gatt_chr_def {
uint8_t *uuid128;
ble_att_svr_access_fn *access_cb;
+ struct ble_gatt_dsc_def *descriptors;
+ uint8_t properties;
};
#define BLE_GATT_SVC_TYPE_END 0
@@ -91,7 +94,7 @@ struct ble_gatt_svc_def {
uint8_t type;
uint8_t *uuid128;
struct ble_gatt_svc_def **includes; /* Terminated with null. */
- struct ble_gatt_char_def *characteristics;
+ struct ble_gatt_chr_def *characteristics;
};
int ble_gatt_register_services(const struct ble_gatt_svc_def *svcs);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/cc55da90/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 3c71ba1..48e0921 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -16,14 +16,21 @@
#include <stddef.h>
#include <assert.h>
+#include <string.h>
+#include "nimble/ble.h"
+#include "host/ble_hs_uuid.h"
#include "ble_hs_priv.h"
#include "ble_gatt_priv.h"
+#define BLE_GATTS_INCLUDE_SZ 6
+#define BLE_GATTS_CHR_MAX_SZ 19
+
#define BLE_GATTS_MAX_SERVICES 32 /* XXX: Make this configurable. */
struct ble_gatts_svc_entry {
const struct ble_gatt_svc_def *svc;
- uint16_t handle; /* 0 means unregistered. */
+ uint16_t handle; /* 0 means unregistered. */
+ uint16_t end_group_handle;
};
static struct ble_gatts_svc_entry
@@ -46,23 +53,92 @@ ble_gatts_svc_access(uint16_t handle_id, uint8_t *uuid128, uint8_t op,
}
static int
-ble_gatts_service_includes_satisfied(const struct ble_gatt_svc_def *svc)
+ble_gatts_inc_access(uint16_t handle_id, uint8_t *uuid128, uint8_t op,
+ union 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;
+
+ assert(op == BLE_ATT_ACCESS_OP_READ);
+
+ entry = arg;
+
+ htole16(buf + 0, entry->handle);
+ htole16(buf + 2, entry->end_group_handle);
+
+ /* Only include the service UUID if it has a 16-bit representation. */
+ uuid16 = ble_hs_uuid_16bit(entry->svc->uuid128);
+ if (uuid16 != 0) {
+ htole16(buf + 4, uuid16);
+ ctxt->ahc_read.attr_len = 6;
+ } else {
+ ctxt->ahc_read.attr_len = 4;
+ }
+ ctxt->ahc_read.attr_data = buf;
+
+ return 0;
+}
+
+static int
+ble_gatts_chr_access(uint16_t handle_id, uint8_t *uuid128, uint8_t op,
+ union ble_att_svr_access_ctxt *ctxt, void *arg)
+{
+ static uint8_t buf[BLE_GATTS_CHR_MAX_SZ];
+ const struct ble_gatt_chr_def *chr;
+ uint16_t uuid16;
+
+ assert(op == BLE_ATT_ACCESS_OP_READ);
+
+ chr = arg;
+
+ buf[0] = chr->properties;
+
+ /* The value attribute is always immediately after the declaration. */
+ htole16(buf + 1, handle_id + 1);
+
+ uuid16 = ble_hs_uuid_16bit(chr->uuid128);
+ if (uuid16 != 0) {
+ htole16(buf + 3, uuid16);
+ ctxt->ahc_read.attr_len = 5;
+ } else {
+ memcpy(buf + 3, chr->uuid128, 16);
+ ctxt->ahc_read.attr_len = 19;
+ }
+
+ return 0;
+}
+
+static int
+ble_gatts_find_svc(const struct ble_gatt_svc_def *svc)
{
- const struct ble_gatt_svc_def *incl;
int i;
+ for (i = 0; i < ble_gatts_num_svc_entries; i++) {
+ if (ble_gatts_svc_entries[i].svc == svc) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int
+ble_gatts_svc_incs_satisfied(const struct ble_gatt_svc_def *svc)
+{
+ const struct ble_gatt_svc_def *incl;
+ int idx;
+
if (svc->includes == NULL) {
/* No included services. */
return 1;
}
for (incl = *svc->includes; incl != NULL; incl++) {
- for (i = 0; i < ble_gatts_num_svc_entries; i++) {
- if (ble_gatts_svc_entries[i].handle == 0) {
- return 0;
- } else {
- break;
- }
+ idx = ble_gatts_find_svc(incl);
+ if (idx == -1) {
+ return 0;
}
}
@@ -70,12 +146,78 @@ ble_gatts_service_includes_satisfied(const struct ble_gatt_svc_def *svc)
}
static int
-ble_gatts_register_service(const struct ble_gatt_svc_def *svc,
+ble_gatts_register_inc(struct ble_gatts_svc_entry *entry)
+{
+ uint16_t handle;
+ int rc;
+
+ assert(entry->handle != 0);
+ assert(entry->end_group_handle != 0);
+
+ rc = ble_att_svr_register(entry->svc->uuid128, HA_FLAG_PERM_READ,
+ &handle, ble_gatts_inc_access, entry);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+}
+
+static int
+ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc)
+{
+ uint16_t handle;
+ int rc;
+
+ rc = ble_att_svr_register(dsc->uuid128, dsc->att_flags, &handle,
+ dsc->access_cb, (void *)dsc->arg);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+
+}
+
+static int
+ble_gatts_register_characteristic(const struct ble_gatt_chr_def *chr)
+{
+ struct ble_gatt_dsc_def *dsc;
+ uint16_t handle;
+ int rc;
+
+ /* Register characteristic declaration attribute (cast away const on
+ * callback arg).
+ */
+ rc = ble_att_svr_register(chr->uuid128, HA_FLAG_PERM_READ, &handle,
+ ble_gatts_chr_access, (void *)chr);
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* Register each descriptor. */
+ if (chr->descriptors != NULL) {
+ for (dsc = chr->descriptors; dsc->uuid128 != NULL; dsc++) {
+ rc = ble_gatts_register_dsc(dsc);
+ if (rc != 0) {
+ return rc;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+ble_gatts_register_svc(const struct ble_gatt_svc_def *svc,
uint16_t *out_handle)
{
+ const struct ble_gatt_svc_def *incl;
+ const struct ble_gatt_chr_def *chr;
+ int idx;
int rc;
- if (!ble_gatts_service_includes_satisfied(svc)) {
+ if (!ble_gatts_svc_incs_satisfied(svc)) {
return BLE_HS_EAGAIN;
}
@@ -88,6 +230,30 @@ ble_gatts_register_service(const struct ble_gatt_svc_def *svc,
return rc;
}
+ /* Register each include. */
+ if (svc->includes != NULL) {
+ for (incl = *svc->includes; incl != NULL; incl++) {
+ idx = ble_gatts_find_svc(incl);
+ assert(idx != -1);
+
+ rc = ble_gatts_register_inc(ble_gatts_svc_entries + idx);
+ if (rc != 0) {
+ return rc;
+ }
+ }
+ }
+
+ /* Register each characteristic. */
+ if (svc->characteristics != NULL) {
+ for (chr = svc->characteristics; chr->uuid128 != NULL; chr++) {
+ rc = ble_gatts_register_characteristic(chr);
+ if (rc != 0) {
+ return rc;
+ }
+ }
+
+ }
+
return 0;
}
@@ -104,7 +270,7 @@ ble_gatts_register_round(int *out_num_registered)
entry = ble_gatts_svc_entries + i;
if (entry->handle == 0) {
- rc = ble_gatts_register_service(entry->svc, &handle);
+ rc = ble_gatts_register_svc(entry->svc, &handle);
switch (rc) {
case 0:
/* Service successfully registered. */