You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/07/09 10:49:10 UTC

[GitHub] michal-narajowski closed pull request #38: [WIP] Mesh storage

michal-narajowski closed pull request #38: [WIP] Mesh storage
URL: https://github.com/apache/mynewt-nimble/pull/38
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/nimble/host/mesh/include/mesh/main.h b/nimble/host/mesh/include/mesh/main.h
index 752878fa..aabe187d 100644
--- a/nimble/host/mesh/include/mesh/main.h
+++ b/nimble/host/mesh/include/mesh/main.h
@@ -348,6 +348,8 @@ int bt_mesh_lpn_poll(void);
  */
 void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established));
 
+int bt_mesh_restore(void);
+
 /**
  * @}
  */
diff --git a/nimble/host/mesh/pkg.yml b/nimble/host/mesh/pkg.yml
index 0365b300..66dc29c7 100644
--- a/nimble/host/mesh/pkg.yml
+++ b/nimble/host/mesh/pkg.yml
@@ -30,6 +30,7 @@ pkg.deps:
     - "@apache-mynewt-core/kernel/os"
     - "@apache-mynewt-core/util/mem"
     - "@apache-mynewt-core/crypto/tinycrypt"
+    - "@apache-mynewt-core/sys/config"
     - nimble
     - nimble/host  
 
diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c
index 2fb3fec6..e53fa2ac 100644
--- a/nimble/host/mesh/src/access.c
+++ b/nimble/host/mesh/src/access.c
@@ -27,7 +27,6 @@
 #endif
 
 static const struct bt_mesh_comp *dev_comp;
-static u16_t dev_primary_addr;
 
 static const struct {
 	const u16_t id;
@@ -282,7 +281,7 @@ void bt_mesh_comp_provision(u16_t addr)
 {
 	int i;
 
-	dev_primary_addr = addr;
+	bt_mesh.dev_primary_addr = addr;
 
 	BT_DBG("addr 0x%04x elem_count %zu", addr, dev_comp->elem_count);
 
@@ -300,14 +299,14 @@ void bt_mesh_comp_unprovision(void)
 {
 	BT_DBG("");
 
-	dev_primary_addr = BT_MESH_ADDR_UNASSIGNED;
+	bt_mesh.dev_primary_addr = BT_MESH_ADDR_UNASSIGNED;
 
 	bt_mesh_model_foreach(mod_init, NULL);
 }
 
 u16_t bt_mesh_primary_addr(void)
 {
-	return dev_primary_addr;
+	return bt_mesh.dev_primary_addr;
 }
 
 u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr)
diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c
index bda46a72..5d447d5f 100644
--- a/nimble/host/mesh/src/cfg_srv.c
+++ b/nimble/host/mesh/src/cfg_srv.c
@@ -28,6 +28,7 @@
 #include "foundation.h"
 #include "friend.h"
 #include "testing.h"
+#include "store.h"
 
 #define DEFAULT_TTL 7
 
@@ -447,6 +448,8 @@ static u8_t app_key_set(u16_t net_idx, u16_t app_idx, const u8_t val[16],
 	key->app_idx = app_idx;
 	memcpy(keys->val, val, 16);
 
+	bt_mesh_store_app_key_set(key);
+
 	return STATUS_SUCCESS;
 }
 
@@ -516,6 +519,8 @@ static void _app_key_del(struct bt_mesh_app_key *key)
 {
 	bt_mesh_model_foreach(_mod_unbind, &key->app_idx);
 
+	bt_mesh_store_app_key_del(key);
+
 	key->net_idx = BT_MESH_KEY_UNUSED;
 	memset(key->keys, 0, sizeof(key->keys));
 }
diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c
index 85db989f..916fabcb 100644
--- a/nimble/host/mesh/src/mesh.c
+++ b/nimble/host/mesh/src/mesh.c
@@ -28,9 +28,9 @@
 #include "proxy.h"
 #include "shell.h"
 #include "mesh_priv.h"
+#include "store.h"
 
 u8_t g_mesh_addr_type;
-static bool provisioned;
 
 int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
 		      u8_t flags, u32_t iv_index, u32_t seq,
@@ -61,7 +61,7 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
 
 	memcpy(bt_mesh.dev_key, dev_key, 16);
 
-	provisioned = true;
+	bt_mesh.provisioned = true;
 
 	if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
 		bt_mesh_beacon_enable();
@@ -89,23 +89,70 @@ int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
 		bt_mesh_prov_complete(net_idx, addr);
 	}
 
