Bluetooth: GATT: Add BT_GATT_CCC_MANAGED

This adds another helper macro called BT_GATT_CCC_MANAGED which can be
used to set 2 new callbacks:

 - cfg_write: Which application can set if it wants to manage writes to
 CCC configuration.
 - cfg_match: Which application can set if it wants to manage matching
 CCC configuration when notifying/indicating.

BT_GATT_CCC_MANAGED retains the ability of saving peer configuration
on storage making it useful for clients which are only interrested in
managing the CCC configuration but not the storage itself.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2019-02-18 16:26:13 +02:00 committed by Anas Nashif
commit da163794d0
2 changed files with 36 additions and 6 deletions

View file

@ -511,6 +511,11 @@ struct _bt_gatt_ccc {
u16_t value; u16_t value;
void (*cfg_changed)(const struct bt_gatt_attr *attr, void (*cfg_changed)(const struct bt_gatt_attr *attr,
u16_t value); u16_t value);
bool (*cfg_write)(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
u16_t value);
bool (*cfg_match)(struct bt_conn *conn,
const struct bt_gatt_attr *attr);
}; };
/** @brief Read Client Characteristic Configuration Attribute helper. /** @brief Read Client Characteristic Configuration Attribute helper.
@ -551,6 +556,26 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const void *buf, const struct bt_gatt_attr *attr, const void *buf,
u16_t len, u16_t offset, u8_t flags); u16_t len, u16_t offset, u8_t flags);
/** @def BT_GATT_CCC_MANAGED
* @brief Managed Client Characteristic Configuration Declaration Macro.
*
* Helper macro to declare a Managed CCC attribute.
*
* @param _cfg Initial configuration.
* @param _changed Configuration changed callback.
* @param _write Configuration write callback.
* @param _match Configuration match callback.
*/
#define BT_GATT_CCC_MANAGED(_cfg, _changed, _write, _match) \
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CCC, \
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, \
bt_gatt_attr_read_ccc, bt_gatt_attr_write_ccc, \
(&(struct _bt_gatt_ccc) { .cfg = _cfg, \
.cfg_len = ARRAY_SIZE(_cfg), \
.cfg_changed = _changed, \
.cfg_write = _write, \
.cfg_match = _match }))
/** @def BT_GATT_CCC /** @def BT_GATT_CCC
* @brief Client Characteristic Configuration Declaration Macro. * @brief Client Characteristic Configuration Declaration Macro.
* *
@ -560,12 +585,7 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
* @param _cfg_changed Configuration changed callback. * @param _cfg_changed Configuration changed callback.
*/ */
#define BT_GATT_CCC(_cfg, _cfg_changed) \ #define BT_GATT_CCC(_cfg, _cfg_changed) \
BT_GATT_ATTRIBUTE(BT_UUID_GATT_CCC, \ BT_GATT_CCC_MANAGED(_cfg, _cfg_changed, NULL, NULL)
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, \
bt_gatt_attr_read_ccc, bt_gatt_attr_write_ccc, \
(&(struct _bt_gatt_ccc) { .cfg = _cfg, \
.cfg_len = ARRAY_SIZE(_cfg), \
.cfg_changed = _cfg_changed, }))
/** @brief Read Characteristic Extended Properties Attribute helper /** @brief Read Characteristic Extended Properties Attribute helper
* *

View file

@ -1056,6 +1056,11 @@ ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
} }
} }
/* Confirm write if cfg is managed by application */
if (ccc->cfg_write && !ccc->cfg_write(conn, attr, value)) {
return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
}
ccc->cfg[i].value = value; ccc->cfg[i].value = value;
BT_DBG("handle 0x%04x value %u", attr->handle, ccc->cfg[i].value); BT_DBG("handle 0x%04x value %u", attr->handle, ccc->cfg[i].value);
@ -1325,6 +1330,11 @@ static u8_t notify_cb(const struct bt_gatt_attr *attr, void *user_data)
continue; continue;
} }
/* Confirm match if cfg is managed by application */
if (ccc->cfg_match && !ccc->cfg_match(conn, attr)) {
continue;
}
if (data->type == BT_GATT_CCC_INDICATE) { if (data->type == BT_GATT_CCC_INDICATE) {
err = gatt_indicate(conn, data->params); err = gatt_indicate(conn, data->params);
} else { } else {