Преглед изворни кода

Merge branch 'bugfix/ble_mesh_node_deinit_v4.2' into 'release/v4.2'

ble_mesh: stack: Persistent storage misc fixes (v4.2)

See merge request espressif/esp-idf!11503
Island пре 5 година
родитељ
комит
c2f08b3e35

+ 2 - 2
components/bt/esp_ble_mesh/Kconfig.in

@@ -327,7 +327,7 @@ if BLE_MESH
         config BLE_MESH_SEQ_STORE_RATE
             int "How often the sequence number gets updated in storage"
             range 0 1000000
-            default 6
+            default 0
             help
                 This value defines how often the local sequence number gets updated in
                 persistent storage (i.e. flash). e.g. a value of 100 means that the
@@ -342,7 +342,7 @@ if BLE_MESH
         config BLE_MESH_RPL_STORE_TIMEOUT
             int "Minimum frequency that the RPL gets updated in storage"
             range 0 1000000
-            default 5
+            default 0
             help
                 This value defines in seconds how soon the RPL (Replay Protection List)
                 gets written to persistent storage after a change occurs. If the node

+ 14 - 5
components/bt/esp_ble_mesh/mesh_core/cfg_srv.c

@@ -3403,7 +3403,10 @@ static int cfg_srv_deinit(struct bt_mesh_model *model)
         return -EINVAL;
     }
 
-    bt_mesh_cfg_reset();
+    /* Use "false" here because if cfg needs to be erased,
+     * it will already be erased in the ble_mesh_deinit().
+     */
+    bt_mesh_cfg_reset(false);
 
     k_delayed_work_free(&cfg->hb_pub.timer);
     cfg->hb_pub.dst = BLE_MESH_ADDR_UNASSIGNED;
@@ -3421,6 +3424,7 @@ const struct bt_mesh_model_cb bt_mesh_cfg_srv_cb = {
 static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
                       bool vnd, bool primary, void *user_data)
 {
+    bool store = *(bool *)user_data;
     size_t clear_count = 0U;
 
     /* Clear model state that isn't otherwise cleared. E.g. AppKey
@@ -3431,12 +3435,17 @@ static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
 
     clear_count = mod_sub_list_clear(mod);
 
-    if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && clear_count) {
+    if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && clear_count && store) {
         bt_mesh_store_mod_sub(mod);
     }
 }
 
-void bt_mesh_cfg_reset(void)
+void bt_mesh_mod_sub_reset(bool store)
+{
+    bt_mesh_model_foreach(mod_reset, &store);
+}
+
+void bt_mesh_cfg_reset(bool store)
 {
     struct bt_mesh_cfg_srv *cfg = conf;
     int i;
@@ -3460,11 +3469,11 @@ void bt_mesh_cfg_reset(void)
         struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
 
         if (sub->net_idx != BLE_MESH_KEY_UNUSED) {
-            bt_mesh_subnet_del(sub, true);
+            bt_mesh_subnet_del(sub, store);
         }
     }
 
-    bt_mesh_model_foreach(mod_reset, NULL);
+    bt_mesh_mod_sub_reset(store);
 
     (void)memset(labels, 0, sizeof(labels));
 }

+ 3 - 1
components/bt/esp_ble_mesh/mesh_core/foundation.h

@@ -132,7 +132,9 @@ struct label {
     bt_mesh_atomic_t flags[1];
 };
 
-void bt_mesh_cfg_reset(void);
+void bt_mesh_mod_sub_reset(bool store);
+
+void bt_mesh_cfg_reset(bool store);
 
 void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat);
 

+ 37 - 25
components/bt/esp_ble_mesh/mesh_core/main.c

@@ -105,7 +105,7 @@ void bt_mesh_node_reset(void)
 
     k_delayed_work_cancel(&bt_mesh.ivu_timer);
 
-    bt_mesh_cfg_reset();
+    bt_mesh_cfg_reset(true);
 
     bt_mesh_rx_reset(true);
     bt_mesh_tx_reset();
@@ -122,10 +122,6 @@ void bt_mesh_node_reset(void)
         bt_mesh_proxy_server_gatt_disable();
     }
 
-    if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
-        bt_mesh_clear_net();
-    }
-
     (void)memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
 
     bt_mesh_scan_disable();
@@ -134,6 +130,7 @@ void bt_mesh_node_reset(void)
     bt_mesh_comp_unprovision();
 
     if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
+        bt_mesh_clear_net();
         bt_mesh_clear_seq();
         bt_mesh_clear_role();
     }
@@ -443,15 +440,26 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param)
         return -EALREADY;
     }
 
-    if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
-        if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV)) {
-            bt_mesh_beacon_disable();
-            bt_mesh_scan_disable();
-        }
+    bt_mesh_scan_disable();
+    bt_mesh_beacon_disable();
 
-        if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) {
+    if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node()) {
+        if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
+            !bt_mesh_is_provisioned()) {
             bt_mesh_proxy_server_prov_disable(true);
         }
+
+        if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
+            bt_mesh_is_provisioned()) {
+            bt_mesh_proxy_server_gatt_disable();
+        }
+
+        if (bt_mesh_is_provisioned()) {
+            /* Clear valid flag here in order to perform settings erase */
+            bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID);
+
+            bt_mesh_cfg_reset(param->erase);
+        }
     }
 
     if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) {
@@ -459,7 +467,7 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param)
             bt_mesh_proxy_client_prov_disable();
         }
 
-        bt_mesh_scan_disable();
+        /* Clear valid flag here in order to perform settings erase */
         bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID_PROV);
     }
 
@@ -470,16 +478,22 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param)
                 return err;
             }
         }
+
         if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) {
             err = bt_mesh_provisioner_prov_deinit(param->erase);
             if (err) {
                 return err;
             }
+
+            err = bt_mesh_provisioner_deinit(param->erase);
+            if (err) {
+                return err;
+            }
         }
     }
 
     bt_mesh_trans_deinit(param->erase);
-    bt_mesh_net_deinit(param->erase);
+    bt_mesh_net_deinit();
 
     bt_mesh_beacon_deinit();
 
@@ -497,13 +511,6 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param)
 
     bt_mesh_gatt_deinit();
 
-    if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) {
-        err = bt_mesh_provisioner_deinit(param->erase);
-        if (err) {
-            return err;
-        }
-    }
-
     if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
         bt_mesh_friend_deinit();
     }
@@ -514,6 +521,10 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param)
 
     bt_mesh_adv_deinit();
 
+    if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
+        bt_mesh_settings_deinit(param->erase);
+    }
+
     err = bt_mesh_comp_deregister();
     if (err) {
         return err;
@@ -521,9 +532,7 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param)
 
     bt_mesh_comp_unprovision();
 
-    if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
-        bt_mesh_settings_deinit(param->erase);
-    }
+    memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
 
     bt_mesh_timer_deinit();
 
@@ -568,6 +577,11 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)
         }
     }
 
+    /* Enable Provisioner here, because during the following net
+     * creation, some information needs to be stored in flash.
+     */
+    bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_VALID_PROV);
+
     err = bt_mesh_provisioner_net_create();
     if (err) {
         BT_ERR("Failed to create network");
@@ -603,8 +617,6 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)
         bt_mesh_proxy_client_prov_enable();
     }
 
-    bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_VALID_PROV);
-
     if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
         bt_mesh_friend_init();
     }

+ 1 - 8
components/bt/esp_ble_mesh/mesh_core/net.c

@@ -1557,7 +1557,7 @@ void bt_mesh_net_init(void)
     k_work_init(&bt_mesh.local_work, bt_mesh_net_local);
 }
 
-void bt_mesh_net_deinit(bool erase)
+void bt_mesh_net_deinit(void)
 {
     k_delayed_work_free(&bt_mesh.ivu_timer);
 
@@ -1579,11 +1579,4 @@ void bt_mesh_net_deinit(bool erase)
 
     bt_mesh.iv_index = 0U;
     bt_mesh.seq = 0U;
-
-    memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
-
-    if (erase && IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
-        bt_mesh_clear_seq();
-        bt_mesh_clear_iv();
-    }
 }

+ 1 - 1
components/bt/esp_ble_mesh/mesh_core/net.h

@@ -375,7 +375,7 @@ u32_t bt_mesh_next_seq(void);
 void bt_mesh_net_start(void);
 
 void bt_mesh_net_init(void);
-void bt_mesh_net_deinit(bool erase);
+void bt_mesh_net_deinit(void);
 
 void bt_mesh_net_header_parse(struct net_buf_simple *buf,
                               struct bt_mesh_net_rx *rx);

+ 30 - 28
components/bt/esp_ble_mesh/mesh_core/provisioner_main.c

@@ -22,6 +22,7 @@
 #include "settings.h"
 #include "friend.h"
 #include "transport.h"
+#include "foundation.h"
 #include "mesh_common.h"
 #include "proxy_client.h"
 #include "provisioner_prov.h"