+	bt_mesh_store_net_set(&bt_mesh);
+	bt_mesh_store_sub_set_all(bt_mesh.sub ,ARRAY_SIZE(bt_mesh.sub));
+	bt_mesh_store_app_key_set_all(bt_mesh.app_keys ,ARRAY_SIZE(bt_mesh.app_keys));
+
+	return 0;
+}
+
+int bt_mesh_restore(void)
+{
+	const struct bt_mesh_store_net *store_net;
+	const struct bt_mesh_store_sub *store_sub;
+	struct bt_mesh_subnet *sub;
+	u8_t flags;
+
+	BT_DBG("");
+
+	store_net = bt_mesh_store_net_get();
+
+	if (!store_net->provisioned) {
+		BT_INFO("Nothing to restore");
+		return 0;
+	}
+
+	store_sub = bt_mesh_store_sub_get_next(NULL);
+	flags = bt_mesh_store_net_flags(store_sub);
+
+	bt_mesh_provision(store_sub->keys[store_sub->kr_flag].net,
+			  store_sub->net_idx, flags, store_net->iv_index,
+			  store_net->seq, store_net->dev_primary_addr,
+			  store_net->dev_key);
+
+	store_sub = bt_mesh_store_sub_get_next(store_sub);
+
+	while(store_sub) {
+		sub = bt_mesh_subnet_get(BT_MESH_KEY_UNUSED);
+		if (!sub) {
+			break;
+		}
+
+		flags = bt_mesh_store_net_flags(store_sub);
+
+		bt_mesh_subnet_create(sub, store_sub->net_idx, flags,
+				      store_sub->keys[store_sub->kr_phase].net);
+		store_sub = bt_mesh_store_sub_get_next(store_sub);
+	}
+
+	bt_mesh_store_app_key_restore(bt_mesh.app_keys, ARRAY_SIZE(bt_mesh.app_keys));
+
 	return 0;
 }
 
 void bt_mesh_reset(void)
 {
-	if (!provisioned) {
+	if (!bt_mesh.provisioned) {
 		return;
 	}
 
 	bt_mesh_comp_unprovision();
 
-	bt_mesh.iv_index = 0;
-	bt_mesh.seq = 0;
-	bt_mesh.iv_update = 0;
-	bt_mesh.pending_update = 0;
-	bt_mesh.valid = 0;
-	bt_mesh.last_update = 0;
+	bt_mesh_net_set_iv_index(0, false);
+	bt_mesh_net_set_sequence_number(0);
+	bt_mesh_net_set_pending_update(false);
+	bt_mesh_net_set_valid(false);
+	bt_mesh_net_set_last_update(0);
 	bt_mesh.ivu_initiator = 0;
 
 	k_delayed_work_cancel(&bt_mesh.ivu_complete);
@@ -135,7 +182,7 @@ void bt_mesh_reset(void)
 
 	memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
 
-	provisioned = false;
+	bt_mesh.provisioned = false;
 
 	bt_mesh_scan_disable();
 	bt_mesh_beacon_disable();
@@ -143,11 +190,16 @@ void bt_mesh_reset(void)
 	if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
 		bt_mesh_prov_reset();
 	}
+
+	bt_mesh_store_net_set(&bt_mesh);
+	bt_mesh_store_sub_set_all(bt_mesh.sub, ARRAY_SIZE(bt_mesh.sub));
+	bt_mesh_store_app_key_set_all(bt_mesh.app_keys,
+				      ARRAY_SIZE(bt_mesh.app_keys));
 }
 
 bool bt_mesh_is_provisioned(void)
 {
-	return provisioned;
+	return bt_mesh.provisioned;
 }
 
 int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c
index 9bd79681..64ae347b 100644
--- a/nimble/host/mesh/src/net.c
+++ b/nimble/host/mesh/src/net.c
@@ -143,6 +143,96 @@ static bool msg_cache_match(struct bt_mesh_net_rx *rx,
 	return false;
 }
 
+void bt_mesh_net_set_last_update(s64_t last_udpate)
+{
+	bt_mesh.last_update = last_udpate;
+}
+
+s64_t bt_mesh_net_get_last_update(void)
+{
+	return bt_mesh.last_update;
+}
+
+bool bt_mesh_net_get_valid(void)
+{
+	return (bool) bt_mesh.valid;
+}
+
+void bt_mesh_net_set_valid(bool valid)
+{
+	bt_mesh.valid = (uint32_t) valid;
+}
+
+bool bt_mesh_net_get_iv_update(void)
+{
+	return (bool) bt_mesh.iv_update;
+}
+
+void bt_mesh_net_set_iv_update(bool iv_update)
+{
+	bt_mesh.iv_update = (uint32_t) iv_update;
+}
+
+u32_t bt_mesh_net_get_iv_index(bool *update)
+{
+	if (update)
+		*update = (bool) bt_mesh.iv_update;
+
+	return bt_mesh.iv_index;
+}
+
+void bt_mesh_net_set_iv_index(u32_t index, bool update)
+{
+	bt_mesh.iv_index = index;
+	bt_mesh.iv_update = (uint32_t) update;
+}
+
+bool bt_mesh_net_get_key(u16_t net_idx, u8_t *key)
+{
+	struct bt_mesh_subnet *sub;
+
+	sub = bt_mesh_subnet_get(net_idx);
+	if (!sub) {
+		return false;
+	}
+
+	memcpy(key, sub->keys[sub->kr_flag].net, 16);
+	return true;
+}
+
+bool bt_mesh_net_get_flags(u16_t net_idx, u8_t *out_flags)
+{
+	struct bt_mesh_subnet *sub;
+
+	sub = bt_mesh_subnet_get(net_idx);
+	if (!sub) {
+		return false;
+	}
+
+	*out_flags = bt_mesh_net_flags(sub);
+	return true;
+}
+
+u32_t bt_mesh_net_get_sequence_number(void)
+{
+	return bt_mesh.seq;
+}
+
+void bt_mesh_net_set_sequence_number(u32_t seq_number)
+{
+	bt_mesh.seq = seq_number;
+}
+
+bool bt_mesh_net_get_pending_update(void)
+{
+	return (bool) bt_mesh.pending_update;
+}
+
+void bt_mesh_net_set_pending_update(bool pending)
+{
+	bt_mesh.pending_update = (uint32_t) pending;
+}
+
 struct bt_mesh_subnet *bt_mesh_subnet_get(u16_t net_idx)
 {
 	int i;
@@ -412,7 +502,7 @@ u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub)
 		flags |= BT_MESH_NET_FLAG_KR;
 	}
 
-	if (bt_mesh.iv_update) {
+	if (bt_mesh_net_get_iv_update()) {
 		flags |= BT_MESH_NET_FLAG_IVU;
 	}
 
@@ -432,31 +522,17 @@ int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub)
 		keys = &sub->keys[0];
 	}
 
-	BT_DBG("flags 0x%02x, IVI 0x%08x", flags, bt_mesh.iv_index);
+	BT_DBG("flags 0x%02x, IVI 0x%08x", flags, bt_mesh_net_get_iv_index(NULL));
 
 	return bt_mesh_beacon_auth(keys->beacon, flags, keys->net_id,
-				   bt_mesh.iv_index, sub->auth);
+				   bt_mesh_net_get_iv_index(NULL), sub->auth);
 }
 
-int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
-		       u32_t iv_index)
+int bt_mesh_subnet_create(struct bt_mesh_subnet *sub, u16_t idx,
+			  u8_t flags, const u8_t key[16])
 {
-	struct bt_mesh_subnet *sub;
 	int err;
 
-	BT_DBG("idx %u flags 0x%02x iv_index %u", idx, flags, iv_index);
-
-	BT_DBG("NetKey %s", bt_hex(key, 16));
-
-	if (bt_mesh.valid) {
-		return -EALREADY;
-	}
-
-	memset(msg_cache, 0, sizeof(msg_cache));
-	msg_cache_next = 0;
-
-	sub = &bt_mesh.sub[0];
-
 	sub->kr_flag = BT_MESH_KEY_REFRESH(flags);
 	if (sub->kr_flag) {
 		err = bt_mesh_net_keys_create(&sub->keys[1], key);
@@ -472,7 +548,6 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
 		}
 	}
 
-	bt_mesh.valid = 1;
 	sub->net_idx = idx;
 
 	if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) {
@@ -481,14 +556,37 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
 		sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
 	}
 
-	bt_mesh.iv_index = iv_index;
-	bt_mesh.iv_update = BT_MESH_IV_UPDATE(flags);
+	/* Make sure we have valid beacon data to be sent */
+	bt_mesh_net_beacon_update(sub);
+
+	return 0;
+}
+
+int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
+		       u32_t iv_index)
+{
+	struct bt_mesh_subnet *sub;
+
+	BT_DBG("idx %u flags 0x%02x iv_index %u", idx, flags, iv_index);
+
+	BT_DBG("NetKey %s", bt_hex(key, 16));
+
+	if (bt_mesh_net_get_valid()) {
+		return -EALREADY;
+	}
+
+	memset(msg_cache, 0, sizeof(msg_cache));
+	msg_cache_next = 0;
+
+	bt_mesh_net_set_valid(true);
+	bt_mesh_net_set_iv_index(iv_index, BT_MESH_IV_UPDATE(flags));
 
 	/* Set initial IV Update procedure state time-stamp */
-	bt_mesh.last_update = k_uptime_get();
+	bt_mesh_net_set_last_update(k_uptime_get());
 
-	/* Make sure we have valid beacon data to be sent */
-	bt_mesh_net_beacon_update(sub);
+	sub = &bt_mesh.sub[0];
+
+	bt_mesh_subnet_create(sub, idx, flags, key);
 
 	return 0;
 }
@@ -590,15 +688,15 @@ bool bt_mesh_iv_update(void)
 		return false;
 	}
 
-	if (bt_mesh.iv_update) {
-		bt_mesh_net_iv_update(bt_mesh.iv_index, false);
+	if (bt_mesh_net_get_iv_update()) {
+		bt_mesh_net_iv_update(bt_mesh_net_get_iv_index(NULL), false);
 	} else {
-		bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true);
+		bt_mesh_net_iv_update(bt_mesh_net_get_iv_index(NULL) + 1, true);
 	}
 
 	bt_mesh_net_sec_update(NULL);
 
-	return bt_mesh.iv_update;
+	return bt_mesh_net_get_iv_update();
 }
 #endif /* CONFIG_BT_MESH_IV_UPDATE_TEST */
 
@@ -619,12 +717,12 @@ bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update)
 {
 	int i;
 
-	if (bt_mesh.iv_update) {
+	if (bt_mesh_net_get_iv_update()) {
 		/* We're currently in IV Update mode */
 
-		if (iv_index != bt_mesh.iv_index) {
+		if (iv_index != bt_mesh_net_get_iv_index(NULL)) {
 			BT_WARN("IV Index mismatch: 0x%08x != 0x%08x",
-				iv_index, bt_mesh.iv_index);
+				iv_index, bt_mesh_net_get_iv_index(NULL));
 			return false;
 		}
 
@@ -636,27 +734,27 @@ bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update)
 	} else {
 		/* We're currently in Normal mode */
 
-		if (iv_index == bt_mesh.iv_index) {
+		if (iv_index == bt_mesh_net_get_iv_index(NULL)) {
 			BT_DBG("Same IV Index in normal mode");
 			return false;
 		}
 
-		if (iv_index < bt_mesh.iv_index ||
-		    iv_index > bt_mesh.iv_index + 42) {
+		if (iv_index < bt_mesh_net_get_iv_index(NULL) ||
+		    iv_index > bt_mesh_net_get_iv_index(NULL) + 42) {
 			BT_ERR("IV Index out of sync: 0x%08x != 0x%08x",
-			       iv_index, bt_mesh.iv_index);
+			       iv_index, bt_mesh_net_get_iv_index(NULL));
 			return false;
 		}
 
-		if (iv_index > bt_mesh.iv_index + 1) {
+		if (iv_index > bt_mesh_net_get_iv_index(NULL) + 1) {
 			BT_WARN("Performing IV Index Recovery");
 			memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
-			bt_mesh.iv_index = iv_index;
-			bt_mesh.seq = 0;
+			bt_mesh_net_set_iv_index(iv_index, bt_mesh_net_get_iv_update());
+			bt_mesh_net_set_sequence_number(0);
 			goto do_update;
 		}
 
-		if (iv_index == bt_mesh.iv_index + 1 && !iv_update) {
+		if (iv_index == bt_mesh_net_get_iv_index(NULL) + 1 && !iv_update) {
 			BT_WARN("Ignoring new index in normal mode");
 			return false;
 		}
@@ -667,15 +765,15 @@ bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update)
 			return false;
 		}
 
-		if (iv_index != bt_mesh.iv_index + 1) {
+		if (iv_index != bt_mesh_net_get_iv_index(NULL) + 1) {
 			BT_WARN("Wrong new IV Index: 0x%08x != 0x%08x + 1",
-				iv_index, bt_mesh.iv_index);
+				iv_index, bt_mesh_net_get_iv_index(NULL));
 			return false;
 		}
 	}
 
 	if (!MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST) || !bt_mesh.ivu_test) {
-		s64_t delta = k_uptime_get() - bt_mesh.last_update;
+		s64_t delta = k_uptime_get() - bt_mesh_net_get_last_update();
 
 		if (delta < K_HOURS(96)) {
 			BT_WARN("IV Update before minimum duration");
@@ -686,17 +784,17 @@ bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update)
 	/* Defer change to Normal Operation if there are pending acks */
 	if (!iv_update && bt_mesh_tx_in_progress()) {
 		BT_WARN("IV Update deferred because of pending transfer");
-		bt_mesh.pending_update = 1;
+		bt_mesh_net_set_pending_update(true);
 		return false;
 	}
 
 do_update:
-	bt_mesh.iv_update = iv_update;
+	bt_mesh_net_set_iv_update(iv_update);
 
-	if (bt_mesh.iv_update) {
-		bt_mesh.iv_index = iv_index;
+	if (bt_mesh_net_get_iv_update()) {
+		bt_mesh_net_set_iv_index(iv_index, iv_update);
 		BT_DBG("IV Update state entered. New index 0x%08x",
-		       bt_mesh.iv_index);
+		       bt_mesh_net_get_iv_index(NULL));
 
 		bt_mesh_rpl_reset();
 
@@ -704,12 +802,12 @@ bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update)
 				      IV_UPDATE_TIMEOUT);
 	} else {
 		BT_DBG("Normal mode entered");
-		bt_mesh.seq = 0;
+		bt_mesh_net_set_sequence_number(0);
 		k_delayed_work_cancel(&bt_mesh.ivu_complete);
 	}
 
 	/* Store time-stamp of the IV procedure state change */
