ble_mesh: stack: Persistent storage misc fixes

* Fix the issue that deinit node with "erase_flash"
  set to true, but info is not erased from nvs
* Reuse bt_mesh_cfg_reset() when deinit node
* Optimize Provisioner related erase operations
* No store pending timeout will be used when Node
  is not provisioned OR Provisioner is disabled
  and erase operation is performed
* Change the default timeout for settings operation
  to 0, and rpl store rate to 0
This commit is contained in:
lly 2020-09-17 11:22:49 +08:00
parent 733aaa4af0
commit 542b6bdbc1
10 changed files with 108 additions and 76 deletions

View file

@ -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

View file

@ -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));
}

View file

@ -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);

View file

@ -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();
}

View file

@ -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();
}
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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,

View file

@ -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;
}

View file

@ -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);