Bluetooth: Disable GATT notifications while disconnected
Once disconnected disable CCC configuration and enabling it back once reconnected: bt: bt_gatt_disconnected (0x0010c610): conn 0x0010a1f4 bt: disconnected_cb (0x0010c610): ccc 0x00108e44 reseted Disconnected Connected bt: bt_gatt_connected (0x0010c610): conn 0x0010a1f4 bt: gatt_ccc_changed (0x0010c610): ccc 0x00108e44 value 0x0001 Change-Id: Ia4ac6793176f80ea9c6f255a4d151f9080660b0d Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
ea15db12ba
commit
168446d058
3 changed files with 100 additions and 0 deletions
|
@ -608,4 +608,10 @@ int bt_gatt_attr_read_cep(const bt_addr_le_t *peer,
|
|||
*/
|
||||
void bt_gatt_notify(uint16_t handle, const void *data, size_t len);
|
||||
|
||||
/*! @brief connected callback */
|
||||
void bt_gatt_connected(struct bt_conn *conn);
|
||||
|
||||
/*! @brief disconnected callback */
|
||||
void bt_gatt_disconnected(struct bt_conn *conn);
|
||||
|
||||
#endif /* __BT_GATT_H */
|
||||
|
|
|
@ -1212,6 +1212,7 @@ static void bt_att_connected(struct bt_conn *conn)
|
|||
att->conn = conn;
|
||||
conn->att = att;
|
||||
att->mtu = BT_ATT_DEFAULT_LE_MTU;
|
||||
bt_gatt_connected(conn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1231,6 +1232,7 @@ static void bt_att_disconnected(struct bt_conn *conn)
|
|||
|
||||
conn->att = NULL;
|
||||
memset(att, 0, sizeof(*att));
|
||||
bt_gatt_disconnected(conn);
|
||||
}
|
||||
|
||||
void bt_att_init(void)
|
||||
|
|
|
@ -219,6 +219,8 @@ static void gatt_ccc_changed(struct _bt_gatt_ccc *ccc)
|
|||
}
|
||||
}
|
||||
|
||||
BT_DBG("ccc %p value 0x%04x\n", ccc, value);
|
||||
|
||||
if (value != ccc->value) {
|
||||
ccc->value = value;
|
||||
ccc->cfg_changed(value);
|
||||
|
@ -368,3 +370,93 @@ void bt_gatt_notify(uint16_t handle, const void *data, size_t len)
|
|||
|
||||
bt_gatt_foreach_attr(handle, 0xffff, notify_cb, &nfy);
|
||||
}
|
||||
|
||||
static uint8_t connected_cb(const struct bt_gatt_attr *attr, void *user_data)
|
||||
{
|
||||
struct bt_conn *conn = user_data;
|
||||
struct _bt_gatt_ccc *ccc;
|
||||
size_t i;
|
||||
|
||||
/* Check attribute user_data must be of type struct _bt_gatt_ccc */
|
||||
if (attr->write != bt_gatt_attr_write_ccc) {
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
ccc = attr->user_data;
|
||||
|
||||
/* If already enabled skip */
|
||||
if (ccc->value) {
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ccc->cfg_len; i++) {
|
||||
/* Ignore configuration for different peer */
|
||||
if (bt_addr_le_cmp(&conn->dst, &ccc->cfg[i].peer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ccc->cfg[i].value) {
|
||||
gatt_ccc_changed(ccc);
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
void bt_gatt_connected(struct bt_conn *conn)
|
||||
{
|
||||
BT_DBG("conn %p\n", conn);
|
||||
bt_gatt_foreach_attr(0x0001, 0xffff, connected_cb, conn);
|
||||
}
|
||||
|
||||
static uint8_t disconnected_cb(const struct bt_gatt_attr *attr, void *user_data)
|
||||
{
|
||||
struct bt_conn *conn = user_data;
|
||||
struct _bt_gatt_ccc *ccc;
|
||||
size_t i;
|
||||
|
||||
/* Check attribute user_data must be of type struct _bt_gatt_ccc */
|
||||
if (attr->write != bt_gatt_attr_write_ccc) {
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
ccc = attr->user_data;
|
||||
|
||||
/* If already disabled skip */
|
||||
if (!ccc->value) {
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ccc->cfg_len; i++) {
|
||||
/* Ignore configurations with disabled value */
|
||||
if (!ccc->cfg[i].value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bt_addr_le_cmp(&conn->dst, &ccc->cfg[i].peer)) {
|
||||
struct bt_conn *tmp;
|
||||
|
||||
/* Skip if there is another peer connected */
|
||||
tmp = bt_conn_lookup_addr_le(&ccc->cfg[i].peer);
|
||||
if (tmp) {
|
||||
bt_conn_put(tmp);
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset value while disconnected */
|
||||
memset(&ccc->value, 0, sizeof(ccc->value));
|
||||
ccc->cfg_changed(ccc->value);
|
||||
|
||||
BT_DBG("ccc %p reseted\n", ccc);
|
||||
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
void bt_gatt_disconnected(struct bt_conn *conn)
|
||||
{
|
||||
BT_DBG("conn %p\n", conn);
|
||||
bt_gatt_foreach_attr(0x0001, 0xffff, disconnected_cb, conn);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue