Bluetooth: GATT: Fix not clearing Client Features

When a device is considered unpaired any configuration set in Client
Features shall also be removed.

Fixes #15329

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2019-04-10 13:50:36 +03:00 committed by Johan Hedberg
commit f2a34a6106
4 changed files with 59 additions and 17 deletions

View file

@ -3103,7 +3103,7 @@ static u8_t remove_peer_from_attr(const struct bt_gatt_attr *attr,
return BT_GATT_ITER_CONTINUE;
}
int bt_gatt_clear_ccc(u8_t id, const bt_addr_le_t *addr)
static int bt_gatt_clear_ccc(u8_t id, const bt_addr_le_t *addr)
{
char key[BT_SETTINGS_KEY_MAX];
@ -3124,6 +3124,60 @@ int bt_gatt_clear_ccc(u8_t id, const bt_addr_le_t *addr)
return settings_delete(key);
}
#if defined(CONFIG_BT_GATT_CACHING)
static struct gatt_cf_cfg *find_cf_cfg_by_addr(const bt_addr_le_t *addr)
{
int i;
for (i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
if (!bt_addr_le_cmp(addr, &cf_cfg[i].peer)) {
return &cf_cfg[i];
}
}
return NULL;
}
#endif /* CONFIG_BT_GATT_CACHING */
static int bt_gatt_clear_cf(u8_t id, const bt_addr_le_t *addr)
{
#if defined(CONFIG_BT_GATT_CACHING)
char key[BT_SETTINGS_KEY_MAX];
struct gatt_cf_cfg *cfg;
if (id) {
char id_str[4];
snprintk(id_str, sizeof(id_str), "%u", id);
bt_settings_encode_key(key, sizeof(key), "cf",
(bt_addr_le_t *)addr, id_str);
} else {
bt_settings_encode_key(key, sizeof(key), "cf",
(bt_addr_le_t *)addr, NULL);
}
cfg = find_cf_cfg_by_addr(addr);
if (cfg) {
clear_cf_cfg(cfg);
}
return settings_delete(key);
#endif /* CONFIG_BT_GATT_CACHING */
return 0;
}
int bt_gatt_clear(u8_t id, const bt_addr_le_t *addr)
{
int err;
err = bt_gatt_clear_ccc(id, addr);
if (err < 0) {
return err;
}
return bt_gatt_clear_cf(id, addr);
}
static void ccc_clear(struct _bt_gatt_ccc *ccc, bt_addr_le_t *addr)
{
struct bt_gatt_ccc_cfg *cfg;
@ -3254,19 +3308,6 @@ static int ccc_set(int argc, char **argv, void *val_ctx)
BT_SETTINGS_DEFINE(ccc, ccc_set, NULL, NULL);
#if defined(CONFIG_BT_GATT_CACHING)
static struct gatt_cf_cfg *find_cf_cfg_by_addr(const bt_addr_le_t *addr)
{
int i;
for (i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
if (!bt_addr_le_cmp(addr, &cf_cfg[i].peer)) {
return &cf_cfg[i];
}
}
return NULL;
}
static int cf_set(int argc, char **argv, void *val_ctx)
{
struct gatt_cf_cfg *cfg;

View file

@ -18,7 +18,8 @@ void bt_gatt_disconnected(struct bt_conn *conn);
bool bt_gatt_change_aware(struct bt_conn *conn, bool req);
int bt_gatt_store_ccc(u8_t id, const bt_addr_le_t *addr);
int bt_gatt_clear_ccc(u8_t id, const bt_addr_le_t *addr);
int bt_gatt_clear(u8_t id, const bt_addr_le_t *addr);
#if defined(CONFIG_BT_GATT_CLIENT)
void bt_gatt_notification(struct bt_conn *conn, u16_t handle,

View file

@ -1492,7 +1492,7 @@ int bt_unpair(u8_t id, const bt_addr_le_t *addr)
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_gatt_clear_ccc(id, addr);
bt_gatt_clear(id, addr);
}
return 0;

View file

@ -231,7 +231,7 @@ static void keys_clear_id(struct bt_keys *keys, void *data)
if (*id == keys->id) {
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_gatt_clear_ccc(*id, &keys->addr);
bt_gatt_clear(*id, &keys->addr);
}
bt_keys_clear(keys);