diff --git a/include/bluetooth/gatt.h b/include/bluetooth/gatt.h index 13cf4baa610bb3..357ef19c71581c 100644 --- a/include/bluetooth/gatt.h +++ b/include/bluetooth/gatt.h @@ -1256,7 +1256,8 @@ struct bt_gatt_subscribe_params; /** @typedef bt_gatt_notify_func_t * @brief Notification callback function * - * @param conn Connection object. + * @param conn Connection object. May be NULL, indicating that the peer is + * being unpaired * @param params Subscription parameters. * @param data Attribute value data. If NULL then subscription was removed. * @param length Attribute value length. diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 3f4959c0e15dd5..04881c5a9e8983 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -4152,6 +4152,23 @@ static int sc_clear_by_addr(u8_t id, const bt_addr_le_t *addr) return 0; } +static void bt_gatt_clear_subscriptions(const bt_addr_le_t *addr) +{ +#if defined(CONFIG_BT_GATT_CLIENT) + struct bt_gatt_subscribe_params *params, *tmp; + sys_snode_t *prev = NULL; + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&subscriptions, params, tmp, node) { + if (bt_addr_le_cmp(addr, ¶ms->_peer)) { + prev = ¶ms->node; + continue; + } + params->value = 0U; + gatt_subscription_remove(NULL, prev, params); + } +#endif /* CONFIG_BT_GATT_CLIENT */ +} + int bt_gatt_clear(u8_t id, const bt_addr_le_t *addr) { int err; @@ -4171,6 +4188,8 @@ int bt_gatt_clear(u8_t id, const bt_addr_le_t *addr) return err; } + bt_gatt_clear_subscriptions(addr); + return 0; } diff --git a/tests/bluetooth/tester/src/gatt.c b/tests/bluetooth/tester/src/gatt.c index af215106eb7bfa..b1f559bf0db37b 100644 --- a/tests/bluetooth/tester/src/gatt.c +++ b/tests/bluetooth/tester/src/gatt.c @@ -1650,14 +1650,14 @@ static u8_t notify_func(struct bt_conn *conn, const void *data, u16_t length) { struct gatt_notification_ev *ev = (void *) ev_buf; - const bt_addr_le_t *addr = bt_conn_get_dst(conn); + const bt_addr_le_t *addr; - if (!data) { + if (!conn || !data) { LOG_DBG("Unsubscribed"); (void)memset(params, 0, sizeof(*params)); return BT_GATT_ITER_STOP; } - + addr = bt_conn_get_dst(conn); ev->type = (u8_t) subscribe_params.value; ev->handle = sys_cpu_to_le16(subscribe_params.value_handle); ev->data_length = sys_cpu_to_le16(length);