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 <roger.lendenmann@intel.com>
This commit is contained in:
Roger Lendenmann 2016-04-12 21:07:53 +02:00 committed by Johan Hedberg
parent ee795d87ff
commit 3278f542eb
4 changed files with 52 additions and 47 deletions

View file

@ -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);

View file

@ -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.

View file

@ -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) {

View file

@ -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;
}