-	bt_mesh.last_update = k_uptime_get();
+	bt_mesh_net_set_last_update(k_uptime_get());
 
 	for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
 		if (bt_mesh.sub[i].net_idx != BT_MESH_KEY_UNUSED) {
@@ -746,9 +844,10 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf,
 	}
 
 	/* Update with a new sequence number */
-	buf->om_data[2] = (bt_mesh.seq >> 16);
-	buf->om_data[3] = (bt_mesh.seq >> 8);
-	buf->om_data[4] = bt_mesh.seq++;
+	buf->om_data[2] = (bt_mesh_net_get_sequence_number() >> 16);
+	buf->om_data[3] = (bt_mesh_net_get_sequence_number() >> 8);
+	buf->om_data[4] = bt_mesh_net_get_sequence_number();
+	bt_mesh_net_set_sequence_number(bt_mesh_net_get_sequence_number() + 1);
 
 	err = bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_TX, false);
 	if (err) {
@@ -764,9 +863,10 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf,
 
 	bt_mesh_adv_send(buf, cb, cb_data);
 
-	if (!bt_mesh.iv_update && bt_mesh.seq > IV_UPDATE_SEQ_LIMIT) {
+	if (!bt_mesh_net_get_iv_update() &&
+	    bt_mesh_net_get_sequence_number() > IV_UPDATE_SEQ_LIMIT) {
 		bt_mesh_beacon_ivu_initiator(true);
-		bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true);
+		bt_mesh_net_iv_update(bt_mesh_net_get_iv_index(NULL) + 1, true);
 		bt_mesh_net_sec_update(NULL);
 	}
 
@@ -802,15 +902,16 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf,
 	}
 
 	BT_DBG("src 0x%04x dst 0x%04x ctl %u seq 0x%06x",
-	       tx->src, tx->ctx->addr, ctl, bt_mesh.seq);
+	       tx->src, tx->ctx->addr, ctl, bt_mesh_net_get_sequence_number());
 
 	net_buf_simple_push_be16(buf, tx->ctx->addr);
 	net_buf_simple_push_be16(buf, tx->src);
 
 	seq = net_buf_simple_push(buf, 3);
-	seq[0] = (bt_mesh.seq >> 16);
-	seq[1] = (bt_mesh.seq >> 8);
-	seq[2] = bt_mesh.seq++;
+	seq[0] = (bt_mesh_net_get_sequence_number() >> 16);
+	seq[1] = (bt_mesh_net_get_sequence_number() >> 8);
+	seq[2] = bt_mesh_net_get_sequence_number();
+	bt_mesh_net_set_sequence_number(bt_mesh_net_get_sequence_number() + 1);
 
 	if (ctl) {
 		net_buf_simple_push_u8(buf, tx->ctx->send_ttl | 0x80);
@@ -855,7 +956,7 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf,
 	       tx->src, tx->ctx->addr, buf->om_len, net_buf_headroom(buf),
 	       net_buf_tailroom(buf));
 	BT_DBG("Payload len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len));
-	BT_DBG("Seq 0x%06x", bt_mesh.seq);
+	BT_DBG("Seq 0x%06x", bt_mesh_net_get_sequence_number());
 
 	if (tx->ctx->send_ttl == BT_MESH_TTL_DEFAULT) {
 		tx->ctx->send_ttl = bt_mesh_default_ttl_get();
@@ -979,9 +1080,9 @@ static int net_decrypt(struct bt_mesh_subnet *sub, const u8_t *enc,
 		       struct os_mbuf *buf)
 {
 	BT_DBG("NID 0x%02x net_idx 0x%04x", NID(data), sub->net_idx);
-	BT_DBG("IVI %u net->iv_index 0x%08x", IVI(data), bt_mesh.iv_index);
+	BT_DBG("IVI %u net->iv_index 0x%08x", IVI(data), bt_mesh_net_get_iv_index(NULL));
 
-	rx->old_iv = (IVI(data) != (bt_mesh.iv_index & 0x01));
+	rx->old_iv = (IVI(data) != (bt_mesh_net_get_iv_index(NULL) & 0x01));
 
 	net_buf_simple_init(buf, 0);
 	memcpy(net_buf_simple_add(buf, data_len), data, data_len);
@@ -1342,7 +1443,7 @@ static void ivu_complete(struct os_event *work)
 	BT_DBG("");
 
 	bt_mesh_beacon_ivu_initiator(true);
-	bt_mesh_net_iv_update(bt_mesh.iv_index, false);
+	bt_mesh_net_iv_update(bt_mesh_net_get_iv_index(NULL), false);
 }
 
 void bt_mesh_net_init(void)
diff --git a/nimble/host/mesh/src/net.h b/nimble/host/mesh/src/net.h
index 5e11aa27..8645dc46 100644
--- a/nimble/host/mesh/src/net.h
+++ b/nimble/host/mesh/src/net.h
@@ -199,6 +199,9 @@ struct bt_mesh_net {
 
 	s64_t last_update;       /* Time since last IV Update change */
 
+    	bool provisioned;
+    	u16_t dev_primary_addr;
+
 	/* Local network interface */
 	struct os_callout local_work;
 	struct net_buf_slist_t local_queue;
@@ -266,9 +269,27 @@ extern struct bt_mesh_net bt_mesh;
 
 #define BT_MESH_NET_HDR_LEN 9
 
+void bt_mesh_net_set_last_update(s64_t last_udpate);
+s64_t bt_mesh_net_get_last_update(void);
+bool bt_mesh_net_get_valid(void);
+void bt_mesh_net_set_valid(bool valid);
+bool bt_mesh_net_get_iv_update(void);
+void bt_mesh_net_set_iv_update(bool iv_update);
+u32_t bt_mesh_net_get_iv_index(bool *iv_update);
+void  bt_mesh_net_set_iv_index(u32_t index, bool update);
+u32_t bt_mesh_net_get_sequence_number(void);
+void  bt_mesh_net_set_sequence_number(u32_t seq_number);
+bool bt_mesh_net_get_pending_update(void);
+void bt_mesh_net_set_pending_update(bool pending);
+bool bt_mesh_net_get_key(u16_t net_idx, u8_t *key);
+bool bt_mesh_net_get_flags(u16_t net_idx, u8_t *out_flags);
+
 int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys,
 			    const u8_t key[16]);
 
+int bt_mesh_subnet_create(struct bt_mesh_subnet *sub, u16_t idx,
+			  u8_t flags, const u8_t key[16]);
+
 int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
 		       u32_t iv_index);
 
diff --git a/nimble/host/mesh/src/shell.c b/nimble/host/mesh/src/shell.c
index 44b4f5f7..b427290a 100644
--- a/nimble/host/mesh/src/shell.c
+++ b/nimble/host/mesh/src/shell.c
@@ -37,6 +37,7 @@
 #include "foundation.h"
 #include "testing.h"
 #include "model_cli.h"
+#include "store_config.h"
 
 /* This should be higher priority (lower value) than main task priority */
 #define BLE_MESH_SHELL_TASK_PRIO 126
@@ -2333,6 +2334,11 @@ static int cmd_print_composition_data(int argc, char *argv[])
 	return 0;
 }
 
+static int cmd_restore(int argc, char *argv[])
+{
+	return bt_mesh_restore();
+}
+
 static const struct shell_cmd mesh_commands[] = {
 	{ "init", cmd_init, NULL },
 	{ "timeout", cmd_timeout, &cmd_timeout_help },
@@ -2406,6 +2412,8 @@ static const struct shell_cmd mesh_commands[] = {
 	{ "add-fault", cmd_add_fault, &cmd_add_fault_help },
 	{ "del-fault", cmd_del_fault, &cmd_del_fault_help },
 
+	{ "restore", cmd_restore, NULL },
+
 #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
 	/* Generic Client Model Operations */
 	{ "gen-onoff-get", cmd_gen_onoff_get, NULL },
@@ -2454,4 +2462,6 @@ void ble_mesh_shell_init(void)
 #endif
 
 #endif
+
+	bt_mesh_store_config_init();
 }
diff --git a/nimble/host/mesh/src/store.c b/nimble/host/mesh/src/store.c
new file mode 100644
index 00000000..1aef96ab
--- /dev/null
+++ b/nimble/host/mesh/src/store.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "net.h"
+#include "store.h"
+#include "store_config.h"
+#include "mesh_priv.h"
+
+#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG))
+
+struct bt_mesh_store_net mesh_store_net;
+struct bt_mesh_store_sub mesh_store_subs[MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)];
+struct bt_mesh_store_app_key mesh_store_app_keys[MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT)];
+
+const struct bt_mesh_store_net *bt_mesh_store_net_get(void)
+{
+	BT_DBG("");
+
+	return &mesh_store_net;
+}
+
+void bt_mesh_store_net_set(struct bt_mesh_net *net)
+{
+	BT_DBG("");
+
+	mesh_store_net.iv_index = net->iv_index;
+	mesh_store_net.provisioned = net->provisioned;
+	mesh_store_net.dev_primary_addr = net->dev_primary_addr;
+	mesh_store_net.seq = net->seq;
+	mesh_store_net.iv_update = net->iv_update;
+	memcpy(mesh_store_net.dev_key, net->dev_key, sizeof(net->dev_key));
+
+	bt_mesh_store_config_persist_net();
+}
+
+const struct bt_mesh_store_sub *bt_mesh_store_sub_get_next(const struct bt_mesh_store_sub *p)
+{
+	const struct bt_mesh_store_sub *last = mesh_store_subs + ARRAY_SIZE(mesh_store_subs) - 1;
+
+	if (!p) {
+		return &mesh_store_subs[0];
+	}
+
+	if ((p < mesh_store_subs) || (p >= (last))) {
+		return NULL;
+	}
+
+	p++;
+
+	while(p < last) {
+		if (p->net_idx != BT_MESH_KEY_UNUSED) {
+			return p;
+		}
+
+		p++;
+	}
+
+	return NULL;
+}
+
+static struct bt_mesh_store_sub *mesh_store_subs_get(u16_t net_idx)
+{
+	int i;
+
+	if (net_idx == BT_MESH_KEY_ANY) {
+		return &mesh_store_subs[0];
+	}
+
+	for (i = 0; i < ARRAY_SIZE(mesh_store_subs); i++) {
+		if (mesh_store_subs[i].net_idx == net_idx) {
+			return &mesh_store_subs[i];
+		}
+	}
+
+	return NULL;
+}
+
+static struct bt_mesh_store_sub *mesh_store_subs_alloc(void)
+{
+	return mesh_store_subs_get(BT_MESH_KEY_UNUSED);
+}
+
+static void mesh_store_sub_set(struct bt_mesh_store_sub *store_sub,
+			       struct bt_mesh_subnet *sub)
+{
+	store_sub->net_idx = sub->net_idx;
+	store_sub->kr_flag = sub->kr_flag;
+	store_sub->kr_phase = sub->kr_phase;
+
+	memcpy(store_sub->keys[0].net, sub->keys[0].net,
+	       sizeof(store_sub->keys[0].net));
+	memcpy(store_sub->keys[1].net, sub->keys[1].net,
+	       sizeof(store_sub->keys[1].net));
+}
+
+void bt_mesh_store_sub_set(struct bt_mesh_subnet *sub)
+{
+	struct bt_mesh_store_sub *store_sub;
+
+	store_sub = mesh_store_subs_get(sub->net_idx);
+	if (!store_sub) {
+		store_sub = mesh_store_subs_alloc();
+	}
+
+	mesh_store_sub_set(store_sub, sub);
+
+	bt_mesh_store_config_persist_subnets();
+}
+
+void bt_mesh_store_sub_set_all(struct bt_mesh_subnet *sub, size_t count)
+{
+	int i;
+
+	for (i = 0; i < count ; ++i) {
+		mesh_store_sub_set(&mesh_store_subs[i], sub++);
+	}
+
+	bt_mesh_store_config_persist_subnets();
+}
+
+u8_t bt_mesh_store_net_flags(const struct bt_mesh_store_sub *sub)
+{
+	u8_t flags = 0x00;
+
+	if (sub && sub->kr_flag) {
+		flags |= BT_MESH_NET_FLAG_KR;
+	}
+
+	if (mesh_store_net.iv_update) {
+		flags |= BT_MESH_NET_FLAG_IVU;
+	}
+
+	return flags;
+}
+
+static struct bt_mesh_store_app_key *app_key_alloc()
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mesh_store_app_keys); i++) {
+		struct bt_mesh_store_app_key *key = &mesh_store_app_keys[i];
+
+		if (key->net_idx == BT_MESH_KEY_UNUSED) {
+			return key;
+		}
+	}
+
+	return NULL;
+}
+
+static struct bt_mesh_store_app_key *app_key_find(u16_t app_idx)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mesh_store_app_keys); i++) {
+		struct bt_mesh_store_app_key *key = &mesh_store_app_keys[i];
+
+		if (key->net_idx != BT_MESH_KEY_UNUSED &&
+		    key->app_idx == app_idx) {
+			return key;
+		}
+	}
+
+	return NULL;
+}
+
+void bt_mesh_store_app_key_del(struct bt_mesh_app_key *key)
+{
+	struct bt_mesh_store_app_key *found_key;
+
+	found_key = app_key_find(key->app_idx);
+	if (!found_key) {
+		return;
+	}
+
+	found_key->net_idx = BT_MESH_KEY_UNUSED;
+	memset(found_key->keys, 0, sizeof(found_key->keys));
+
+	bt_mesh_store_config_persist_app_keys();
+}
+
+static void mesh_store_app_key_set(struct bt_mesh_store_app_key *store_key,
+				   struct bt_mesh_app_key *key)
+{
+	store_key->net_idx = key->net_idx;
+	store_key->app_idx = key->app_idx;
+	store_key->updated = key->updated;
+	store_key->keys[0].id = key->keys[0].id;
+	store_key->keys[1].id = key->keys[1].id;
+	memcpy(store_key->keys[0].val, key->keys[0].val,
+	       sizeof(store_key->keys[0].val));
+	memcpy(store_key->keys[1].val, key->keys[1].val,
+	       sizeof(store_key->keys[1].val));
+}
+
+static void mesh_store_app_key_restore(struct bt_mesh_app_key *key,
+				       struct bt_mesh_store_app_key *store_key)
+{
+	key->net_idx = store_key->net_idx ;
+	key->app_idx = store_key->app_idx;
+	key->updated = store_key->updated;
+	key->keys[0].id = store_key->keys[0].id ;
+	key->keys[1].id = store_key->keys[1].id;
+	memcpy(key->keys[0].val, store_key->keys[0].val,
+	       sizeof(key->keys[0].val));
+	memcpy(key->keys[1].val, store_key->keys[1].val,
+	       sizeof(key->keys[1].val));
+}
+
+void bt_mesh_store_app_key_set(struct bt_mesh_app_key *key)
+{
+	struct bt_mesh_store_app_key *found_key = app_key_find(key->app_idx);
+	if (!found_key) {
+		found_key = app_key_alloc();
+	}
+
+	mesh_store_app_key_set(found_key, key);
+
+	bt_mesh_store_config_persist_app_keys();
+}
+
+void bt_mesh_store_app_key_set_all(struct bt_mesh_app_key *key, size_t count)
+{
+	int i;
+
+	for (i = 0; i < count ; ++i) {
+		mesh_store_app_key_set(&mesh_store_app_keys[i], key++);
+	}
+
+	bt_mesh_store_config_persist_app_keys();
+}
+
+void bt_mesh_store_app_key_restore(struct bt_mesh_app_key *key, size_t num)
+{
+	int i;
+
+	for (i = 0; i < num; ++i) {
+		mesh_store_app_key_restore(&key[i], &mesh_store_app_keys[i]);
+	}
+}
diff --git a/nimble/host/mesh/src/store.h b/nimble/host/mesh/src/store.h
new file mode 100644
index 00000000..c7d23fbf
--- /dev/null
+++ b/nimble/host/mesh/src/store.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __BT_MESH_STORE_H
+#define __BT_MESH_STORE_H
+
+#include "mesh/glue.h"
+
+struct bt_mesh_store_net {
+    u32_t iv_index;
+    u32_t seq:24,
+          iv_update:1;
+
+    bool provisioned;
+    uint16_t dev_primary_addr;
+
+    u8_t dev_key[16];
+};
+
+struct bt_mesh_store_sub {
+    u16_t net_idx;
+    bool kr_flag;
+    u8_t kr_phase;
+
+    struct bt_mesh_store_subnet_keys {
+        u8_t net[16];       /* NetKey */
+    } keys[2];
+};
+
+struct bt_mesh_store_app_key {
+    u16_t net_idx;
+    u16_t app_idx;
+    bool  updated;
+    struct bt_mesh_store_app_keys {
+        u8_t id;
+        u8_t val[16];
+    } keys[2];
+};
+
+struct bt_mesh_net;
+struct bt_mesh_subnet;
+struct bt_mesh_app_key;
+
+const struct bt_mesh_store_net *bt_mesh_store_net_get(void);
+void bt_mesh_store_net_set(struct bt_mesh_net *net);
+
+const struct bt_mesh_store_sub *bt_mesh_store_sub_get_next(const struct bt_mesh_store_sub *p);
+void bt_mesh_store_sub_set(struct bt_mesh_subnet *sub);
+void bt_mesh_store_sub_set_all(struct bt_mesh_subnet *sub, size_t count);
+u8_t bt_mesh_store_net_flags(const struct bt_mesh_store_sub *sub);
+
+void bt_mesh_store_app_key_del(struct bt_mesh_app_key *key);
+void bt_mesh_store_app_key_set(struct bt_mesh_app_key *key);
+void bt_mesh_store_app_key_set_all(struct bt_mesh_app_key *key, size_t count);
+const struct bt_mesh_store_app_key *bt_mesh_store_app_key_get_next(const struct bt_mesh_store_app_key *p);
+void bt_mesh_store_app_key_restore(struct bt_mesh_app_key *key, size_t num);
+
+#endif /* __BT_MESH_STORE_H */
+
diff --git a/nimble/host/mesh/src/store_config.c b/nimble/host/mesh/src/store_config.c
new file mode 100644
index 00000000..0f7be60c
--- /dev/null
+++ b/nimble/host/mesh/src/store_config.c
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "syscfg/syscfg.h"
+
+//#if MYNEWT_VAL(BT_MESH_STORE_CONFIG_PERSIST)
+
+#include <inttypes.h>
+
+#include "sysinit/sysinit.h"
+
+#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG))
+
+#include "config/config.h"
+#include "base64/base64.h"
+#include "mesh/glue.h"
+#include "store.h"
+#include "store_config.h"
+
+extern struct bt_mesh_store_net mesh_store_net;
+extern struct bt_mesh_store_sub mesh_store_subs[MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)];
+extern struct bt_mesh_store_app_key mesh_store_app_keys[MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT)];
+
+static int bt_mesh_store_config_conf_set(int argc, char **argv, char *val);
+static int bt_mesh_store_config_conf_export(void (*func)(char *name, char *val),
+					    enum conf_export_tgt tgt);
+
+static struct conf_handler bt_mesh_store_config_conf_handler = {
+	.ch_name = "bt_mesh",
+	.ch_get = NULL,
+	.ch_set = bt_mesh_store_config_conf_set,
+	.ch_commit = NULL,
+	.ch_export = bt_mesh_store_config_conf_export
+};
+
+#define BT_STORE_CONFIG_NET_ENCODE_SZ \
+            (BASE64_ENCODE_SIZE(sizeof(mesh_store_net)))
+
+#define BT_STORE_CONFIG_SUBNETS_ENCODE_SZ \
+            (BASE64_ENCODE_SIZE(sizeof(mesh_store_subs)))
+
+#define BT_STORE_CONFIG_APP_KEYS_ENCODE_SZ \
+            (BASE64_ENCODE_SIZE(sizeof(mesh_store_app_keys)))
+
+static void bt_mesh_store_config_serialize_arr(const void *arr, int obj_sz,
+					       int num_objs, char *out_buf,
+					       int buf_sz)
+{
+	int arr_size;
+
+	arr_size = obj_sz * num_objs;
+	assert(arr_size <= buf_sz);
+
+	base64_encode(arr, arr_size, out_buf, 1);
+}
+
+static int bt_mesh_store_config_deserialize_arr(const char *enc, void *out_arr,
+						int obj_sz, int *out_num_objs)
+{
+	int len;
+
+	len = base64_decode(enc, out_arr);
+	if (len < 0) {
+		return OS_EINVAL;
+	}
+
+	*out_num_objs = len / obj_sz;
+	return 0;
+}
+
+static int bt_mesh_store_config_conf_set(int argc, char **argv, char *val)
+{
+	int rc;
+
+	BT_DBG("");
+
+	if (argc == 1) {
+		if (strcmp(argv[0], "net") == 0) {
+			rc = bt_mesh_store_config_deserialize_arr(
+				val,
+				&mesh_store_net,
+				sizeof(struct bt_mesh_store_net),
+				NULL);
+			return rc;
+		}
+		if (strcmp(argv[0], "subnets") == 0) {
+			rc = bt_mesh_store_config_deserialize_arr(
+				val,
+				mesh_store_subs,
+				sizeof(struct bt_mesh_store_sub),
+				NULL);
+			return rc;
+		}
+		if (strcmp(argv[0], "app_keys") == 0) {
+			rc = bt_mesh_store_config_deserialize_arr(
+				val,
+				mesh_store_app_keys,
+				sizeof(struct bt_mesh_store_app_key),
+				NULL);
+			return rc;
+		}
+	}
+	return OS_ENOENT;
+}
+
+static int bt_mesh_store_config_conf_export(void (*func)(char *name, char *val),
+					    enum conf_export_tgt tgt)
+{
+	union {
+	    char net[BT_STORE_CONFIG_NET_ENCODE_SZ];
+	    char subs[BT_STORE_CONFIG_SUBNETS_ENCODE_SZ];
+	    char app_keys[BT_STORE_CONFIG_APP_KEYS_ENCODE_SZ];
+	} buf;
+
+	BT_DBG("");
+
+	bt_mesh_store_config_serialize_arr(&mesh_store_net,
+					   sizeof(struct bt_mesh_store_net),
+					   1,
+					   buf.net,
+					   sizeof(buf.net));
+	func("bt_mesh/net", buf.net);
+
+	bt_mesh_store_config_serialize_arr(&mesh_store_subs,
+					   sizeof(struct bt_mesh_store_sub),
+					   ARRAY_SIZE(mesh_store_subs),
+					   buf.subs,
+					   sizeof(buf.subs));
+	func("bt_mesh/subnets", buf.subs);
+
+	bt_mesh_store_config_serialize_arr(&mesh_store_app_keys,
+					   sizeof(struct bt_mesh_store_app_key),
+					   ARRAY_SIZE(mesh_store_app_keys),
+					   buf.app_keys,
+					   sizeof(buf.app_keys));
+	func("bt_mesh/app_keys", buf.app_keys);
+
+	return 0;
+}
+
+int bt_mesh_store_config_persist_net(void)
+{
+	char buf[BT_STORE_CONFIG_NET_ENCODE_SZ];
+	int rc;
+
+	bt_mesh_store_config_serialize_arr(&mesh_store_net,
+					   sizeof(struct bt_mesh_store_net),
+					   1, buf, sizeof(buf));
+	rc = conf_save_one("bt_mesh/net", buf);
+
+	BT_DBG("");
+
+	if (rc != 0) {
+		return rc;
+	}
+
+	return 0;
+}
+
+int bt_mesh_store_config_persist_subnets(void)
+{
+	char buf[BT_STORE_CONFIG_SUBNETS_ENCODE_SZ];
+	int rc;
+
+	bt_mesh_store_config_serialize_arr(mesh_store_subs,
+					   sizeof(struct bt_mesh_store_sub),
+					   ARRAY_SIZE(mesh_store_subs),
+					   buf, sizeof(buf));
+	rc = conf_save_one("bt_mesh/subnets", buf);
+
+	BT_DBG("");
+
+	if (rc != 0) {
+		return rc;
+	}
+
+	return 0;
+}
+
+int bt_mesh_store_config_persist_app_keys(void)
+{
+	char buf[BT_STORE_CONFIG_APP_KEYS_ENCODE_SZ];
+	int rc;
+
+	bt_mesh_store_config_serialize_arr(mesh_store_app_keys,
+					   sizeof(struct bt_mesh_store_app_keys),
+					   ARRAY_SIZE(mesh_store_app_keys),
+					   buf, sizeof(buf));
+	rc = conf_save_one("bt_mesh/app_keys", buf);
+
+	BT_DBG("");
+
+	if (rc != 0) {
+		return rc;
+	}
+
+	return 0;
+}
+
+void bt_mesh_store_config_init(void)
+{
+	int rc;
+
+	/* Ensure this function only gets called by sysinit. */
+	SYSINIT_ASSERT_ACTIVE();
+
+	rc = conf_register(&bt_mesh_store_config_conf_handler);
+	SYSINIT_PANIC_ASSERT_MSG(rc == 0,
+				 "Failed to register bt_mesh_store_config conf");
+
+	rc = conf_load();
+	SYSINIT_PANIC_ASSERT_MSG(rc == 0,
+				 "Failed to load config");
+}
+
+//#endif /* MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) */
diff --git a/nimble/host/mesh/src/store_config.h b/nimble/host/mesh/src/store_config.h
new file mode 100644
index 00000000..49d1225e
--- /dev/null
+++ b/nimble/host/mesh/src/store_config.h
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BT_MESH_STORE_CONFIG_PRIV_
+#define H_BT_MESH_STORE_CONFIG_PRIV_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#if MYNEWT_VAL(BT_MESH_STORE_CONFIG_PERSIST)
+
+void bt_mesh_store_config_init(void);
+int bt_mesh_store_config_persist_net(void);
+int bt_mesh_store_config_persist_subnets(void);
+int bt_mesh_store_config_persist_app_keys(void);
+
+//#else
+//
+//static inline int bt_mesh_store_config_persist_net(void)   { return 0; }
+//static inline void bt_mesh_store_config_init(void)         { }
+//
+//#endif /* MYNEWT_VAL(BT_MESH_STORE_CONFIG_PERSIST) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/nimble/host/mesh/src/testing.c b/nimble/host/mesh/src/testing.c
index bb35cff3..10a278fc 100644
--- a/nimble/host/mesh/src/testing.c
+++ b/nimble/host/mesh/src/testing.c
@@ -100,12 +100,12 @@ void bt_test_print_credentials(void)
 
 	for (i = 0; i < MYNEWT_VAL(BLE_MESH_SUBNET_COUNT); ++i)
 	{
-		if (bt_mesh.app_keys[i].net_idx == BT_MESH_KEY_UNUSED) {
+		sub = &bt_mesh.sub[i];
+
+		if (sub->net_idx == BT_MESH_KEY_UNUSED) {
 			continue;
 		}
 
-		sub = &bt_mesh.sub[i];
-
 		console_printf("Subnet: %d\n", i);
 		console_printf("\tNetKeyIdx: %04x\n",
 			       sub->net_idx);
diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c
index 918af1fe..ab93a728 100644
--- a/nimble/host/mesh/src/transport.c
+++ b/nimble/host/mesh/src/transport.c
@@ -176,13 +176,13 @@ static void seg_tx_reset(struct seg_tx *tx)
 
 	tx->nack_count = 0;
 
-	if (bt_mesh.pending_update) {
+	if (bt_mesh_net_get_pending_update()) {
 		BT_DBG("Proceding with pending IV Update");
-		bt_mesh.pending_update = 0;
+		bt_mesh_net_set_pending_update(false);
 		/* bt_mesh_net_iv_update() will re-enable the flag if this
 		 * wasn't the only transfer.
 		 */
-		if (bt_mesh_net_iv_update(bt_mesh.iv_index, false)) {
+		if (bt_mesh_net_iv_update(bt_mesh_net_get_iv_index(NULL), false)) {
 			bt_mesh_net_sec_update(NULL);
 		}
 	}
@@ -322,7 +322,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct os_mbuf *sdu,
 	tx->dst = net_tx->ctx->addr;
 	tx->seg_n = (sdu->om_len - 1) / 12;
 	tx->nack_count = tx->seg_n + 1;
-	tx->seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_TX, bt_mesh.seq);
+	tx->seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_TX, bt_mesh_net_get_sequence_number());
 	tx->sub = net_tx->sub;
 	tx->new_key = net_tx->sub->kr_flag;
 	tx->cb = cb;
@@ -480,7 +480,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg,
 
 	err = bt_mesh_app_encrypt(key, tx->ctx->app_idx == BT_MESH_KEY_DEV,
 				  tx->aszmic, msg, ad, tx->src,
-				  tx->ctx->addr, bt_mesh.seq,
+				  tx->ctx->addr, bt_mesh_net_get_sequence_number(),
 				  BT_MESH_NET_IVI_TX);
 	if (err) {
 		return err;


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services