Bluetooth: GATT: Add option to enforce client change-unware state

This adds BT_GATT_ENFORCE_CHANGE_UNAWARE option which when enable
returns -EAGAIN when notifying or indicating if the client is
change-unware to conform with following statement on the spec:

  'BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2350:
   Except for the Handle Value indication, the  server shall not send
   notifications and indications to such a client until it becomes
   change-aware.'

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2019-02-08 14:10:50 +02:00 committed by Johan Hedberg
commit e919054155
2 changed files with 37 additions and 0 deletions

View file

@ -369,6 +369,19 @@ config BT_GATT_CACHING
characteristics which can be used by clients to detect if anything has characteristics which can be used by clients to detect if anything has
changed on the GATT database. changed on the GATT database.
config BT_GATT_ENFORCE_CHANGE_UNAWARE
bool "GATT Enforce change-unaware state"
default n
depends on BT_GATT_CACHING
help
When enable this option blocks notification and indications to client
to conform to the following statement from the Bluetooth 5.1
specification:
'...the server shall not send notifications and indications to such
a client until it becomes change-aware."
In case the service cannot deal with sudden errors (-EAGAIN) then it
shall not use this option.
config BT_GATT_CLIENT config BT_GATT_CLIENT
bool "GATT client support" bool "GATT client support"
help help

View file

@ -1134,6 +1134,17 @@ static int gatt_notify(struct bt_conn *conn, u16_t handle, const void *data,
struct net_buf *buf; struct net_buf *buf;
struct bt_att_notify *nfy; struct bt_att_notify *nfy;
#if defined(CONFIG_BT_GATT_ENFORCE_CHANGE_UNAWARE)
/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2350:
* Except for the Handle Value indication, the server shall not send
* notifications and indications to such a client until it becomes
* change-aware.
*/
if (!bt_gatt_change_aware(conn, false)) {
return -EAGAIN;
}
#endif
buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY, sizeof(*nfy) + len); buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY, sizeof(*nfy) + len);
if (!buf) { if (!buf) {
BT_WARN("No buffer available to send notification"); BT_WARN("No buffer available to send notification");
@ -1192,6 +1203,19 @@ static int gatt_indicate(struct bt_conn *conn,
struct bt_att_indicate *ind; struct bt_att_indicate *ind;
u16_t value_handle = params->attr->handle; u16_t value_handle = params->attr->handle;
#if defined(CONFIG_BT_GATT_ENFORCE_CHANGE_UNAWARE)
/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2350:
* Except for the Handle Value indication, the server shall not send
* notifications and indications to such a client until it becomes
* change-aware.
*/
if (!(params->func && params->func == sc_indicate_rsp) &&
!bt_gatt_change_aware(conn, false)) {
return -EAGAIN;
}
#endif
/* Check if attribute is a characteristic then adjust the handle */ /* 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(params->attr->uuid, BT_UUID_GATT_CHRC)) {
struct bt_gatt_chrc *chrc = params->attr->user_data; struct bt_gatt_chrc *chrc = params->attr->user_data;