@@ -162,28 +163,22 @@ int bt_mesh_provisioner_deinit(bool erase)
 {
     int i;
 
-    for (i = 0; i < CONFIG_BLE_MESH_PROVISIONER_SUBNET_COUNT; i++) {
+    for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
         if (bt_mesh.p_sub[i]) {
-            if (erase && IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
-                bt_mesh_clear_p_subnet(bt_mesh.p_sub[i]->net_idx);
-            }
-            bt_mesh_free(bt_mesh.p_sub[i]);
-            bt_mesh.p_sub[i] = NULL;
+            bt_mesh_provisioner_local_net_key_del(bt_mesh.p_sub[i]->net_idx, erase);
         }
     }
 
-    for (i = 0; i < CONFIG_BLE_MESH_PROVISIONER_APP_KEY_COUNT; i++) {
-        if (bt_mesh.p_app_keys[i]) {
-            if (erase && IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
-                bt_mesh_clear_p_app_key(bt_mesh.p_app_keys[i]->app_idx);
-            }
-            bt_mesh_free(bt_mesh.p_app_keys[i]);
-            bt_mesh.p_app_keys[i] = NULL;
-        }
-    }
+    /* 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.
+     */
+    bt_mesh_mod_sub_reset(erase);
 
     bt_mesh.p_net_idx_next = 0U;
     bt_mesh.p_app_idx_next = 0U;
+
     if (erase && IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
         bt_mesh_clear_p_net_idx();
         bt_mesh_clear_p_app_idx();
@@ -1116,7 +1111,7 @@ const u8_t *bt_mesh_provisioner_local_app_key_get(u16_t net_idx, u16_t app_idx)
     return NULL;
 }
 
-static void model_pub_clear(struct bt_mesh_model *model)
+static void model_pub_clear(struct bt_mesh_model *model, bool store)
 {
     if (!model->pub) {
         return;
@@ -1138,14 +1133,14 @@ static void model_pub_clear(struct bt_mesh_model *model)
         k_delayed_work_cancel(&model->pub->timer);
     }
 
-    if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
+    if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
         bt_mesh_store_mod_pub(model);
     }
 
     return;
 }
 
-static void model_unbind(struct bt_mesh_model *model, u16_t app_idx)
+static void model_unbind(struct bt_mesh_model *model, u16_t app_idx, bool store)
 {
     int i;
 
@@ -1158,24 +1153,30 @@ static void model_unbind(struct bt_mesh_model *model, u16_t app_idx)
 
         model->keys[i] = BLE_MESH_KEY_UNUSED;
 
-        if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
+        if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
             bt_mesh_store_mod_bind(model);
         }
 
-        model_pub_clear(model);
+        model_pub_clear(model, store);
     }
 }
 
+struct unbind_data {
+    u16_t app_idx;
+    bool store;
+};
+
 static void _model_unbind(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
                           bool vnd, bool primary, void *user_data)
 {
-    u16_t app_idx = *(u16_t *)user_data;
+    struct unbind_data *data = user_data;
 
-    model_unbind(mod, app_idx);
+    model_unbind(mod, data->app_idx, data->store);
 }
 
-int bt_mesh_provisioner_local_app_key_delete(u16_t net_idx, u16_t app_idx)
+int bt_mesh_provisioner_local_app_key_del(u16_t net_idx, u16_t app_idx, bool store)
 {
+    struct unbind_data data = { .app_idx = app_idx, .store = store };
     struct bt_mesh_app_key *key = NULL;
     int i;
 
@@ -1196,9 +1197,9 @@ int bt_mesh_provisioner_local_app_key_delete(u16_t net_idx, u16_t app_idx)
         if (key && key->net_idx == net_idx &&
                 key->app_idx == app_idx) {
             /* Remove the AppKey from the models if they are bound with it */
-            bt_mesh_model_foreach(_model_unbind, &app_idx);
+            bt_mesh_model_foreach(_model_unbind, &data);
 
-            if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
+            if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
                 bt_mesh_clear_p_app_key(app_idx);
             }
 
@@ -1369,7 +1370,7 @@ const u8_t *bt_mesh_provisioner_local_net_key_get(u16_t net_idx)
     return NULL;
 }
 
