From cee271968e9c1598a2ee032e1982820b18143e3a Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 13 Aug 2019 14:52:52 +0300 Subject: [PATCH] Bluetooth: GATT: Add support for indicating by UUID This adds support to provide an UUID to bt_gatt_indicate so API user don't need to hardcode the attribute offset by hand. Fixes #18572 Signed-off-by: Luiz Augusto von Dentz --- include/bluetooth/gatt.h | 20 +++++++++++++++++--- subsys/bluetooth/host/gatt.c | 27 +++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/include/bluetooth/gatt.h b/include/bluetooth/gatt.h index 801a8647687..4c85e4ebf6f 100644 --- a/include/bluetooth/gatt.h +++ b/include/bluetooth/gatt.h @@ -866,6 +866,8 @@ typedef void (*bt_gatt_indicate_func_t)(struct bt_conn *conn, /** @brief GATT Indicate Value parameters */ struct bt_gatt_indicate_params { struct bt_att_req _req; + /** Notification Attribute UUID type */ + const struct bt_uuid *uuid; /** Indicate Attribute object*/ const struct bt_gatt_attr *attr; /** Indicate Value callback */ @@ -878,9 +880,21 @@ struct bt_gatt_indicate_params { /** @brief Indicate attribute value change. * - * Send an indication of attribute value change. - * Note: This function should only be called if CCC is declared with - * BT_GATT_CCC otherwise it cannot find a valid peer configuration. + * Send an indication of attribute value change. if connection is NULL + * indicate all peer that have notification enabled via CCC otherwise do a + * direct indication only the given connection. + * + * The attribute object on the parameters can be the so called Characteristic + * Declaration, which is usually declared with BT_GATT_CHARACTERISTIC followed + * by BT_GATT_CCC, or the Characteristic Value Declaration which is + * automatically created after the Characteristic Declaration when using + * BT_GATT_CHARACTERISTIC. + * + * The callback is run from System Workqueue context. + * + * Alternatively it is possible to indicate by UUID by setting it on the + * parameters, when using this method the attribute given is used as the + * start range when looking up for possible matches. * * Note: This procedure is asynchronous therefore the parameters need to * remains valid while it is active. diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index f8f77e2b6eb..1c34cac8229 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -1459,6 +1459,10 @@ static int gatt_indicate(struct bt_conn *conn, u16_t handle, net_buf_add(buf, params->len); memcpy(ind->value, params->data, params->len); + if (!params->func) { + return gatt_send(conn, buf, NULL, NULL, NULL); + } + return gatt_send(conn, buf, gatt_indicate_rsp, params, NULL); } @@ -1634,18 +1638,37 @@ int bt_gatt_indicate(struct bt_conn *conn, struct bt_gatt_indicate_params *params) { struct notify_data data; + const struct bt_gatt_attr *attr; u16_t handle; __ASSERT(params, "invalid parameters\n"); __ASSERT(params->attr, "invalid parameters\n"); - handle = params->attr->handle ? : find_static_attr(params->attr); + attr = params->attr; + + handle = attr->handle ? : find_static_attr(attr); if (!handle) { return -ENOENT; } + /* Lookup UUID if it was given */ + if (params->uuid) { + attr = NULL; + + bt_gatt_foreach_attr_type(handle, 0xffff, params->uuid, + NULL, 1, match_uuid, &attr); + if (!attr) { + return -ENOENT; + } + + handle = attr->handle ? : find_static_attr(attr); + if (!handle) { + return -ENOENT; + } + } + /* Check if attribute is a characteristic then adjust the handle */ - if (!bt_uuid_cmp(params->attr->uuid, BT_UUID_GATT_CHRC)) { + if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC)) { struct bt_gatt_chrc *chrc = params->attr->user_data; if (!(chrc->properties & BT_GATT_CHRC_INDICATE)) {