diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 882efb98e..cedc3d2cf 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -2030,7 +2030,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 @@ -2045,7 +2045,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 diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c index e5db4550f..3ea1a1229 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c +++ b/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)); } diff --git a/components/bt/esp_ble_mesh/mesh_core/foundation.h b/components/bt/esp_ble_mesh/mesh_core/foundation.h index abac4a6be..f766fc9c3 100644 --- a/components/bt/esp_ble_mesh/mesh_core/foundation.h +++ b/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); diff --git a/components/bt/esp_ble_mesh/mesh_core/main.c b/components/bt/esp_ble_mesh/mesh_core/main.c index 3fe02fe46..341fc8dd6 100644 --- a/components/bt/esp_ble_mesh/mesh_core/main.c +++ b/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,14 +440,25 @@ 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_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_PB_GATT)) { - 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); } } @@ -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(); } diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 64924f612..4fe0c3fa8 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/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(); - } } diff --git a/components/bt/esp_ble_mesh/mesh_core/net.h b/components/bt/esp_ble_mesh/mesh_core/net.h index 52b8abab9..23e3d4bc1 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.h +++ b/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); diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c index 59c64f1cf..fd6008a8e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c +++ b/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); } diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h index 332d1a541..5cc6490d5 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.h +++ b/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, diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.c b/components/bt/esp_ble_mesh/mesh_core/settings.c index 6a7af58ae..ccd1bdaa1 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.c +++ b/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; } diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.h b/components/bt/esp_ble_mesh/mesh_core/settings.h index 39d33e0a6..22bb153f1 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.h +++ b/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);