-int bt_mesh_provisioner_local_net_key_delete(u16_t net_idx)
+int bt_mesh_provisioner_local_net_key_del(u16_t net_idx, bool store)
 {
     struct bt_mesh_subnet *sub = NULL;
     int i, j;
@@ -1387,12 +1388,13 @@ int bt_mesh_provisioner_local_net_key_delete(u16_t net_idx)
             /* Delete any app keys bound to this NetKey index */
             for (j = 0; j < ARRAY_SIZE(bt_mesh.p_app_keys); j++) {
                 struct bt_mesh_app_key *key = bt_mesh.p_app_keys[j];
+
                 if (key && key->net_idx == sub->net_idx) {
-                    bt_mesh_provisioner_local_app_key_delete(key->net_idx, key->app_idx);
+                    bt_mesh_provisioner_local_app_key_del(key->net_idx, key->app_idx, store);
                 }
             }
 
-            if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
+            if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
                 bt_mesh_clear_p_subnet(net_idx);
             }
 

+ 2 - 2
components/bt/esp_ble_mesh/mesh_core/provisioner_main.h

@@ -111,7 +111,7 @@ int bt_mesh_provisioner_local_app_key_update(const u8_t app_key[16],
 
 const u8_t *bt_mesh_provisioner_local_app_key_get(u16_t net_idx, u16_t app_idx);
 
-int bt_mesh_provisioner_local_app_key_delete(u16_t net_idx, u16_t app_idx);
+int bt_mesh_provisioner_local_app_key_del(u16_t net_idx, u16_t app_idx, bool store);
 
 int bt_mesh_provisioner_local_net_key_add(const u8_t net_key[16], u16_t *net_idx);
 
@@ -119,7 +119,7 @@ int bt_mesh_provisioner_local_net_key_update(const u8_t net_key[16], u16_t net_i
 
 const u8_t *bt_mesh_provisioner_local_net_key_get(u16_t net_idx);
 
-int bt_mesh_provisioner_local_net_key_delete(u16_t net_idx);
+int bt_mesh_provisioner_local_net_key_del(u16_t net_idx, bool store);
 
 /* Provisioner bind local client model with proper appkey index */
 int bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr, u16_t mod_id,

+ 18 - 3
components/bt/esp_ble_mesh/mesh_core/settings.c

@@ -65,6 +65,7 @@ static struct key_update {
 } key_updates[CONFIG_BLE_MESH_APP_KEY_COUNT + CONFIG_BLE_MESH_SUBNET_COUNT];
 
 static struct k_delayed_work pending_store;
+static void store_pending(struct k_work *work);
 
 /* Mesh network storage information */
 struct net_val {
@@ -1463,6 +1464,14 @@ static void schedule_store(int flag)
 
     bt_mesh_atomic_set_bit(bt_mesh.flags, flag);
 
+    /* When Node is not provisioned OR Provisioner is disabled,
+     * we will directly erase the stored information.
+     */
+    if (!bt_mesh_is_provisioned() && !bt_mesh_is_provisioner_en()) {
+        store_pending(NULL);
+        return;
+    }
+
     if (bt_mesh_atomic_get(bt_mesh.flags) & NO_WAIT_PENDING_BITS) {
         timeout = K_NO_WAIT;
     } else if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_RPL_PENDING) &&
@@ -1540,7 +1549,7 @@ void bt_mesh_store_iv(bool only_duration)
     }
 }
 
-void bt_mesh_clear_iv(void)
+static void clear_iv(void)
 {
     BT_DBG("Clearing IV");
     bt_mesh_erase_core_settings("mesh/iv");
@@ -2080,7 +2089,7 @@ static void store_pending(struct k_work *work)
         if (bt_mesh_is_provisioned() || bt_mesh_is_provisioner_en()) {
             store_pending_iv();
         } else {
-            bt_mesh_clear_iv();
+            clear_iv();
         }
     }
 
@@ -2626,7 +2635,13 @@ int settings_core_deinit(void)
 
 int settings_core_erase(void)
 {
-    /* Erase here must not use the pending_store timer. */
+    /* Erase here must not use the pending_store timer.
+     * This is used for erasing the information which
+     * could not be erased during the previous deinit
+     * operations.
+     */
+    bt_mesh_clear_net();
+    bt_mesh_clear_seq();
     bt_mesh_clear_role();
     return 0;
 }

+ 0 - 1
components/bt/esp_ble_mesh/mesh_core/settings.h

@@ -22,7 +22,6 @@ extern "C" {
 void bt_mesh_store_role(void);
 void bt_mesh_store_net(void);
 void bt_mesh_store_iv(bool only_duration);
-void bt_mesh_clear_iv(void);
 void bt_mesh_store_seq(void);
 void bt_mesh_clear_seq(void);
 void bt_mesh_store_rpl(struct bt_mesh_rpl *rpl);