From 3278f542ebe88b28e8e83e14825dc1deda9e8bfa Mon Sep 17 00:00:00 2001 From: Roger Lendenmann Date: Tue, 12 Apr 2016 21:07:53 +0200 Subject: [PATCH] Bluetooth: gatt: include service api definition proposal * service include macro definition takes reference to first service attribute of the included service Change-Id: Ib2b1defe2c99aea738da791af74a534d56025eae Signed-off-by: Roger Lendenmann --- drivers/bluetooth/nble/gatt.c | 20 ++++++++++++---- include/bluetooth/gatt.h | 8 +++---- net/bluetooth/gatt.c | 39 ++++++++++++++++++++++++------- tests/bluetooth/tester/src/gatt.c | 32 ++----------------------- 4 files changed, 52 insertions(+), 47 deletions(-) diff --git a/drivers/bluetooth/nble/gatt.c b/drivers/bluetooth/nble/gatt.c index 7bed68d38d..1f2ba75e5d 100644 --- a/drivers/bluetooth/nble/gatt.c +++ b/drivers/bluetooth/nble/gatt.c @@ -283,10 +283,19 @@ ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, } ssize_t bt_gatt_attr_read_included(struct bt_conn *conn, - const struct bt_gatt_attr *attr, - void *buf, uint16_t len, uint16_t offset) + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) { - return BT_GATT_ERR(BT_ATT_ERR_NOT_SUPPORTED); + struct bt_gatt_attr *incl = attr->user_data; + + /* nble gatt register case reading user_data. */ + if (!conn) { + return bt_gatt_attr_read(conn, attr, buf, len, offset, incl, + sizeof(incl)); + } + + /* nble handles gattc reads internally */ + return -EINVAL; } struct gatt_chrc { @@ -550,8 +559,9 @@ static uint16_t parse_include(struct bt_conn *conn, const uint8_t *data, break; } - attr = (&(struct bt_gatt_attr) - BT_GATT_INCLUDE_SERVICE(&gatt_include)); + attr = (&(struct bt_gatt_attr) { + .uuid = BT_UUID_GATT_INCLUDE, + .user_data = &gatt_include, }); attr->handle = att->handle; data += sizeof(*att); diff --git a/include/bluetooth/gatt.h b/include/bluetooth/gatt.h index 4a005bf7b8..8879fa1932 100644 --- a/include/bluetooth/gatt.h +++ b/include/bluetooth/gatt.h @@ -450,16 +450,16 @@ ssize_t bt_gatt_attr_read_included(struct bt_conn *conn, /** @def BT_GATT_INCLUDE_SERVICE * @brief Include Service Declaration Macro. * - * Helper macro to declare a include service attribute. + * Helper macro to declare database internal include service attribute. * - * @param _service Service attribute value. + * @param _service_incl, the first service attribute of service to include */ -#define BT_GATT_INCLUDE_SERVICE(_service) \ +#define BT_GATT_INCLUDE_SERVICE(_service_incl) \ { \ .uuid = BT_UUID_GATT_INCLUDE, \ .perm = BT_GATT_PERM_READ, \ .read = bt_gatt_attr_read_included, \ - .user_data = _service, \ + .user_data = _service_incl, \ } /** @brief Read Characteristic Attribute helper. diff --git a/net/bluetooth/gatt.c b/net/bluetooth/gatt.c index c9304e4c20..01a4beccc2 100644 --- a/net/bluetooth/gatt.c +++ b/net/bluetooth/gatt.c @@ -163,28 +163,49 @@ struct gatt_incl { uint16_t uuid16; } __packed; +static uint8_t get_service_handles(const struct bt_gatt_attr *attr, + void *user_data) +{ + struct gatt_incl *include = user_data; + + /* Stop if attribute is a service */ + if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) || + !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) { + return BT_GATT_ITER_STOP; + } + + include->end_handle = attr->handle; + + return BT_GATT_ITER_CONTINUE; +} + ssize_t bt_gatt_attr_read_included(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct bt_gatt_include *incl = attr->user_data; + struct bt_gatt_attr *incl = attr->user_data; + struct bt_uuid *uuid = incl->user_data; struct gatt_incl pdu; uint8_t value_len; - pdu.start_handle = sys_cpu_to_le16(incl->start_handle); - pdu.end_handle = sys_cpu_to_le16(incl->end_handle); + /* first attr points to the start handle */ + pdu.start_handle = sys_cpu_to_le16(incl->handle); value_len = sizeof(pdu.start_handle) + sizeof(pdu.end_handle); /* * Core 4.2, Vol 3, Part G, 3.2, - * The Service UUID shall only be present when the UUID is a 16-bit - * Bluetooth UUID. + * The Service UUID shall only be present when the UUID is a + * 16-bit Bluetooth UUID. */ - if (incl->uuid->type == BT_UUID_TYPE_16) { - pdu.uuid16 = sys_cpu_to_le16(BT_UUID_16(incl->uuid)->val); + if (uuid->type == BT_UUID_TYPE_16) { + pdu.uuid16 = sys_cpu_to_le16(BT_UUID_16(uuid)->val); value_len += sizeof(pdu.uuid16); } + /* Lookup for service end handle */ + bt_gatt_foreach_attr(incl->handle + 1, 0xffff, get_service_handles, + &pdu); + return bt_gatt_attr_read(conn, attr, buf, len, offset, &pdu, value_len); } @@ -911,7 +932,9 @@ static uint16_t parse_include(struct bt_conn *conn, const void *pdu, continue; } - attr = (&(struct bt_gatt_attr)BT_GATT_INCLUDE_SERVICE(&value)); + attr = (&(struct bt_gatt_attr) { + .uuid = BT_UUID_GATT_INCLUDE, + .user_data = &value, }); attr->handle = handle; if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) { diff --git a/tests/bluetooth/tester/src/gatt.c b/tests/bluetooth/tester/src/gatt.c index 72fa6ed624..fdad4dbd83 100644 --- a/tests/bluetooth/tester/src/gatt.c +++ b/tests/bluetooth/tester/src/gatt.c @@ -540,46 +540,18 @@ fail: CONTROLLER_INDEX, BTP_STATUS_FAILED); } -static void get_service_end_handle(const struct bt_gatt_attr *attr, - struct bt_gatt_include *include, - uint16_t svc_start_handle) -{ - /* Skip first attribute found, it is a service declaration. */ - while (++attr < server_db + attr_count) { - /* Stop if attribute is a service */ - if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) || - !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) { - include->end_handle = svc_start_handle; - return; - } - - svc_start_handle++; - } - - /* Last attribute in db */ - include->end_handle = attr_count; -} - static int alloc_included(const struct bt_gatt_attr *attr, uint16_t *included_service_id, uint16_t svc_handle) { struct bt_gatt_attr *attr_incl; - struct bt_gatt_include include; - - include.uuid = attr->user_data; - include.start_handle = svc_handle; - include.end_handle = svc_handle; attr_incl = gatt_db_add(&(struct bt_gatt_attr) - BT_GATT_INCLUDE_SERVICE(&include), - sizeof(include)); + BT_GATT_INCLUDE_SERVICE(&attr), + sizeof(attr)); if (!attr_incl) { return -EINVAL; } - /* Get included end handle */ - get_service_end_handle(attr, attr_incl->user_data, svc_handle); - *included_service_id = attr_incl->handle; return 0; }