mesh: Fix clearing model subscription list
The code was storing a "cleared" entry in storage for every model,
regardless of them having any subscriptions or not. Update hte
mod_sub_list_clear() function to return a "cleared entries" count so
that the calling code can decide whether any action is needed or not.
@@ -1243,28 +1243,36 @@ static u8_t va_del(u8_t *label_uuid, u16_t *addr)
return STATUS_CANNOT_REMOVE;
}
-static void mod_sub_list_clear(struct bt_mesh_model *mod)
+static size_t mod_sub_list_clear(struct bt_mesh_model *mod)
{
u8_t *label_uuid;
+ size_t clear_count;
int i;
/* Unref stored labels related to this model */
- for (i = 0; i < ARRAY_SIZE(mod->groups); i++) {
+ for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) {
if (!BT_MESH_ADDR_IS_VIRTUAL(mod->groups[i])) {
- continue;
+ if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
+ mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
+ clear_count++;
}
- label_uuid = bt_mesh_label_uuid_get(mod->groups[i]);
- if (!label_uuid) {
- BT_ERR("Label UUID not found");
continue;
}
+ label_uuid = bt_mesh_label_uuid_get(mod->groups[i]);
+
+ mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
+ clear_count++;
+
+ if (label_uuid) {
va_del(label_uuid, NULL);
+ } else {
+ BT_ERR("Label UUID not found");
+ }
}
- /* Clear all subscriptions (0x0000 is the unassigned address) */
- memset(mod->groups, 0, sizeof(mod->groups));
+ return clear_count;
}
static void mod_pub_va_set(struct bt_mesh_model *model,
@@ -1333,10 +1341,20 @@ send_status:
status, mod_id);
}
#else
-static void mod_sub_list_clear(struct bt_mesh_model *mod)
+static size_t mod_sub_list_clear(struct bt_mesh_model *mod)
{
- /* Clear all subscriptions (0x0000 is the unassigned address) */
- memset(mod->groups, 0, sizeof(mod->groups));
+ size_t clear_count;
+ int i;
+
+ /* Unref stored labels related to this model */
+ for (i = 0, clear_count = 0; i < ARRAY_SIZE(mod->groups); i++) {
+ if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) {
+ mod->groups[i] = BT_MESH_ADDR_UNASSIGNED;
+ clear_count++;
+ }
+ }
+
+ return clear_count;
}
static void mod_pub_va_set(struct bt_mesh_model *model,
@@ -3396,15 +3414,17 @@ int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary)
static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
bool vnd, bool primary, void *user_data)
{
+ size_t clear_count;
+
/* Clear model state that isn't otherwise cleared. E.g. AppKey
* binding and model publication is cleared as a consequence
* of removing all app keys, however model subscription clearing
* must be taken care of here.
*/
- mod_sub_list_clear(mod);
+ clear_count = mod_sub_list_clear(mod);
- if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
+ if (IS_ENABLED(CONFIG_BT_SETTINGS) && clear_count) {
bt_mesh_store_mod_sub(mod);
}
}
