linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org
@ 2019-07-14 23:23 Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 01/10 v3] mesh: Move network config setup from storage.c to node.c Inga Stotland
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

+ rebase off the tip

This set of patches introduces the notion of generic mesh-config API
that allows the daemon to be agnostic of the underlying node configuration
directory layout and the format of the file(s) in which node configuration
is saved. 

Currently, the daemon supports only JSON-based configuration format.
It is expected that other configuration formats may be added in future.

As a result of these changes, storage.c and storage.h are obsolete
and are removed.

Inga Stotland (10):
  mesh: Move network config setup from storage.c to node.c
  mesh: Rename mesh-db.c to mesh-config-json.c
  mesh: Change mesh_db prefix to mesh_config
  mesh: Move load from storage functionality into node.c
  mesh: Confine dependency on json-c to mesh-config-json.c
  mesh: Replace storage_save_config with mesh_config_save_config
  mesh: Use mesh_config APIs to store node configuration
  mesh: Manage node config directory in mesh-config
  mesh: Create or re-use a node storage directory for keyring
  mesh: Rename mesh_config_srv_init() to cfgmod_server_init()

 Makefile.mesh                          |    3 +-
 mesh/appkey.c                          |   19 +-
 mesh/cfgmod-server.c                   |   31 +-
 mesh/cfgmod.h                          |    2 +-
 mesh/keyring.c                         |   36 +-
 mesh/{mesh-db.c => mesh-config-json.c} | 1071 +++++++++++++++++-------
 mesh/mesh-config.h                     |  172 ++++
 mesh/mesh-db.h                         |  157 ----
 mesh/mesh.c                            |   15 +-
 mesh/mesh.h                            |    1 +
 mesh/model.c                           |   23 +-
 mesh/net.c                             |   26 +-
 mesh/node.c                            |  224 +++--
 mesh/node.h                            |   13 +-
 mesh/storage.c                         |  656 ---------------
 mesh/storage.h                         |   51 --
 mesh/util.c                            |   39 +-
 mesh/util.h                            |    1 +
 18 files changed, 1219 insertions(+), 1321 deletions(-)
 rename mesh/{mesh-db.c => mesh-config-json.c} (58%)
 create mode 100644 mesh/mesh-config.h
 delete mode 100644 mesh/mesh-db.h
 delete mode 100644 mesh/storage.c
 delete mode 100644 mesh/storage.h

-- 
2.21.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 01/10 v3] mesh: Move network config setup from storage.c to node.c
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 02/10 v3] mesh: Rename mesh-db.c to mesh-config-json.c Inga Stotland
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This commit moves initialization of configuration parameters
for node->net when the local node state is restored from stored
configuration. Old location: storage.c, new locaiton node.c.
---
 mesh/node.c    | 28 ++++++++++++++++++++++++++++
 mesh/storage.c | 39 ---------------------------------------
 2 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/mesh/node.c b/mesh/node.c
index 27235ef34..dc9781482 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -376,6 +376,7 @@ bool node_init_from_storage(struct mesh_node *node, void *data)
 {
 	struct mesh_db_node *db_node = data;
 	unsigned int num_ele;
+	uint8_t mode;
 
 	node->comp = l_new(struct node_composition, 1);
 	node->comp->cid = db_node->cid;
@@ -408,6 +409,33 @@ bool node_init_from_storage(struct mesh_node *node, void *data)
 
 	node->primary = db_node->unicast;
 
+	mesh_net_set_seq_num(node->net, node->seq_number);
+	mesh_net_set_default_ttl(node->net, node->ttl);
+
+	mode = node->proxy;
+	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
+		mesh_net_set_proxy_mode(node->net, mode == MESH_MODE_ENABLED);
+
+	mode = node->lpn;
+	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
+		mesh_net_set_friend_mode(node->net, mode == MESH_MODE_ENABLED);
+
+	mode = node->relay.mode;
+	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
+		mesh_net_set_relay_mode(node->net, mode == MESH_MODE_ENABLED,
+					node->relay.cnt, node->relay.interval);
+
+	mode = node->beacon;
+	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
+		mesh_net_set_beacon_mode(node->net, mode == MESH_MODE_ENABLED);
+
+	if (!IS_UNASSIGNED(node->primary) &&
+		!mesh_net_register_unicast(node->net, node->primary, num_ele))
+		return false;
+
+	if (node->uuid)
+		mesh_net_id_uuid_set(node->net, node->uuid);
+
 	/* Initialize configuration server model */
 	mesh_config_srv_init(node, PRIMARY_ELE_IDX);
 
diff --git a/mesh/storage.c b/mesh/storage.c
index 0f2b77fde..2b7804242 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -56,51 +56,12 @@ static const char *storage_dir;
 static bool read_node_cb(struct mesh_db_node *db_node, void *user_data)
 {
 	struct mesh_node *node = user_data;
-	struct mesh_net *net;
-	uint32_t seq_number;
-	uint8_t ttl, mode, cnt, num_ele;
-	uint16_t unicast, interval;
-	uint8_t *uuid;
 
 	if (!node_init_from_storage(node, db_node)) {
 		node_remove(node);
 		return false;
 	}
 
-	net = node_get_net(node);
-	seq_number = node_get_sequence_number(node);
-	mesh_net_set_seq_num(net, seq_number);
-	ttl = node_default_ttl_get(node);
-	mesh_net_set_default_ttl(net, ttl);
-
-	mode = node_proxy_mode_get(node);
-	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
-		mesh_net_set_proxy_mode(net, mode == MESH_MODE_ENABLED);
-
-	mode = node_friend_mode_get(node);
-	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
-		mesh_net_set_friend_mode(net, mode == MESH_MODE_ENABLED);
-
-	mode = node_relay_mode_get(node, &cnt, &interval);
-	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
-		mesh_net_set_relay_mode(net, mode == MESH_MODE_ENABLED, cnt,
-								interval);
-
-	mode = node_beacon_mode_get(node);
-	if (mode == MESH_MODE_ENABLED || mode == MESH_MODE_DISABLED)
-		mesh_net_set_beacon_mode(net, mode == MESH_MODE_ENABLED);
-
-	unicast = db_node->unicast;
-	num_ele = node_get_num_elements(node);
-
-	if (!IS_UNASSIGNED(unicast) &&
-		!mesh_net_register_unicast(net, unicast, num_ele))
-		return false;
-
-	uuid = node_uuid_get(node);
-	if (uuid)
-		mesh_net_id_uuid_set(net, uuid);
-
 	return true;
 }
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 02/10 v3] mesh: Rename mesh-db.c to mesh-config-json.c
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 01/10 v3] mesh: Move network config setup from storage.c to node.c Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 03/10 v3] mesh: Change mesh_db prefix to mesh_config Inga Stotland
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This moves mesh-db.h to mesh-config.h and mesh-db.c to mesh-config-json.c.
mesh-config.h declares common APIs for storing mesh node configuration.
mesh-config-json.c defines the APIs for JSOn specific storage.
This allows for future parallel implementation a different (not JSON-based)
mechanism of storing node configuration.
---
 Makefile.mesh                          | 2 +-
 mesh/cfgmod-server.c                   | 3 +--
 mesh/{mesh-db.c => mesh-config-json.c} | 3 +--
 mesh/{mesh-db.h => mesh-config.h}      | 0
 mesh/model.c                           | 2 +-
 mesh/node.c                            | 2 +-
 mesh/storage.c                         | 3 +--
 7 files changed, 6 insertions(+), 9 deletions(-)
 rename mesh/{mesh-db.c => mesh-config-json.c} (99%)
 rename mesh/{mesh-db.h => mesh-config.h} (100%)

diff --git a/Makefile.mesh b/Makefile.mesh
index 1ace507af..502ba2a47 100644
--- a/Makefile.mesh
+++ b/Makefile.mesh
@@ -25,7 +25,7 @@ mesh_sources = mesh/mesh.h mesh/mesh.c \
 				mesh/provision.h mesh/prov.h \
 				mesh/model.h mesh/model.c \
 				mesh/cfgmod.h mesh/cfgmod-server.c \
-				mesh/mesh-db.h mesh/mesh-db.c \
+				mesh/mesh-config.h mesh/mesh-config-json.c \
 				mesh/util.h mesh/util.c \
 				mesh/dbus.h mesh/dbus.c \
 				mesh/agent.h mesh/agent.c \
diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index a19ddc72e..486c87307 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -32,8 +32,7 @@
 #include "mesh/appkey.h"
 #include "mesh/model.h"
 #include "mesh/storage.h"
-#include "mesh/mesh-db.h"
-
+#include "mesh/mesh-config.h"
 #include "mesh/cfgmod.h"
 
 #define CFG_MAX_MSG_LEN 380
diff --git a/mesh/mesh-db.c b/mesh/mesh-config-json.c
similarity index 99%
rename from mesh/mesh-db.c
rename to mesh/mesh-config-json.c
index e0a000261..35d0bd27e 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-config-json.c
@@ -31,8 +31,7 @@
 
 #include "mesh/mesh-defs.h"
 #include "mesh/util.h"
-
-#include "mesh/mesh-db.h"
+#include "mesh/mesh-config.h"
 
 #define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095))
 
diff --git a/mesh/mesh-db.h b/mesh/mesh-config.h
similarity index 100%
rename from mesh/mesh-db.h
rename to mesh/mesh-config.h
diff --git a/mesh/model.c b/mesh/model.c
index e08f95b71..0474762e0 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -30,7 +30,7 @@
 #include "mesh/mesh.h"
 #include "mesh/crypto.h"
 #include "mesh/node.h"
-#include "mesh/mesh-db.h"
+#include "mesh/mesh-config.h"
 #include "mesh/net.h"
 #include "mesh/appkey.h"
 #include "mesh/cfgmod.h"
diff --git a/mesh/node.c b/mesh/node.c
index dc9781482..51cf4cda8 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -31,7 +31,7 @@
 #include "mesh/mesh-defs.h"
 #include "mesh/mesh.h"
 #include "mesh/net.h"
-#include "mesh/mesh-db.h"
+#include "mesh/mesh-config.h"
 #include "mesh/provision.h"
 #include "mesh/storage.h"
 #include "mesh/keyring.h"
diff --git a/mesh/storage.c b/mesh/storage.c
index 2b7804242..bba2ef348 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -22,7 +22,6 @@
 #endif
 
 #define _GNU_SOURCE
-//#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -37,7 +36,7 @@
 #include "mesh/node.h"
 #include "mesh/net.h"
 #include "mesh/appkey.h"
-#include "mesh/mesh-db.h"
+#include "mesh/mesh-config.h"
 #include "mesh/util.h"
 #include "mesh/storage.h"
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 03/10 v3] mesh: Change mesh_db prefix to mesh_config
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 01/10 v3] mesh: Move network config setup from storage.c to node.c Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 02/10 v3] mesh: Rename mesh-db.c to mesh-config-json.c Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 04/10 v3] mesh: Move load from storage functionality into node.c Inga Stotland
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This changes the naming the API declarations in mesh-config.h:
mesh_db_... ->mesh_config_...
---
 mesh/cfgmod-server.c    |  20 ++--
 mesh/mesh-config-json.c | 213 +++++++++++++++++++++-------------------
 mesh/mesh-config.h      | 122 ++++++++++++-----------
 mesh/model.c            |   4 +-
 mesh/node.c             |  36 +++----
 mesh/storage.c          |  54 +++++-----
 6 files changed, 234 insertions(+), 215 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index 486c87307..0479a9185 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -197,14 +197,14 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 
 		/* Remove model publication from config file */
 		if (status == MESH_STATUS_SUCCESS)
-			mesh_db_model_pub_del(node_jconfig_get(node), ele_addr,
-					vendor ? mod_id : mod_id & 0x0000ffff,
-					vendor);
+			mesh_config_model_pub_del(node_jconfig_get(node),
+				ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
+									vendor);
 		goto done;
 	}
 
 	if (status == MESH_STATUS_SUCCESS) {
-		struct mesh_db_pub db_pub = {
+		struct mesh_config_pub db_pub = {
 			.virt = b_virt,
 			.addr = ota,
 			.idx = idx,
@@ -219,7 +219,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 			memcpy(db_pub.virt_addr, pub_addr, 16);
 
 		/* Save model publication to config file */
-		if (!mesh_db_model_pub_add(node_jconfig_get(node), ele_addr,
+		if (!mesh_config_model_pub_add(node_jconfig_get(node), ele_addr,
 					vendor ? mod_id : mod_id & 0x0000ffff,
 					vendor, &db_pub))
 			status = MESH_STATUS_STORAGE_FAIL;
@@ -321,7 +321,7 @@ static bool save_config_sub(struct mesh_node *node, uint16_t ele_addr,
 					const uint8_t *addr, bool virt,
 					uint16_t grp, uint32_t opcode)
 {
-	struct mesh_db_sub db_sub = {
+	struct mesh_config_sub db_sub = {
 				.virt = virt,
 				.src.addr = grp
 				};
@@ -331,18 +331,18 @@ static bool save_config_sub(struct mesh_node *node, uint16_t ele_addr,
 
 	if (opcode == OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE ||
 					opcode == OP_CONFIG_MODEL_SUB_OVERWRITE)
-		mesh_db_model_sub_del_all(node_jconfig_get(node),
+		mesh_config_model_sub_del_all(node_jconfig_get(node),
 				ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
 									vendor);
 
 	if (opcode != OP_CONFIG_MODEL_SUB_VIRT_DELETE &&
 			opcode != OP_CONFIG_MODEL_SUB_DELETE)
-		return mesh_db_model_sub_add(node_jconfig_get(node),
+		return mesh_config_model_sub_add(node_jconfig_get(node),
 					ele_addr,
 					vendor ? mod_id : mod_id & 0x0000ffff,
 					vendor, &db_sub);
 	else
-		return mesh_db_model_sub_del(node_jconfig_get(node),
+		return mesh_config_model_sub_del(node_jconfig_get(node),
 					ele_addr,
 					vendor ? mod_id : mod_id & 0x0000ffff,
 					vendor, &db_sub);
@@ -419,7 +419,7 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 		status = mesh_model_sub_del_all(node, ele_addr, mod_id);
 
 		if (status == MESH_STATUS_SUCCESS)
-			mesh_db_model_sub_del_all(node_jconfig_get(node),
+			mesh_config_model_sub_del_all(node_jconfig_get(node),
 				ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
 									vendor);
 		break;
diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c
index 35d0bd27e..8fcb8afe3 100644
--- a/mesh/mesh-config-json.c
+++ b/mesh/mesh-config-json.c
@@ -252,7 +252,7 @@ static json_object *jarray_key_del(json_object *jarray, int16_t idx)
 	return jarray_new;
 }
 
-bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
+bool mesh_config_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
 {
 	int tmp;
 
@@ -270,7 +270,7 @@ bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
 	return true;
 }
 
-bool mesh_db_read_token(json_object *jobj, uint8_t token[8])
+bool mesh_config_read_token(json_object *jobj, uint8_t token[8])
 {
 	json_object *jvalue;
 	char *str;
@@ -288,7 +288,7 @@ bool mesh_db_read_token(json_object *jobj, uint8_t token[8])
 	return true;
 }
 
-bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16])
+bool mesh_config_read_device_key(json_object *jobj, uint8_t key_buf[16])
 {
 	json_object *jvalue;
 	char *str;
@@ -306,7 +306,7 @@ bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16])
 	return true;
 }
 
-bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
+bool mesh_config_read_app_keys(json_object *jobj, mesh_config_app_key_cb cb,
 							void *user_data)
 {
 	json_object *jarray;
@@ -368,7 +368,7 @@ bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
 	return true;
 }
 
-bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
+bool mesh_config_read_net_keys(json_object *jobj, mesh_config_net_key_cb cb,
 								void *user_data)
 {
 	json_object *jarray;
@@ -431,7 +431,7 @@ bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
 	return true;
 }
 
-bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
+bool mesh_config_net_key_add(json_object *jobj, uint16_t idx,
 							const uint8_t key[16])
 {
 	json_object *jarray = NULL, *jentry = NULL, *jstring;
@@ -479,7 +479,7 @@ fail:
 	return false;
 }
 
-bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
+bool mesh_config_net_key_update(json_object *jobj, uint16_t idx,
 							const uint8_t key[16])
 {
 	json_object *jarray, *jentry, *jstring;
@@ -510,7 +510,7 @@ bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
 	return true;
 }
 
-bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
+bool mesh_config_net_key_del(json_object *jobj, uint16_t idx)
 {
 	json_object *jarray, *jarray_new;
 
@@ -541,18 +541,18 @@ bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
 	return true;
 }
 
-bool mesh_db_write_device_key(json_object *jnode, uint8_t *key)
+bool mesh_config_write_device_key(json_object *jnode, uint8_t *key)
 {
 	return add_key_value(jnode, "deviceKey", key);
 }
 
-bool mesh_db_write_token(json_object *jnode, uint8_t *token)
+bool mesh_config_write_token(json_object *jnode, uint8_t *token)
 {
 	return add_u64_value(jnode, "token", token);
 }
 
-bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
-							const uint8_t key[16])
+bool mesh_config_app_key_add(json_object *jobj, uint16_t net_idx,
+					uint16_t app_idx, const uint8_t key[16])
 {
 	json_object *jarray = NULL, *jentry = NULL, *jstring = NULL;
 	char buf[5];
@@ -604,7 +604,7 @@ fail:
 	return false;
 }
 
-bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
+bool mesh_config_app_key_update(json_object *jobj, uint16_t app_idx,
 							const uint8_t key[16])
 {
 	json_object *jarray, *jentry = NULL, *jstring = NULL;
@@ -629,7 +629,7 @@ bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
 	return add_key_value(jentry, "key", key);
 }
 
-bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
+bool mesh_config_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
 {
 	json_object *jarray, *jarray_new;
 
@@ -660,8 +660,9 @@ bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
 	return true;
 }
 
-bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
-				uint32_t mod_id, uint16_t app_idx)
+bool mesh_config_model_binding_add(json_object *jnode, uint8_t ele_idx,
+					bool vendor, uint32_t mod_id,
+							uint16_t app_idx)
 {
 	json_object *jmodel, *jstring, *jarray = NULL;
 	char buf[5];
@@ -694,8 +695,9 @@ bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
 	return true;
 }
 
-bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
-				uint32_t mod_id, uint16_t app_idx)
+bool mesh_config_model_binding_del(json_object *jnode, uint8_t ele_idx,
+					bool vendor, uint32_t mod_id,
+							uint16_t app_idx)
 {
 	json_object *jmodel, *jarray, *jarray_new;
 	char buf[5];
@@ -734,7 +736,7 @@ bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
 
 static void free_model(void *data)
 {
-	struct mesh_db_model *mod = data;
+	struct mesh_config_model *mod = data;
 
 	l_free(mod->bindings);
 	l_free(mod->subs);
@@ -744,18 +746,18 @@ static void free_model(void *data)
 
 static void free_element(void *data)
 {
-	struct mesh_db_element *ele = data;
+	struct mesh_config_element *ele = data;
 
 	l_queue_destroy(ele->models, free_model);
 	l_free(ele);
 }
 
-static bool parse_bindings(json_object *jbindings, struct mesh_db_model *mod)
+static bool parse_bindings(json_object *jarray, struct mesh_config_model *mod)
 {
 	int cnt;
 	int i;
 
-	cnt = json_object_array_length(jbindings);
+	cnt = json_object_array_length(jarray);
 	if (cnt > 0xffff)
 		return false;
 
@@ -771,7 +773,7 @@ static bool parse_bindings(json_object *jbindings, struct mesh_db_model *mod)
 		int idx;
 		json_object *jvalue;
 
-		jvalue = json_object_array_get_idx(jbindings, i);
+		jvalue = json_object_array_get_idx(jarray, i);
 		if (!jvalue)
 			return false;
 
@@ -800,10 +802,10 @@ static bool get_key_index(json_object *jobj, const char *keyword,
 	return true;
 }
 
-static struct mesh_db_pub *parse_model_publication(json_object *jpub)
+static struct mesh_config_pub *parse_model_publication(json_object *jpub)
 {
 	json_object *jvalue;
-	struct mesh_db_pub *pub;
+	struct mesh_config_pub *pub;
 	int len, value;
 	char *str;
 
@@ -812,7 +814,7 @@ static struct mesh_db_pub *parse_model_publication(json_object *jpub)
 
 	str = (char *)json_object_get_string(jvalue);
 	len = strlen(str);
-	pub = l_new(struct mesh_db_pub, 1);
+	pub = l_new(struct mesh_config_pub, 1);
 
 	switch (len) {
 	case 4:
@@ -862,9 +864,9 @@ fail:
 }
 
 static bool parse_model_subscriptions(json_object *jsubs,
-						struct mesh_db_model *mod)
+						struct mesh_config_model *mod)
 {
-	struct mesh_db_sub *subs;
+	struct mesh_config_sub *subs;
 	int i, cnt;
 
 	if (json_object_get_type(jsubs) != json_type_array)
@@ -875,7 +877,7 @@ static bool parse_model_subscriptions(json_object *jsubs,
 	if (!cnt)
 		return true;
 
-	subs = l_new(struct mesh_db_sub, cnt);
+	subs = l_new(struct mesh_config_sub, cnt);
 
 	for (i = 0; i < cnt; ++i) {
 		char *str;
@@ -913,7 +915,7 @@ fail:
 	return false;
 }
 
-static bool parse_models(json_object *jmodels, struct mesh_db_element *ele)
+static bool parse_models(json_object *jmodels, struct mesh_config_element *ele)
 {
 	int i, num_models;
 
@@ -923,7 +925,7 @@ static bool parse_models(json_object *jmodels, struct mesh_db_element *ele)
 
 	for (i = 0; i < num_models; ++i) {
 		json_object *jmodel, *jarray, *jvalue;
-		struct mesh_db_model *mod;
+		struct mesh_config_model *mod;
 		uint32_t id;
 		int len;
 		char *str;
@@ -932,7 +934,7 @@ static bool parse_models(json_object *jmodels, struct mesh_db_element *ele)
 		if (!jmodel)
 			goto fail;
 
-		mod = l_new(struct mesh_db_model, 1);
+		mod = l_new(struct mesh_config_model, 1);
 
 		if (!json_object_object_get_ex(jmodel, "modelId", &jvalue))
 			goto fail;
@@ -987,14 +989,14 @@ fail:
 	return false;
 }
 
-static bool parse_elements(json_object *jelements, struct mesh_db_node *node)
+static bool parse_elements(json_object *jelems, struct mesh_config_node *node)
 {
 	int i, num_ele;
 
-	if (json_object_get_type(jelements) != json_type_array)
+	if (json_object_get_type(jelems) != json_type_array)
 		return false;
 
-	num_ele = json_object_array_length(jelements);
+	num_ele = json_object_array_length(jelems);
 	if (!num_ele)
 		/* Allow "empty" nodes */
 		return true;
@@ -1005,11 +1007,11 @@ static bool parse_elements(json_object *jelements, struct mesh_db_node *node)
 		json_object *jelement;
 		json_object *jmodels;
 		json_object *jvalue;
-		struct mesh_db_element *ele;
+		struct mesh_config_element *ele;
 		int index;
 		char *str;
 
-		jelement = json_object_array_get_idx(jelements, i);
+		jelement = json_object_array_get_idx(jelems, i);
 		if (!jelement)
 			goto fail;
 
@@ -1017,7 +1019,7 @@ static bool parse_elements(json_object *jelements, struct mesh_db_node *node)
 								index > num_ele)
 			goto fail;
 
-		ele = l_new(struct mesh_db_element, 1);
+		ele = l_new(struct mesh_config_element, 1);
 		ele->index = index;
 		ele->models = l_queue_new();
 
@@ -1066,7 +1068,7 @@ static int get_mode(json_object *jvalue)
 	return 0xffffffff;
 }
 
-static void parse_features(json_object *jconfig, struct mesh_db_node *node)
+static void parse_features(json_object *jconfig, struct mesh_config_node *node)
 {
 	json_object *jvalue, *jrelay;
 	int mode, count;
@@ -1123,7 +1125,7 @@ static void parse_features(json_object *jconfig, struct mesh_db_node *node)
 	node->modes.relay.interval = interval;
 }
 
-static bool parse_composition(json_object *jcomp, struct mesh_db_node *node)
+static bool parse_composition(json_object *jcomp, struct mesh_config_node *node)
 {
 	json_object *jvalue;
 	char *str;
@@ -1160,9 +1162,10 @@ static bool parse_composition(json_object *jcomp, struct mesh_db_node *node)
 	return true;
 }
 
-bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
+bool mesh_config_read_node(json_object *jnode, mesh_config_node_cb cb,
+							void *user_data)
 {
-	struct mesh_db_node node;
+	struct mesh_config_node node;
 	json_object *jvalue;
 	char *str;
 
@@ -1213,7 +1216,7 @@ bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
 	return cb(&node, user_data);
 }
 
-bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
+bool mesh_config_write_uint16_hex(json_object *jobj, const char *desc,
 								uint16_t value)
 {
 	json_object *jstring;
@@ -1231,7 +1234,7 @@ bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
 	return true;
 }
 
-bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
+bool mesh_config_write_uint32_hex(json_object *jobj, const char *desc,
 								uint32_t value)
 {
 	json_object *jstring;
@@ -1249,7 +1252,7 @@ bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
 	return true;
 }
 
-bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
+bool mesh_config_write_int(json_object *jobj, const char *keyword, int value)
 {
 	json_object *jvalue;
 
@@ -1266,7 +1269,7 @@ bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
 	return true;
 }
 
-bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value)
+bool mesh_config_write_bool(json_object *jobj, const char *keyword, bool value)
 {
 	json_object *jvalue;
 
@@ -1295,7 +1298,7 @@ static const char *mode_to_string(int mode)
 	}
 }
 
-bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
+bool mesh_config_write_mode(json_object *jobj, const char *keyword, int value)
 {
 	json_object *jstring;
 
@@ -1312,8 +1315,8 @@ bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
 	return true;
 }
 
-bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
-							uint16_t interval)
+bool mesh_config_write_relay_mode(json_object *jnode, uint8_t mode,
+					uint8_t count, uint16_t interval)
 {
 	json_object *jrelay;
 
@@ -1326,13 +1329,13 @@ bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
 	if (!jrelay)
 		return false;
 
-	if (!mesh_db_write_mode(jrelay, "mode", mode))
+	if (!mesh_config_write_mode(jrelay, "mode", mode))
 		goto fail;
 
-	if (!mesh_db_write_int(jrelay, "count", count))
+	if (!mesh_config_write_int(jrelay, "count", count))
 		goto fail;
 
-	if (!mesh_db_write_int(jrelay, "interval", interval))
+	if (!mesh_config_write_int(jrelay, "interval", interval))
 		goto fail;
 
 	json_object_object_add(jnode, "relay", jrelay);
@@ -1343,7 +1346,7 @@ fail:
 	return false;
 }
 
-bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
+bool mesh_config_read_net_transmit(json_object *jobj, uint8_t *cnt,
 							uint16_t *interval)
 {
 	json_object *jretransmit, *jvalue;
@@ -1367,7 +1370,7 @@ bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
 	return true;
 }
 
-bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
+bool mesh_config_write_net_transmit(json_object *jobj, uint8_t cnt,
 							uint16_t interval)
 {
 	json_object *jretransmit;
@@ -1381,10 +1384,10 @@ bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
 	if (jretransmit)
 		return false;
 
-	if (!mesh_db_write_int(jretransmit, "count", cnt))
+	if (!mesh_config_write_int(jretransmit, "count", cnt))
 		goto fail;
 
-	if (!mesh_db_write_int(jretransmit, "interval", interval))
+	if (!mesh_config_write_int(jretransmit, "interval", interval))
 		goto fail;
 
 	json_object_object_add(jobj, "retransmit", jretransmit);
@@ -1396,23 +1399,23 @@ fail:
 
 }
 
-bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
+bool mesh_config_write_iv_index(json_object *jobj, uint32_t idx, bool update)
 {
 	int tmp = update ? 1 : 0;
 
 	if (!jobj)
 		return false;
 
-	if (!mesh_db_write_int(jobj, "IVindex", idx))
+	if (!mesh_config_write_int(jobj, "IVindex", idx))
 		return false;
 
-	if (!mesh_db_write_int(jobj, "IVupdate", tmp))
+	if (!mesh_config_write_int(jobj, "IVupdate", tmp))
 		return false;
 
 	return true;
 }
 
-void mesh_db_remove_property(json_object *jobj, const char *desc)
+void mesh_config_remove_property(json_object *jobj, const char *desc)
 {
 	if (jobj)
 		json_object_object_del(jobj, desc);
@@ -1420,7 +1423,7 @@ void mesh_db_remove_property(json_object *jobj, const char *desc)
 
 static void add_model(void *a, void *b)
 {
-	struct mesh_db_model *mod = a;
+	struct mesh_config_model *mod = a;
 	json_object *jmodels = b, *jmodel;
 
 	jmodel = json_object_new_object();
@@ -1428,54 +1431,54 @@ static void add_model(void *a, void *b)
 		return;
 
 	if (!mod->vendor)
-		mesh_db_write_uint16_hex(jmodel, "modelId",
+		mesh_config_write_uint16_hex(jmodel, "modelId",
 						(uint16_t) mod->id);
 	else
-		mesh_db_write_uint32_hex(jmodel, "modelId", mod->id);
+		mesh_config_write_uint32_hex(jmodel, "modelId", mod->id);
 
 	json_object_array_add(jmodels, jmodel);
 }
 
 /* Add unprovisioned node (local) */
-bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
-
-	struct mesh_db_modes *modes = &node->modes;
+bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node)
+{
+	struct mesh_config_modes *modes = &node->modes;
 	const struct l_queue_entry *entry;
-	json_object *jelements;
+	json_object *jelems;
 
 	if (!jnode)
 		return false;
 
 	/* CID, PID, VID, crpl */
-	if (!mesh_db_write_uint16_hex(jnode, "cid", node->cid))
+	if (!mesh_config_write_uint16_hex(jnode, "cid", node->cid))
 		return false;
 
-	if (!mesh_db_write_uint16_hex(jnode, "pid", node->pid))
+	if (!mesh_config_write_uint16_hex(jnode, "pid", node->pid))
 		return false;
 
-	if (!mesh_db_write_uint16_hex(jnode, "vid", node->vid))
+	if (!mesh_config_write_uint16_hex(jnode, "vid", node->vid))
 		return false;
 
-	if (!mesh_db_write_uint16_hex(jnode, "crpl", node->crpl))
+	if (!mesh_config_write_uint16_hex(jnode, "crpl", node->crpl))
 		return false;
 
 	/* Features: relay, LPN, friend, proxy*/
-	if (!mesh_db_write_relay_mode(jnode, modes->relay.state,
+	if (!mesh_config_write_relay_mode(jnode, modes->relay.state,
 						modes->relay.cnt,
 						modes->relay.interval))
 		return false;
 
-	if (!mesh_db_write_mode(jnode, "lowPower", modes->lpn))
+	if (!mesh_config_write_mode(jnode, "lowPower", modes->lpn))
 		return false;
 
-	if (!mesh_db_write_mode(jnode, "friend", modes->friend))
+	if (!mesh_config_write_mode(jnode, "friend", modes->friend))
 		return false;
 
-	if (!mesh_db_write_mode(jnode, "proxy", modes->proxy))
+	if (!mesh_config_write_mode(jnode, "proxy", modes->proxy))
 		return false;
 
 	/* Beaconing state */
-	if (!mesh_db_write_mode(jnode, "beacon", modes->beacon))
+	if (!mesh_config_write_mode(jnode, "beacon", modes->beacon))
 		return false;
 
 	/* Sequence number */
@@ -1487,26 +1490,27 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
 						json_object_new_int(node->ttl));
 
 	/* Elements */
-	jelements = json_object_new_array();
-	if (!jelements)
+	jelems = json_object_new_array();
+	if (!jelems)
 		return false;
 
 	entry = l_queue_get_entries(node->elements);
 
 	for (; entry; entry = entry->next) {
-		struct mesh_db_element *ele = entry->data;
+		struct mesh_config_element *ele = entry->data;
 		json_object *jelement, *jmodels;
 
 		jelement = json_object_new_object();
 
 		if (!jelement) {
-			json_object_put(jelements);
+			json_object_put(jelems);
 			return false;
 		}
 
-		mesh_db_write_int(jelement, "elementIndex", ele->index);
-		mesh_db_write_uint16_hex(jelement, "location", ele->location);
-		json_object_array_add(jelements, jelement);
+		mesh_config_write_int(jelement, "elementIndex", ele->index);
+		mesh_config_write_uint16_hex(jelement, "location",
+								ele->location);
+		json_object_array_add(jelems, jelement);
 
 		/* Models */
 		if (l_queue_isempty(ele->models))
@@ -1514,7 +1518,7 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
 
 		jmodels = json_object_new_array();
 		if (!jmodels) {
-			json_object_put(jelements);
+			json_object_put(jelems);
 			return false;
 		}
 
@@ -1522,7 +1526,7 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
 		l_queue_foreach(ele->models, add_model, jmodels);
 	}
 
-	json_object_object_add(jnode, "elements", jelements);
+	json_object_object_add(jnode, "elements", jelems);
 
 	return true;
 }
@@ -1558,7 +1562,8 @@ static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
 
 }
 
-bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
+bool mesh_config_net_key_set_phase(json_object *jobj, uint16_t idx,
+								uint8_t phase)
 {
 	json_object *jarray, *jentry = NULL;
 
@@ -1583,8 +1588,9 @@ bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
 	return true;
 }
 
-bool mesh_db_model_pub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
-					bool vendor, struct mesh_db_pub *pub)
+bool mesh_config_model_pub_add(json_object *jnode, uint16_t addr,
+					uint32_t mod_id, bool vendor,
+					struct mesh_config_pub *pub)
 {
 	json_object *jmodel, *jpub, *jretransmit;
 	bool res;
@@ -1610,31 +1616,32 @@ bool mesh_db_model_pub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
 	if (pub->virt)
 		res = add_key_value(jpub, "address", pub->virt_addr);
 	else
-		res = mesh_db_write_uint16_hex(jpub, "address", pub->addr);
+		res = mesh_config_write_uint16_hex(jpub, "address", pub->addr);
 
 	if (!res)
 		goto fail;
 
-	if (!mesh_db_write_uint16_hex(jpub, "index", pub->idx))
+	if (!mesh_config_write_uint16_hex(jpub, "index", pub->idx))
 		goto fail;
 
-	if (!mesh_db_write_int(jpub, "ttl", pub->ttl))
+	if (!mesh_config_write_int(jpub, "ttl", pub->ttl))
 		goto fail;
 
-	if (!mesh_db_write_int(jpub, "period", pub->period))
+	if (!mesh_config_write_int(jpub, "period", pub->period))
 		goto fail;
 
-	if (!mesh_db_write_int(jpub, "credentials", pub->credential ? 1 : 0))
+	if (!mesh_config_write_int(jpub, "credentials",
+						pub->credential ? 1 : 0))
 		goto fail;
 
 	jretransmit = json_object_new_object();
 	if (!jretransmit)
 		goto fail;
 
-	if (!mesh_db_write_int(jretransmit, "count", pub->count))
+	if (!mesh_config_write_int(jretransmit, "count", pub->count))
 		goto fail;
 
-	if (!mesh_db_write_int(jretransmit, "interval", pub->interval))
+	if (!mesh_config_write_int(jretransmit, "interval", pub->interval))
 		goto fail;
 
 	json_object_object_add(jpub, "retransmit", jretransmit);
@@ -1665,8 +1672,8 @@ static bool delete_model_property(json_object *jnode, uint16_t addr,
 	return true;
 }
 
-bool mesh_db_model_pub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
-								bool vendor)
+bool mesh_config_model_pub_del(json_object *jnode, uint16_t addr,
+						uint32_t mod_id, bool vendor)
 {
 	if (!jnode)
 		return false;
@@ -1674,8 +1681,9 @@ bool mesh_db_model_pub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
 	return delete_model_property(jnode, addr, mod_id, vendor, "publish");
 }
 
-bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
-					bool vendor, struct mesh_db_sub *sub)
+bool mesh_config_model_sub_add(json_object *jnode, uint16_t addr,
+						uint32_t mod_id, bool vendor,
+						struct mesh_config_sub *sub)
 {
 	json_object *jmodel, *jstring, *jarray = NULL;
 	int ele_idx, len;
@@ -1722,8 +1730,9 @@ bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
 	return true;
 }
 
-bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr,
-			uint32_t mod_id, bool vendor, struct mesh_db_sub *sub)
+bool mesh_config_model_sub_del(json_object *jnode, uint16_t addr,
+						uint32_t mod_id, bool vendor,
+						struct mesh_config_sub *sub)
 {
 	json_object *jmodel, *jarray, *jarray_new;
 	char buf[33];
@@ -1774,7 +1783,7 @@ bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr,
 	return true;
 }
 
-bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr,
+bool mesh_config_model_sub_del_all(json_object *jnode, uint16_t addr,
 						uint32_t mod_id, bool vendor)
 {
 	if (!jnode)
diff --git a/mesh/mesh-config.h b/mesh/mesh-config.h
index da5efa12a..f60ae18cd 100644
--- a/mesh/mesh-config.h
+++ b/mesh/mesh-config.h
@@ -17,7 +17,7 @@
  *
  */
 
-struct mesh_db_sub {
+struct mesh_config_sub {
 	bool virt;
 	union {
 		uint16_t addr;
@@ -25,7 +25,7 @@ struct mesh_db_sub {
 	} src;
 };
 
-struct mesh_db_pub {
+struct mesh_config_pub {
 	bool virt;
 	uint32_t period;
 	uint16_t addr;
@@ -37,9 +37,9 @@ struct mesh_db_pub {
 	uint8_t virt_addr[16];
 };
 
-struct mesh_db_model {
-	struct mesh_db_sub *subs;
-	struct mesh_db_pub *pub;
+struct mesh_config_model {
+	struct mesh_config_sub *subs;
+	struct mesh_config_pub *pub;
 	uint16_t *bindings;
 	uint32_t id;
 	bool vendor;
@@ -47,13 +47,13 @@ struct mesh_db_model {
 	uint32_t num_subs;
 };
 
-struct mesh_db_element {
+struct mesh_config_element {
 	struct l_queue *models;
 	uint16_t location;
 	uint8_t index;
 };
 
-struct mesh_db_modes {
+struct mesh_config_modes {
 	struct {
 		uint16_t interval;
 		uint8_t cnt;
@@ -65,10 +65,10 @@ struct mesh_db_modes {
 	uint8_t beacon;
 };
 
-struct mesh_db_node {
+struct mesh_config_node {
 	bool provisioner;
 	uint32_t seq_number;
-	struct mesh_db_modes modes;
+	struct mesh_config_modes modes;
 	uint16_t cid;
 	uint16_t pid;
 	uint16_t vid;
@@ -78,7 +78,7 @@ struct mesh_db_node {
 	struct l_queue *elements;
 };
 
-struct mesh_db_prov {
+struct mesh_config_prov {
 	uint16_t algorithm;
 	struct {
 		uint16_t actions;
@@ -93,65 +93,73 @@ struct mesh_db_prov {
 	uint8_t priv_key[32];
 };
 
-typedef bool (*mesh_db_net_key_cb)(uint16_t idx, uint8_t key[16],
+typedef bool (*mesh_config_net_key_cb)(uint16_t idx, uint8_t key[16],
 			uint8_t new_key[16], int phase, void *user_data);
-typedef bool (*mesh_db_app_key_cb)(uint16_t idx, uint16_t net_idx,
+typedef bool (*mesh_config_app_key_cb)(uint16_t idx, uint16_t net_idx,
 			uint8_t key[16], uint8_t new_key[16], void *user_data);
-typedef bool (*mesh_db_node_cb)(struct mesh_db_node *node, void *user_data);
+typedef bool (*mesh_config_node_cb)(struct mesh_config_node *node,
+							void *user_data);
 
-bool mesh_db_read_node(json_object *jobj, mesh_db_node_cb cb, void *user_data);
-bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node);
-bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update);
-bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16]);
-bool mesh_db_read_token(json_object *jobj, uint8_t token[8]);
-bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
+bool mesh_config_read_node(json_object *jobj, mesh_config_node_cb cb,
+							void *user_data);
+bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node);
+bool mesh_config_read_iv_index(json_object *jobj, uint32_t *idx, bool *update);
+bool mesh_config_read_device_key(json_object *jobj, uint8_t key_buf[16]);
+bool mesh_config_read_token(json_object *jobj, uint8_t token[8]);
+bool mesh_config_read_net_transmit(json_object *jobj, uint8_t *cnt,
 							uint16_t *interval);
-bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
+bool mesh_config_write_net_transmit(json_object *jobj, uint8_t cnt,
 							uint16_t interval);
-bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
+bool mesh_config_read_net_keys(json_object *jobj, mesh_config_net_key_cb cb,
 							void *user_data);
-bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
+bool mesh_config_read_app_keys(json_object *jobj, mesh_config_app_key_cb cb,
 							void *user_data);
-bool mesh_db_write_device_key(json_object *jobj, uint8_t *key);
-bool mesh_db_write_token(json_object *jobj, uint8_t *token);
-bool mesh_db_write_network_key(json_object *jobj, uint16_t idx, uint8_t *key,
-						uint8_t *new_key, int phase);
-bool mesh_db_write_app_key(json_object *jobj, uint16_t net_idx,
+bool mesh_config_write_device_key(json_object *jobj, uint8_t *key);
+bool mesh_config_write_token(json_object *jobj, uint8_t *token);
+bool mesh_config_write_network_key(json_object *jobj, uint16_t idx,
+				uint8_t *key, uint8_t *new_key, int phase);
+bool mesh_config_write_app_key(json_object *jobj, uint16_t net_idx,
 			uint16_t app_idx, uint8_t *key, uint8_t *new_key);
-bool mesh_db_write_int(json_object *jobj, const char *keyword, int value);
-bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
+bool mesh_config_write_int(json_object *jobj, const char *keyword, int value);
+bool mesh_config_write_uint16_hex(json_object *jobj, const char *desc,
 								uint16_t value);
-bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
+bool mesh_config_write_uint32_hex(json_object *jobj, const char *desc,
 								uint32_t value);
-bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value);
-bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
-							uint16_t interval);
-bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value);
-bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
-					uint32_t mod_id, uint16_t app_idx);
-bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
-					uint32_t mod_id, uint16_t app_idx);
-bool mesh_db_model_pub_add(json_object *jnode, uint16_t ele_addr,
-			uint32_t mod_id, bool vendor, struct mesh_db_pub *pub);
-bool mesh_db_model_pub_del(json_object *jnode, uint16_t ele_addr,
+bool mesh_config_write_bool(json_object *jobj, const char *keyword, bool value);
+bool mesh_config_write_relay_mode(json_object *jnode, uint8_t mode,
+					uint8_t count, uint16_t interval);
+bool mesh_config_write_mode(json_object *jobj, const char *keyword, int value);
+bool mesh_config_model_binding_add(json_object *jnode, uint8_t ele_idx,
+						bool vendor, uint32_t mod_id,
+							uint16_t app_idx);
+bool mesh_config_model_binding_del(json_object *jnode, uint8_t ele_idx,
+						bool vendor, uint32_t mod_id,
+							uint16_t app_idx);
+bool mesh_config_model_pub_add(json_object *jnode, uint16_t ele_addr,
+						uint32_t mod_id, bool vendor,
+						struct mesh_config_pub *pub);
+bool mesh_config_model_pub_del(json_object *jnode, uint16_t ele_addr,
 						uint32_t mod_id, bool vendor);
-bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
-					bool vendor, struct mesh_db_sub *sub);
-bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
-					bool vendor, struct mesh_db_sub *sub);
-bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr,
+bool mesh_config_model_sub_add(json_object *jnode, uint16_t addr,
+						uint32_t mod_id, bool vendor,
+						struct mesh_config_sub *sub);
+bool mesh_config_model_sub_del(json_object *jnode, uint16_t addr,
+						uint32_t mod_id, bool vendor,
+						struct mesh_config_sub *sub);
+bool mesh_config_model_sub_del_all(json_object *jnode, uint16_t addr,
 						uint32_t mod_id, bool vendor);
-bool mesh_db_app_key_add(json_object *jnode, uint16_t net_idx, uint16_t app_idx,
-							const uint8_t key[16]);
-bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
+bool mesh_config_app_key_add(json_object *jnode, uint16_t net_idx,
+				uint16_t app_idx, const uint8_t key[16]);
+bool mesh_config_app_key_update(json_object *jobj, uint16_t app_idx,
 							const uint8_t key[16]);
-bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx);
-bool mesh_db_net_key_add(json_object *jobj, uint16_t net_idx,
+bool mesh_config_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx);
+bool mesh_config_net_key_add(json_object *jobj, uint16_t net_idx,
 							const uint8_t key[16]);
-bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
+bool mesh_config_net_key_update(json_object *jobj, uint16_t idx,
 							const uint8_t key[16]);
-bool mesh_db_net_key_del(json_object *jobj, uint16_t net_idx);
-bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase);
-bool mesh_db_write_address(json_object *jobj, uint16_t address);
-bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update);
-void mesh_db_remove_property(json_object *jobj, const char *desc);
+bool mesh_config_net_key_del(json_object *jobj, uint16_t net_idx);
+bool mesh_config_net_key_set_phase(json_object *jobj, uint16_t idx,
+								uint8_t phase);
+bool mesh_config_write_address(json_object *jobj, uint16_t address);
+bool mesh_config_write_iv_index(json_object *jobj, uint32_t idx, bool update);
+void mesh_config_remove_property(json_object *jobj, const char *desc);
diff --git a/mesh/model.c b/mesh/model.c
index 0474762e0..9331e1044 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -1406,10 +1406,10 @@ int mesh_model_sub_del_all(struct mesh_node *node, uint16_t addr, uint32_t id)
 struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
 								void *data)
 {
-	struct mesh_db_model *db_mod = data;
+	struct mesh_config_model *db_mod = data;
 	struct mesh_model *mod;
 	struct mesh_net *net;
-	struct mesh_db_pub *pub = db_mod->pub;
+	struct mesh_config_pub *pub = db_mod->pub;
 	uint32_t i;
 
 	if (db_mod->num_bindings > MAX_BINDINGS) {
diff --git a/mesh/node.c b/mesh/node.c
index 51cf4cda8..ac2e98254 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -290,7 +290,7 @@ void node_remove(struct mesh_node *node)
 }
 
 static bool add_models(struct mesh_node *node, struct node_element *ele,
-						struct mesh_db_element *db_ele)
+					struct mesh_config_element *db_ele)
 {
 	const struct l_queue_entry *entry;
 
@@ -300,7 +300,7 @@ static bool add_models(struct mesh_node *node, struct node_element *ele,
 	entry = l_queue_get_entries(db_ele->models);
 	for (; entry; entry = entry->next) {
 		struct mesh_model *mod;
-		struct mesh_db_model *db_mod;
+		struct mesh_config_model *db_mod;
 
 		db_mod = entry->data;
 		mod = mesh_model_setup(node, ele->idx, db_mod);
@@ -318,7 +318,7 @@ static void add_internal_model(struct mesh_node *node, uint32_t mod_id,
 {
 	struct node_element *ele;
 	struct mesh_model *mod;
-	struct mesh_db_model db_mod;
+	struct mesh_config_model db_mod;
 
 	ele = l_queue_find(node->elements, match_element_idx,
 							L_UINT_TO_PTR(ele_idx));
@@ -339,7 +339,8 @@ static void add_internal_model(struct mesh_node *node, uint32_t mod_id,
 	l_queue_push_tail(ele->models, mod);
 }
 
-static bool add_element(struct mesh_node *node, struct mesh_db_element *db_ele)
+static bool add_element(struct mesh_node *node,
+					struct mesh_config_element *db_ele)
 {
 	struct node_element *ele;
 
@@ -357,7 +358,8 @@ static bool add_element(struct mesh_node *node, struct mesh_db_element *db_ele)
 	return true;
 }
 
-static bool add_elements(struct mesh_node *node, struct mesh_db_node *db_node)
+static bool add_elements(struct mesh_node *node,
+					struct mesh_config_node *db_node)
 {
 	const struct l_queue_entry *entry;
 
@@ -374,7 +376,7 @@ static bool add_elements(struct mesh_node *node, struct mesh_db_node *db_node)
 
 bool node_init_from_storage(struct mesh_node *node, void *data)
 {
-	struct mesh_db_node *db_node = data;
+	struct mesh_config_node *db_node = data;
 	unsigned int num_ele;
 	uint8_t mode;
 
@@ -1266,7 +1268,7 @@ static bool get_element_properties(struct mesh_node *node, const char *path,
 }
 
 static void convert_node_to_storage(struct mesh_node *node,
-						struct mesh_db_node *db_node)
+					struct mesh_config_node *db_node)
 {
 	const struct l_queue_entry *entry;
 
@@ -1292,10 +1294,10 @@ static void convert_node_to_storage(struct mesh_node *node,
 
 	for (; entry; entry = entry->next) {
 		struct node_element *ele = entry->data;
-		struct mesh_db_element *db_ele;
+		struct mesh_config_element *db_ele;
 		const struct l_queue_entry *mod_entry;
 
-		db_ele = l_new(struct mesh_db_element, 1);
+		db_ele = l_new(struct mesh_config_element, 1);
 
 		db_ele->index = ele->idx;
 		db_ele->location = ele->location;
@@ -1305,10 +1307,10 @@ static void convert_node_to_storage(struct mesh_node *node,
 
 		for (; mod_entry; mod_entry = mod_entry->next) {
 			struct mesh_model *mod = mod_entry->data;
-			struct mesh_db_model *db_mod;
+			struct mesh_config_model *db_mod;
 			uint32_t mod_id = mesh_model_get_model_id(mod);
 
-			db_mod = l_new(struct mesh_db_model, 1);
+			db_mod = l_new(struct mesh_config_model, 1);
 			db_mod->id = mod_id;
 			db_mod->vendor = ((mod_id & VENDOR_ID_MASK)
 							!= VENDOR_ID_MASK);
@@ -1322,7 +1324,7 @@ static void convert_node_to_storage(struct mesh_node *node,
 
 static bool create_node_config(struct mesh_node *node)
 {
-	struct mesh_db_node db_node;
+	struct mesh_config_node db_node;
 	const struct l_queue_entry *entry;
 	bool res;
 
@@ -1332,7 +1334,7 @@ static bool create_node_config(struct mesh_node *node)
 	/* Free temporarily allocated resources */
 	entry = l_queue_get_entries(db_node.elements);
 	for (; entry; entry = entry->next) {
-		struct mesh_db_element *db_ele = entry->data;
+		struct mesh_config_element *db_ele = entry->data;
 
 		l_queue_destroy(db_ele->models, l_free);
 	}
@@ -1435,16 +1437,16 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 
 	mesh_net_set_iv_index(node->net, iv_idx, ivu);
 
-	if (!mesh_db_write_uint16_hex(node->jconfig, "unicastAddress",
+	if (!mesh_config_write_uint16_hex(node->jconfig, "unicastAddress",
 								unicast))
 		return false;
 
 	l_getrandom(node->token, sizeof(node->token));
-	if (!mesh_db_write_token(node->jconfig, node->token))
+	if (!mesh_config_write_token(node->jconfig, node->token))
 		return false;
 
 	memcpy(node->dev_key, dev_key, 16);
-	if (!mesh_db_write_device_key(node->jconfig, dev_key))
+	if (!mesh_config_write_device_key(node->jconfig, dev_key))
 		return false;
 
 	node->primary = unicast;
@@ -1460,7 +1462,7 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 							MESH_STATUS_SUCCESS)
 			return false;
 
-		if (!mesh_db_net_key_set_phase(node->jconfig, net_key_idx,
+		if (!mesh_config_net_key_set_phase(node->jconfig, net_key_idx,
 							KEY_REFRESH_PHASE_TWO))
 			return false;
 	}
diff --git a/mesh/storage.c b/mesh/storage.c
index bba2ef348..601669791 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -52,7 +52,7 @@ static const char *bak_ext = ".bak";
 static const char *tmp_ext = ".tmp";
 static const char *storage_dir;
 
-static bool read_node_cb(struct mesh_db_node *db_node, void *user_data)
+static bool read_node_cb(struct mesh_config_node *db_node, void *user_data)
 {
 	struct mesh_node *node = user_data;
 
@@ -95,30 +95,30 @@ static bool parse_node(struct mesh_node *node, json_object *jnode)
 	uint16_t interval;
 	struct mesh_net *net = node_get_net(node);
 
-	if (mesh_db_read_iv_index(jnode, &iv_index, &bvalue))
+	if (mesh_config_read_iv_index(jnode, &iv_index, &bvalue))
 		mesh_net_set_iv_index(net, iv_index, bvalue);
 
-	if (mesh_db_read_net_transmit(jnode, &cnt, &interval))
+	if (mesh_config_read_net_transmit(jnode, &cnt, &interval))
 		mesh_net_transmit_params_set(net, cnt, interval);
 
 	/* Node composition/configuration info */
-	if (!mesh_db_read_node(jnode, read_node_cb, node))
+	if (!mesh_config_read_node(jnode, read_node_cb, node))
 		return false;
 
-	if (!mesh_db_read_net_keys(jnode, read_net_keys_cb, net))
+	if (!mesh_config_read_net_keys(jnode, read_net_keys_cb, net))
 		return false;
 
-	if (!mesh_db_read_token(jnode, key_buf))
+	if (!mesh_config_read_token(jnode, key_buf))
 		return false;
 
 	node_set_token(node, key_buf);
 
-	if (!mesh_db_read_device_key(jnode, key_buf))
+	if (!mesh_config_read_device_key(jnode, key_buf))
 		return false;
 
 	node_set_device_key(node, key_buf);
 
-	mesh_db_read_app_keys(jnode, read_app_keys_cb, net);
+	mesh_config_read_app_keys(jnode, read_app_keys_cb, net);
 
 	return true;
 }
@@ -184,7 +184,7 @@ bool storage_set_ttl(struct mesh_node *node, uint8_t ttl)
 {
 	json_object *jnode = node_jconfig_get(node);
 
-	if (!mesh_db_write_int(jnode, "defaultTTL", ttl))
+	if (!mesh_config_write_int(jnode, "defaultTTL", ttl))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -196,7 +196,7 @@ bool storage_set_relay(struct mesh_node *node, bool enable,
 {
 	json_object *jnode = node_jconfig_get(node);
 
-	if (!mesh_db_write_relay_mode(jnode, enable, count, interval))
+	if (!mesh_config_write_relay_mode(jnode, enable, count, interval))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -208,7 +208,7 @@ bool storage_set_transmit_params(struct mesh_node *node, uint8_t count,
 {
 	json_object *jnode = node_jconfig_get(node);
 
-	if (!mesh_db_write_net_transmit(jnode, count, interval))
+	if (!mesh_config_write_net_transmit(jnode, count, interval))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -220,7 +220,7 @@ bool storage_set_mode(struct mesh_node *node, uint8_t mode,
 {
 	json_object *jnode = node_jconfig_get(node);
 
-	if (!mesh_db_write_mode(jnode, mode_name, mode))
+	if (!mesh_config_write_mode(jnode, mode_name, mode))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -241,11 +241,11 @@ bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t mod_id,
 	jnode = node_jconfig_get(node);
 
 	if (unbind)
-		stored = mesh_db_model_binding_del(jnode, ele_idx, is_vendor,
-							mod_id, app_idx);
+		stored = mesh_config_model_binding_del(jnode, ele_idx,
+						is_vendor, mod_id, app_idx);
 	else
-		stored = mesh_db_model_binding_add(jnode, ele_idx, is_vendor,
-							mod_id, app_idx);
+		stored = mesh_config_model_binding_add(jnode, ele_idx,
+						is_vendor, mod_id, app_idx);
 
 	if (stored)
 		storage_save_config(node, true, NULL, NULL);
@@ -265,9 +265,9 @@ bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
 		return false;
 
 	if (update)
-		stored = mesh_db_app_key_update(jnode, app_idx, key);
+		stored = mesh_config_app_key_update(jnode, app_idx, key);
 	else
-		stored = mesh_db_app_key_add(jnode, net_idx, app_idx, key);
+		stored = mesh_config_app_key_add(jnode, net_idx, app_idx, key);
 
 	if (stored)
 		storage_save_config(node, true, NULL, NULL);
@@ -285,7 +285,7 @@ bool storage_app_key_del(struct mesh_net *net, uint16_t net_idx,
 	if (!jnode)
 		return false;
 
-	if (!mesh_db_app_key_del(jnode, net_idx, app_idx))
+	if (!mesh_config_app_key_del(jnode, net_idx, app_idx))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -300,9 +300,9 @@ bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
 	bool stored;
 
 	if (!update)
-		stored = mesh_db_net_key_add(jnode, net_idx, key);
+		stored = mesh_config_net_key_add(jnode, net_idx, key);
 	else
-		stored = mesh_db_net_key_update(jnode, net_idx, key);
+		stored = mesh_config_net_key_update(jnode, net_idx, key);
 
 	if (stored)
 		storage_save_config(node, true, NULL, NULL);
@@ -315,7 +315,7 @@ bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx)
 	struct mesh_node *node = mesh_net_node_get(net);
 	json_object *jnode = node_jconfig_get(node);
 
-	if (!mesh_db_net_key_del(jnode, net_idx))
+	if (!mesh_config_net_key_del(jnode, net_idx))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -328,7 +328,7 @@ bool storage_set_iv_index(struct mesh_net *net, uint32_t iv_index,
 	struct mesh_node *node = mesh_net_node_get(net);
 	json_object *jnode = node_jconfig_get(node);
 
-	if (!mesh_db_write_iv_index(jnode, iv_index, update))
+	if (!mesh_config_write_iv_index(jnode, iv_index, update))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -341,7 +341,7 @@ bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
 	struct mesh_node *node = mesh_net_node_get(net);
 	json_object *jnode = node_jconfig_get(node);
 
-	if (!mesh_db_net_key_set_phase(jnode, net_idx, phase))
+	if (!mesh_config_net_key_set_phase(jnode, net_idx, phase))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -353,7 +353,7 @@ bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq)
 	struct mesh_node *node = mesh_net_node_get(net);
 	json_object *jnode = node_jconfig_get(node);
 
-	if (!mesh_db_write_int(jnode, "sequenceNumber", seq))
+	if (!mesh_config_write_int(jnode, "sequenceNumber", seq))
 		return false;
 
 	storage_save_config(node, false, NULL, NULL);
@@ -523,7 +523,7 @@ bool storage_load_nodes(const char *dir_name)
 
 bool storage_create_node_config(struct mesh_node *node, void *data)
 {
-	struct mesh_db_node *db_node = data;
+	struct mesh_config_node *db_node = data;
 	char uuid[33];
 	char name_buf[PATH_MAX];
 	json_object *jnode;
@@ -534,7 +534,7 @@ bool storage_create_node_config(struct mesh_node *node, void *data)
 
 	jnode = json_object_new_object();
 
-	if (!mesh_db_add_node(jnode, db_node))
+	if (!mesh_config_add_node(jnode, db_node))
 		return false;
 
 	if (!hex2str(node_uuid_get(node), 16, uuid, sizeof(uuid)))
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 04/10 v3] mesh: Move load from storage functionality into node.c
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (2 preceding siblings ...)
  2019-07-14 23:23 ` [PATCH BlueZ 03/10 v3] mesh: Change mesh_db prefix to mesh_config Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 05/10 v3] mesh: Confine dependency on json-c to mesh-config-json.c Inga Stotland
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This moves the initialization of a mesh node from stored
configuration from storage.c to node.c
---
 mesh/mesh-config-json.c | 255 +++++++++++++++++++++++-----------------
 mesh/mesh-config.h      |  59 +++++-----
 mesh/node.c             |  40 ++++++-
 mesh/storage.c          |  61 +---------
 4 files changed, 215 insertions(+), 200 deletions(-)

diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c
index 8fcb8afe3..a0c3e27c0 100644
--- a/mesh/mesh-config-json.c
+++ b/mesh/mesh-config-json.c
@@ -252,7 +252,7 @@ static json_object *jarray_key_del(json_object *jarray, int16_t idx)
 	return jarray_new;
 }
 
-bool mesh_config_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
+static bool read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
 {
 	int tmp;
 
@@ -270,7 +270,7 @@ bool mesh_config_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
 	return true;
 }
 
-bool mesh_config_read_token(json_object *jobj, uint8_t token[8])
+static bool read_token(json_object *jobj, uint8_t token[8])
 {
 	json_object *jvalue;
 	char *str;
@@ -288,7 +288,7 @@ bool mesh_config_read_token(json_object *jobj, uint8_t token[8])
 	return true;
 }
 
-bool mesh_config_read_device_key(json_object *jobj, uint8_t key_buf[16])
+static bool read_device_key(json_object *jobj, uint8_t key_buf[16])
 {
 	json_object *jvalue;
 	char *str;
@@ -306,78 +306,86 @@ bool mesh_config_read_device_key(json_object *jobj, uint8_t key_buf[16])
 	return true;
 }
 
-bool mesh_config_read_app_keys(json_object *jobj, mesh_config_app_key_cb cb,
-							void *user_data)
+static bool get_key_index(json_object *jobj, const char *keyword,
+								uint16_t *index)
+{
+	int idx;
+
+	if (!get_int(jobj, keyword, &idx))
+		return false;
+
+	if (!CHECK_KEY_IDX_RANGE(idx))
+		return false;
+
+	*index = (uint16_t) idx;
+	return true;
+}
+
+static bool read_app_keys(json_object *jobj, struct mesh_config_node *node)
 {
 	json_object *jarray;
 	int len;
 	int i;
 
-	if (!cb)
-		return true;
-
 	if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
-		return false;
+		return true;
 
 	if (json_object_get_type(jarray) != json_type_array)
 		return false;
 
+	/* Allow empty AppKey array */
 	len = json_object_array_length(jarray);
+	if (!len)
+		return true;
+
+	node->appkeys = l_queue_new();
 
 	for (i = 0; i < len; ++i) {
 		json_object *jtemp, *jvalue;
-		int app_idx, net_idx;
-		bool key_refresh = false;
 		char *str;
-		uint8_t key[16];
-		uint8_t new_key[16];
+		struct mesh_config_appkey *appkey;
+
+		appkey = l_new(struct mesh_config_appkey, 1);
 
 		jtemp = json_object_array_get_idx(jarray, i);
 
-		if (!get_int(jtemp, "index", &app_idx))
-			return false;
+		if (!get_key_index(jtemp, "index", &appkey->app_idx))
+			goto fail;
 
-		if (!CHECK_KEY_IDX_RANGE(app_idx))
-			return false;
+		if (!get_key_index(jtemp, "boundNetKey", &appkey->net_idx))
+			goto fail;
 
-		if (!get_int(jtemp, "boundNetKey", &net_idx))
-			return false;
+		if (!json_object_object_get_ex(jtemp, "key", &jvalue))
+			goto fail;
 
-		if (!CHECK_KEY_IDX_RANGE(net_idx))
-			return false;
+		str = (char *)json_object_get_string(jvalue);
+		if (!str2hex(str, strlen(str), appkey->new_key, 16))
+			goto fail;
 
-		if (json_object_object_get_ex(jtemp, "oldKey", &jvalue)) {
+		if (json_object_object_get_ex(jtemp, "oldKey", &jvalue))
 			str = (char *)json_object_get_string(jvalue);
-			if (!str2hex(str, strlen(str), key, 16))
-				return false;
-			key_refresh = true;
-		}
-
-		if (!json_object_object_get_ex(jtemp, "key", &jvalue))
-			return false;
 
-		str = (char *)json_object_get_string(jvalue);
-		if (!str2hex(str, strlen(str), key_refresh ? new_key : key, 16))
-			return false;
+		if (!str2hex(str, strlen(str), appkey->key, 16))
+			goto fail;
 
-		if (!cb((uint16_t)net_idx, (uint16_t) app_idx, key,
-				key_refresh ? new_key : NULL, user_data))
-			return false;
+		l_queue_push_tail(node->appkeys, appkey);
 	}
 
 	return true;
+fail:
+	l_queue_destroy(node->appkeys, l_free);
+	node->appkeys = NULL;
+
+	return false;
 }
 
-bool mesh_config_read_net_keys(json_object *jobj, mesh_config_net_key_cb cb,
-								void *user_data)
+static bool read_net_keys(json_object *jobj,  struct mesh_config_node *node)
 {
 	json_object *jarray;
 	int len;
 	int i;
 
-	if (!cb)
-		return true;
-
+	/* At least one NetKey must be present for a provisioned node */
 	if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
 		return false;
 
@@ -385,50 +393,57 @@ bool mesh_config_read_net_keys(json_object *jobj, mesh_config_net_key_cb cb,
 		return false;
 
 	len = json_object_array_length(jarray);
+	if (!len)
+		return false;
+
+	node->netkeys = l_queue_new();
 
 	for (i = 0; i < len; ++i) {
 		json_object *jtemp, *jvalue;
-		int idx;
 		char *str;
-		bool key_refresh = false;
-		int phase;
-		uint8_t key[16];
-		uint8_t new_key[16];
+		struct mesh_config_netkey *netkey;
 
-		jtemp = json_object_array_get_idx(jarray, i);
-
-		if (!get_int(jtemp, "index", &idx))
-			return false;
+		netkey = l_new(struct mesh_config_netkey, 1);
 
-		if (!CHECK_KEY_IDX_RANGE(idx))
-			return false;
+		jtemp = json_object_array_get_idx(jarray, i);
 
-		if (json_object_object_get_ex(jtemp, "oldKey", &jvalue)) {
-			str = (char *)json_object_get_string(jvalue);
-			if (!str2hex(str, strlen(str), key, 16))
-				return false;
-			key_refresh = true;
-		}
+		if (!get_key_index(jtemp, "index", &netkey->idx))
+			goto fail;
 
 		if (!json_object_object_get_ex(jtemp, "key", &jvalue))
-			return false;
+			goto fail;
 
 		str = (char *)json_object_get_string(jvalue);
-		if (!str2hex(str, strlen(str), key_refresh ? new_key : key, 16))
-			return false;
+		if (!str2hex(str, strlen(str), netkey->new_key, 16))
+			goto fail;
 
 		if (!json_object_object_get_ex(jtemp, "keyRefresh", &jvalue))
-			phase = KEY_REFRESH_PHASE_NONE;
+			netkey->phase = KEY_REFRESH_PHASE_NONE;
 		else
-			phase = json_object_get_int(jvalue);
+			netkey->phase = (uint8_t) json_object_get_int(jvalue);
 
+		if (netkey->phase > KEY_REFRESH_PHASE_TWO)
+			goto fail;
 
-		if (!cb((uint16_t)idx, key, key_refresh ? new_key : NULL, phase,
-								user_data))
-			return false;
+		if (json_object_object_get_ex(jtemp, "oldKey", &jvalue)) {
+			if (netkey->phase == KEY_REFRESH_PHASE_NONE)
+				goto fail;
+
+			str = (char *)json_object_get_string(jvalue);
+		}
+
+		if (!str2hex(str, strlen(str), netkey->key, 16))
+			goto fail;
+
+		l_queue_push_tail(node->netkeys, netkey);
 	}
 
 	return true;
+fail:
+	l_queue_destroy(node->netkeys, l_free);
+	node->netkeys = NULL;
+
+	return false;
 }
 
 bool mesh_config_net_key_add(json_object *jobj, uint16_t idx,
@@ -787,21 +802,6 @@ static bool parse_bindings(json_object *jarray, struct mesh_config_model *mod)
 	return true;
 }
 
-static bool get_key_index(json_object *jobj, const char *keyword,
-								uint16_t *index)
-{
-	int idx;
-
-	if (!get_int(jobj, keyword, &idx))
-		return false;
-
-	if (!CHECK_KEY_IDX_RANGE(idx))
-		return false;
-
-	*index = (uint16_t) idx;
-	return true;
-}
-
 static struct mesh_config_pub *parse_model_publication(json_object *jpub)
 {
 	json_object *jvalue;
@@ -1162,12 +1162,40 @@ static bool parse_composition(json_object *jcomp, struct mesh_config_node *node)
 	return true;
 }
 
+static bool read_net_transmit(json_object *jobj, struct mesh_config_node *node)
+{
+	json_object *jretransmit, *jvalue;
+	uint16_t interval;
+	uint8_t cnt;
+
+	if (!json_object_object_get_ex(jobj, "retransmit", &jretransmit))
+		return true;
+
+	if (!json_object_object_get_ex(jretransmit, "count", &jvalue))
+		return false;
+
+	/* TODO: add range checking */
+	cnt = (uint8_t) json_object_get_int(jvalue);
+
+	if (!json_object_object_get_ex(jretransmit, "interval", &jvalue))
+		return false;
+
+	interval = (uint16_t) json_object_get_int(jvalue);
+
+	node->net_transmit = l_new(struct mesh_config_transmit, 1);
+	node->net_transmit->count = cnt;
+	node->net_transmit->interval = interval;
+
+	return true;
+}
+
 bool mesh_config_read_node(json_object *jnode, mesh_config_node_cb cb,
 							void *user_data)
 {
 	struct mesh_config_node node;
 	json_object *jvalue;
 	char *str;
+	bool result = false;
 
 	if (!jnode)
 		return false;
@@ -1179,6 +1207,21 @@ bool mesh_config_read_node(json_object *jnode, mesh_config_node_cb cb,
 
 	memset(&node, 0, sizeof(node));
 
+	if (!read_iv_index(jnode, &node.iv_index, &node.iv_update)) {
+		l_info("Failed to read IV index");
+		return false;
+	}
+
+	if (!read_token(jnode, node.token)) {
+		l_info("Failed to read node token");
+		return false;
+	}
+
+	if (!read_device_key(jnode, node.dev_key)) {
+		l_info("Failed to read node device key");
+		return false;
+	}
+
 	if (!parse_composition(jnode, &node)) {
 		l_info("Failed to parse local node composition");
 		return false;
@@ -1210,10 +1253,34 @@ bool mesh_config_read_node(json_object *jnode, mesh_config_node_cb cb,
 	if (!json_object_object_get_ex(jnode, "elements", &jvalue))
 		return false;
 
-	if (!parse_elements(jvalue, &node))
+	if (!read_net_transmit(jnode, &node)) {
+		l_info("Failed to read node net transmit parameters");
 		return false;
+	}
 
-	return cb(&node, user_data);
+	if (!read_net_keys(jnode, &node)) {
+		l_info("Failed to read net keys");
+		goto done;
+	}
+
+	if (!read_app_keys(jnode, &node)) {
+		l_info("Failed to read app keys");
+		goto done;
+	}
+
+	if (!parse_elements(jvalue, &node)) {
+		l_info("Failed to parse elements");
+		goto done;
+	}
+
+	result = cb(&node, user_data);
+
+done:
+	l_free(node.net_transmit);
+	l_queue_destroy(node.netkeys, l_free);
+	l_queue_destroy(node.netkeys, l_free);
+
+	return result;
 }
 
 bool mesh_config_write_uint16_hex(json_object *jobj, const char *desc,
@@ -1346,30 +1413,6 @@ fail:
 	return false;
 }
 
-bool mesh_config_read_net_transmit(json_object *jobj, uint8_t *cnt,
-							uint16_t *interval)
-{
-	json_object *jretransmit, *jvalue;
-
-	if (!jobj)
-		return false;
-
-	if (!json_object_object_get_ex(jobj, "retransmit", &jretransmit))
-		return false;
-
-	if (!json_object_object_get_ex(jretransmit, "count", &jvalue))
-		return false;
-
-	*cnt = (uint8_t) json_object_get_int(jvalue);
-
-	if (!json_object_object_get_ex(jretransmit, "interval", &jvalue))
-		return false;
-
-	*interval = (uint16_t) json_object_get_int(jvalue);
-
-	return true;
-}
-
 bool mesh_config_write_net_transmit(json_object *jobj, uint8_t cnt,
 							uint16_t interval)
 {
diff --git a/mesh/mesh-config.h b/mesh/mesh-config.h
index f60ae18cd..4ba02babb 100644
--- a/mesh/mesh-config.h
+++ b/mesh/mesh-config.h
@@ -65,55 +65,52 @@ struct mesh_config_modes {
 	uint8_t beacon;
 };
 
+struct mesh_config_netkey {
+	uint16_t idx;
+	uint8_t key[16];
+	uint8_t new_key[16];
+	uint8_t phase;
+};
+
+struct mesh_config_appkey {
+	uint16_t net_idx;
+	uint16_t app_idx;
+	uint8_t key[16];
+	uint8_t new_key[16];
+};
+
+struct mesh_config_transmit {
+	uint16_t interval;
+	uint8_t count;
+};
+
 struct mesh_config_node {
-	bool provisioner;
+	struct l_queue *elements;
+	struct l_queue *netkeys;
+	struct l_queue *appkeys;
 	uint32_t seq_number;
-	struct mesh_config_modes modes;
+	uint32_t iv_index;
+	bool iv_update;
 	uint16_t cid;
 	uint16_t pid;
 	uint16_t vid;
 	uint16_t crpl;
 	uint16_t unicast;
+	struct mesh_config_transmit *net_transmit;
+	struct mesh_config_modes modes;
 	uint8_t ttl;
-	struct l_queue *elements;
+	uint8_t dev_key[16];
+	uint8_t token[8];
 };
 
-struct mesh_config_prov {
-	uint16_t algorithm;
-	struct {
-		uint16_t actions;
-		uint8_t size;
-	} input_oob;
-	uint8_t pub_type;
-	struct {
-		uint16_t actions;
-		uint8_t size;
-	} output_oob;
-	uint8_t static_type;
-	uint8_t priv_key[32];
-};
-
-typedef bool (*mesh_config_net_key_cb)(uint16_t idx, uint8_t key[16],
-			uint8_t new_key[16], int phase, void *user_data);
-typedef bool (*mesh_config_app_key_cb)(uint16_t idx, uint16_t net_idx,
-			uint8_t key[16], uint8_t new_key[16], void *user_data);
 typedef bool (*mesh_config_node_cb)(struct mesh_config_node *node,
 							void *user_data);
 
 bool mesh_config_read_node(json_object *jobj, mesh_config_node_cb cb,
 							void *user_data);
 bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node);
-bool mesh_config_read_iv_index(json_object *jobj, uint32_t *idx, bool *update);
-bool mesh_config_read_device_key(json_object *jobj, uint8_t key_buf[16]);
-bool mesh_config_read_token(json_object *jobj, uint8_t token[8]);
-bool mesh_config_read_net_transmit(json_object *jobj, uint8_t *cnt,
-							uint16_t *interval);
 bool mesh_config_write_net_transmit(json_object *jobj, uint8_t cnt,
 							uint16_t interval);
-bool mesh_config_read_net_keys(json_object *jobj, mesh_config_net_key_cb cb,
-							void *user_data);
-bool mesh_config_read_app_keys(json_object *jobj, mesh_config_app_key_cb cb,
-							void *user_data);
 bool mesh_config_write_device_key(json_object *jobj, uint8_t *key);
 bool mesh_config_write_token(json_object *jobj, uint8_t *token);
 bool mesh_config_write_network_key(json_object *jobj, uint16_t idx,
diff --git a/mesh/node.c b/mesh/node.c
index ac2e98254..fd344ddd7 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -31,6 +31,7 @@
 #include "mesh/mesh-defs.h"
 #include "mesh/mesh.h"
 #include "mesh/net.h"
+#include "mesh/appkey.h"
 #include "mesh/mesh-config.h"
 #include "mesh/provision.h"
 #include "mesh/storage.h"
@@ -374,6 +375,24 @@ static bool add_elements(struct mesh_node *node,
 	return true;
 }
 
+static void set_net_key(void *a, void *b)
+{
+	struct mesh_config_netkey *netkey = a;
+	struct mesh_node *node = b;
+
+	mesh_net_set_key(node->net, netkey->idx, netkey->key, netkey->new_key,
+								netkey->phase);
+}
+
+static void set_app_key(void *a, void *b)
+{
+	struct mesh_config_appkey *appkey = a;
+	struct mesh_node *node = b;
+
+	appkey_key_init(node->net, appkey->net_idx, appkey->app_idx,
+						appkey->key, appkey->new_key);
+}
+
 bool node_init_from_storage(struct mesh_node *node, void *data)
 {
 	struct mesh_config_node *db_node = data;
@@ -400,6 +419,9 @@ bool node_init_from_storage(struct mesh_node *node, void *data)
 	node->ttl = db_node->ttl;
 	node->seq_number = db_node->seq_number;
 
+	memcpy(node->dev_key, db_node->dev_key, 16);
+	memcpy(node->token, db_node->token, 8);
+
 	num_ele = l_queue_length(db_node->elements);
 	if (num_ele > 0xff)
 		return false;
@@ -411,6 +433,21 @@ bool node_init_from_storage(struct mesh_node *node, void *data)
 
 	node->primary = db_node->unicast;
 
+	if (!db_node->netkeys)
+		return false;
+
+	mesh_net_set_iv_index(node->net, db_node->iv_index, db_node->iv_update);
+
+	if (db_node->net_transmit)
+		mesh_net_transmit_params_set(node->net,
+					db_node->net_transmit->count,
+					db_node->net_transmit->interval);
+
+	l_queue_foreach(db_node->netkeys, set_net_key, node);
+
+	if (db_node->appkeys)
+		l_queue_foreach(db_node->appkeys, set_app_key, node);
+
 	mesh_net_set_seq_num(node->net, node->seq_number);
 	mesh_net_set_default_ttl(node->net, node->ttl);
 
@@ -435,9 +472,6 @@ bool node_init_from_storage(struct mesh_node *node, void *data)
 		!mesh_net_register_unicast(node->net, node->primary, num_ele))
 		return false;
 
-	if (node->uuid)
-		mesh_net_id_uuid_set(node->net, node->uuid);
-
 	/* Initialize configuration server model */
 	mesh_config_srv_init(node, PRIMARY_ELE_IDX);
 
diff --git a/mesh/storage.c b/mesh/storage.c
index 601669791..645d84c97 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -64,65 +64,6 @@ static bool read_node_cb(struct mesh_config_node *db_node, void *user_data)
 	return true;
 }
 
-static bool read_net_keys_cb(uint16_t idx, uint8_t *key, uint8_t *new_key,
-						int phase, void *user_data)
-{
-	struct mesh_net *net = user_data;
-
-	if (!net)
-		return false;
-
-	return mesh_net_set_key(net, idx, key, new_key, phase);
-}
-
-static bool read_app_keys_cb(uint16_t net_idx, uint16_t app_idx, uint8_t *key,
-					uint8_t *new_key, void *user_data)
-{
-	struct mesh_net *net = user_data;
-
-	if (!net)
-		return false;
-
-	return appkey_key_init(net, net_idx, app_idx, key, new_key);
-}
-
-static bool parse_node(struct mesh_node *node, json_object *jnode)
-{
-	bool bvalue;
-	uint32_t iv_index;
-	uint8_t key_buf[16];
-	uint8_t cnt;
-	uint16_t interval;
-	struct mesh_net *net = node_get_net(node);
-
-	if (mesh_config_read_iv_index(jnode, &iv_index, &bvalue))
-		mesh_net_set_iv_index(net, iv_index, bvalue);
-
-	if (mesh_config_read_net_transmit(jnode, &cnt, &interval))
-		mesh_net_transmit_params_set(net, cnt, interval);
-
-	/* Node composition/configuration info */
-	if (!mesh_config_read_node(jnode, read_node_cb, node))
-		return false;
-
-	if (!mesh_config_read_net_keys(jnode, read_net_keys_cb, net))
-		return false;
-
-	if (!mesh_config_read_token(jnode, key_buf))
-		return false;
-
-	node_set_token(node, key_buf);
-
-	if (!mesh_config_read_device_key(jnode, key_buf))
-		return false;
-
-	node_set_device_key(node, key_buf);
-
-	mesh_config_read_app_keys(jnode, read_app_keys_cb, net);
-
-	return true;
-}
-
 static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
 {
 	int fd;
@@ -162,7 +103,7 @@ static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
 
 	node = node_new(uuid);
 
-	result = parse_node(node, jnode);
+	result = mesh_config_read_node(jnode, read_node_cb, node);
 
 	if (!result) {
 		json_object_put(jnode);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 05/10 v3] mesh: Confine dependency on json-c to mesh-config-json.c
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (3 preceding siblings ...)
  2019-07-14 23:23 ` [PATCH BlueZ 04/10 v3] mesh: Move load from storage functionality into node.c Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 06/10 v3] mesh: Replace storage_save_config with mesh_config_save_config Inga Stotland
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This removes dependency on json-s/json.h header from everywhere
in the code except for mesh-config-json.c. The details about
node configuration storage format are obfuscated: a pointer
to an opaque mesh_config structure is stored with mesh_node and is
passed around to mae all the storage related operations.
---
 mesh/cfgmod-server.c    |  17 +-
 mesh/mesh-config-json.c | 558 +++++++++++++++++++++++++++-------------
 mesh/mesh-config.h      |  77 +++---
 mesh/model.c            |   1 -
 mesh/node.c             |  38 +--
 mesh/node.h             |   9 +-
 mesh/storage.c          | 205 +++++----------
 mesh/storage.h          |   4 +-
 8 files changed, 525 insertions(+), 384 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index 0479a9185..c73e63b4e 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -24,8 +24,6 @@
 #include <sys/time.h>
 #include <ell/ell.h>
 
-#include "json-c/json.h"
-
 #include "mesh/mesh-defs.h"
 #include "mesh/node.h"
 #include "mesh/net.h"
@@ -197,7 +195,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 
 		/* Remove model publication from config file */
 		if (status == MESH_STATUS_SUCCESS)
-			mesh_config_model_pub_del(node_jconfig_get(node),
+			mesh_config_model_pub_del(node_config_get(node),
 				ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
 									vendor);
 		goto done;
@@ -219,7 +217,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 			memcpy(db_pub.virt_addr, pub_addr, 16);
 
 		/* Save model publication to config file */
-		if (!mesh_config_model_pub_add(node_jconfig_get(node), ele_addr,
+		if (!mesh_config_model_pub_add(node_config_get(node), ele_addr,
 					vendor ? mod_id : mod_id & 0x0000ffff,
 					vendor, &db_pub))
 			status = MESH_STATUS_STORAGE_FAIL;
@@ -331,18 +329,18 @@ static bool save_config_sub(struct mesh_node *node, uint16_t ele_addr,
 
 	if (opcode == OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE ||
 					opcode == OP_CONFIG_MODEL_SUB_OVERWRITE)
-		mesh_config_model_sub_del_all(node_jconfig_get(node),
+		mesh_config_model_sub_del_all(node_config_get(node),
 				ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
 									vendor);
 
 	if (opcode != OP_CONFIG_MODEL_SUB_VIRT_DELETE &&
 			opcode != OP_CONFIG_MODEL_SUB_DELETE)
-		return mesh_config_model_sub_add(node_jconfig_get(node),
+		return mesh_config_model_sub_add(node_config_get(node),
 					ele_addr,
 					vendor ? mod_id : mod_id & 0x0000ffff,
 					vendor, &db_sub);
 	else
-		return mesh_config_model_sub_del(node_jconfig_get(node),
+		return mesh_config_model_sub_del(node_config_get(node),
 					ele_addr,
 					vendor ? mod_id : mod_id & 0x0000ffff,
 					vendor, &db_sub);
@@ -419,7 +417,7 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 		status = mesh_model_sub_del_all(node, ele_addr, mod_id);
 
 		if (status == MESH_STATUS_SUCCESS)
-			mesh_config_model_sub_del_all(node_jconfig_get(node),
+			mesh_config_model_sub_del_all(node_config_get(node),
 				ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
 									vendor);
 		break;
@@ -878,8 +876,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst,
 
 		count = (pkt[0] >> 5) + 1;
 		interval = ((pkt[0] & 0x1f) + 1) * 10;
-		if (storage_set_transmit_params(node_jconfig_get(node), count,
-								interval))
+		if (storage_set_transmit_params(node, count, interval))
 			mesh_net_transmit_params_set(net, count, interval);
 		/* Fall Through */
 
diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c
index a0c3e27c0..096b93249 100644
--- a/mesh/mesh-config-json.c
+++ b/mesh/mesh-config-json.c
@@ -22,9 +22,14 @@
 #endif
 
 #define _GNU_SOURCE
+//#include <dirent.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <ftw.h>
+#include <libgen.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <ell/ell.h>
 #include <json-c/json.h>
@@ -35,6 +40,12 @@
 
 #define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095))
 
+struct mesh_config {
+	json_object *jnode;
+	char *node_path;
+	uint8_t uuid[16];
+};
+
 static bool get_int(json_object *jobj, const char *keyword, int *value)
 {
 	json_object *jvalue;
@@ -446,13 +457,18 @@ fail:
 	return false;
 }
 
-bool mesh_config_net_key_add(json_object *jobj, uint16_t idx,
+bool mesh_config_net_key_add(struct mesh_config *cfg, uint16_t idx,
 							const uint8_t key[16])
 {
-	json_object *jarray = NULL, *jentry = NULL, *jstring;
+	json_object *jnode, *jarray = NULL, *jentry = NULL, *jstring;
 	char buf[5];
 
-	json_object_object_get_ex(jobj, "netKeys", &jarray);
+	if (!cfg)
+		return false;
+
+	jnode = cfg->jnode;
+
+	json_object_object_get_ex(jnode, "netKeys", &jarray);
 	if (jarray)
 		jentry = get_key_object(jarray, idx);
 
@@ -481,7 +497,7 @@ bool mesh_config_net_key_add(json_object *jobj, uint16_t idx,
 		jarray = json_object_new_array();
 		if (!jarray)
 			goto fail;
-		json_object_object_add(jobj, "netKeys", jarray);
+		json_object_object_add(jnode, "netKeys", jarray);
 	}
 
 	json_object_array_add(jarray, jentry);
@@ -494,13 +510,18 @@ fail:
 	return false;
 }
 
-bool mesh_config_net_key_update(json_object *jobj, uint16_t idx,
+bool mesh_config_net_key_update(struct mesh_config *cfg, uint16_t idx,
 							const uint8_t key[16])
 {
-	json_object *jarray, *jentry, *jstring;
+	json_object *jnode, *jarray, *jentry, *jstring;
 	const char *str;
 
-	if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
+	if (!cfg)
+		return false;
+
+	jnode = cfg->jnode;
+
+	if (!json_object_object_get_ex(jnode, "netKeys", &jarray))
 		return false;
 
 	jentry = get_key_object(jarray, idx);
@@ -525,11 +546,16 @@ bool mesh_config_net_key_update(json_object *jobj, uint16_t idx,
 	return true;
 }
 
-bool mesh_config_net_key_del(json_object *jobj, uint16_t idx)
+bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
 {
-	json_object *jarray, *jarray_new;
+	json_object *jnode, *jarray, *jarray_new;
 
-	if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
+	if (!cfg)
+		return false;
+
+	jnode = cfg->jnode;
+
+	if (!json_object_object_get_ex(jnode, "netKeys", &jarray))
 		return true;
 
 	/* Check if matching entry exists */
@@ -537,7 +563,7 @@ bool mesh_config_net_key_del(json_object *jobj, uint16_t idx)
 		return true;
 
 	if (json_object_array_length(jarray) == 1) {
-		json_object_object_del(jobj, "netKeys");
+		json_object_object_del(jnode, "netKeys");
 		return true;
 	}
 
@@ -550,29 +576,40 @@ bool mesh_config_net_key_del(json_object *jobj, uint16_t idx)
 	if (!jarray_new)
 		return false;
 
-	json_object_object_del(jobj, "netKeys");
-	json_object_object_add(jobj, "netKeys", jarray_new);
+	json_object_object_del(jnode, "netKeys");
+	json_object_object_add(jnode, "netKeys", jarray_new);
 
 	return true;
 }
 
-bool mesh_config_write_device_key(json_object *jnode, uint8_t *key)
+bool mesh_config_write_device_key(struct mesh_config *cfg, uint8_t *key)
 {
-	return add_key_value(jnode, "deviceKey", key);
+	if (!cfg)
+		return false;
+
+	return add_key_value(cfg->jnode, "deviceKey", key);
 }
 
-bool mesh_config_write_token(json_object *jnode, uint8_t *token)
+bool mesh_config_write_token(struct mesh_config *cfg, uint8_t *token)
 {
-	return add_u64_value(jnode, "token", token);
+	if (!cfg)
+		return false;
+
+	return add_u64_value(cfg->jnode, "token", token);
 }
 
-bool mesh_config_app_key_add(json_object *jobj, uint16_t net_idx,
+bool mesh_config_app_key_add(struct mesh_config *cfg, uint16_t net_idx,
 					uint16_t app_idx, const uint8_t key[16])
 {
-	json_object *jarray = NULL, *jentry = NULL, *jstring = NULL;
+	json_object *jnode, *jarray = NULL, *jentry = NULL, *jstring = NULL;
 	char buf[5];
 
-	json_object_object_get_ex(jobj, "appKeys", &jarray);
+	if (!cfg)
+		return false;
+
+	jnode = cfg->jnode;
+
+	json_object_object_get_ex(jnode, "appKeys", &jarray);
 	if (jarray)
 		jentry = get_key_object(jarray, app_idx);
 
@@ -605,7 +642,7 @@ bool mesh_config_app_key_add(json_object *jobj, uint16_t net_idx,
 		jarray = json_object_new_array();
 		if (!jarray)
 			goto fail;
-		json_object_object_add(jobj, "appKeys", jarray);
+		json_object_object_add(jnode, "appKeys", jarray);
 	}
 
 	json_object_array_add(jarray, jentry);
@@ -619,13 +656,18 @@ fail:
 	return false;
 }
 
-bool mesh_config_app_key_update(json_object *jobj, uint16_t app_idx,
+bool mesh_config_app_key_update(struct mesh_config *cfg, uint16_t app_idx,
 							const uint8_t key[16])
 {
-	json_object *jarray, *jentry = NULL, *jstring = NULL;
+	json_object *jnode, *jarray, *jentry = NULL, *jstring = NULL;
 	const char *str;
 
-	if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
+	if (!cfg)
+		return false;
+
+	jnode = cfg->jnode;
+
+	if (!json_object_object_get_ex(jnode, "appKeys", &jarray))
 		return false;
 
 	/* The key entry should exist if the key is updated */
@@ -644,11 +686,17 @@ bool mesh_config_app_key_update(json_object *jobj, uint16_t app_idx,
 	return add_key_value(jentry, "key", key);
 }
 
-bool mesh_config_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
+bool mesh_config_app_key_del(struct mesh_config *cfg, uint16_t net_idx,
+								uint16_t idx)
 {
-	json_object *jarray, *jarray_new;
+	json_object *jnode, *jarray, *jarray_new;
 
-	if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
+	if (!cfg)
+		return false;
+
+	jnode = cfg->jnode;
+
+	if (!json_object_object_get_ex(jnode, "appKeys", &jarray))
 		return true;
 
 	/* Check if matching entry exists */
@@ -656,7 +704,7 @@ bool mesh_config_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
 		return true;
 
 	if (json_object_array_length(jarray) == 1) {
-		json_object_object_del(jobj, "appKeys");
+		json_object_object_del(jnode, "appKeys");
 		return true;
 	}
 
@@ -669,19 +717,24 @@ bool mesh_config_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
 	if (!jarray_new)
 		return false;
 
-	json_object_object_del(jobj, "appKeys");
-	json_object_object_add(jobj, "appKeys", jarray_new);
+	json_object_object_del(jnode, "appKeys");
+	json_object_object_add(jnode, "appKeys", jarray_new);
 
 	return true;
 }
 
-bool mesh_config_model_binding_add(json_object *jnode, uint8_t ele_idx,
+bool mesh_config_model_binding_add(struct mesh_config *cfg, uint8_t ele_idx,
 					bool vendor, uint32_t mod_id,
 							uint16_t app_idx)
 {
-	json_object *jmodel, *jstring, *jarray = NULL;
+	json_object *jnode, *jmodel, *jstring, *jarray = NULL;
 	char buf[5];
 
+	if (!cfg)
+		return false;
+
+	jnode = cfg->jnode;
+
 	jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
 	if (!jmodel)
 		return false;
@@ -710,13 +763,18 @@ bool mesh_config_model_binding_add(json_object *jnode, uint8_t ele_idx,
 	return true;
 }
 
-bool mesh_config_model_binding_del(json_object *jnode, uint8_t ele_idx,
+bool mesh_config_model_binding_del(struct mesh_config *cfg, uint8_t ele_idx,
 					bool vendor, uint32_t mod_id,
 							uint16_t app_idx)
 {
-	json_object *jmodel, *jarray, *jarray_new;
+	json_object *jnode, *jmodel, *jarray, *jarray_new;
 	char buf[5];
 
+	if (!cfg)
+		return false;
+
+	jnode = cfg->jnode;
+
 	jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
 	if (!jmodel)
 		return false;
@@ -1189,45 +1247,32 @@ static bool read_net_transmit(json_object *jobj, struct mesh_config_node *node)
 	return true;
 }
 
-bool mesh_config_read_node(json_object *jnode, mesh_config_node_cb cb,
-							void *user_data)
+static bool read_node(json_object *jnode, struct mesh_config_node *node)
 {
-	struct mesh_config_node node;
 	json_object *jvalue;
 	char *str;
-	bool result = false;
-
-	if (!jnode)
-		return false;
-
-	if (!cb) {
-		l_info("Node read callback is required");
-		return false;
-	}
 
-	memset(&node, 0, sizeof(node));
-
-	if (!read_iv_index(jnode, &node.iv_index, &node.iv_update)) {
+	if (!read_iv_index(jnode, &node->iv_index, &node->iv_update)) {
 		l_info("Failed to read IV index");
 		return false;
 	}
 
-	if (!read_token(jnode, node.token)) {
+	if (!read_token(jnode, node->token)) {
 		l_info("Failed to read node token");
 		return false;
 	}
 
-	if (!read_device_key(jnode, node.dev_key)) {
+	if (!read_device_key(jnode, node->dev_key)) {
 		l_info("Failed to read node device key");
 		return false;
 	}
 
-	if (!parse_composition(jnode, &node)) {
+	if (!parse_composition(jnode, node)) {
 		l_info("Failed to parse local node composition");
 		return false;
 	}
 
-	parse_features(jnode, &node);
+	parse_features(jnode, node);
 
 	if (!json_object_object_get_ex(jnode, "unicastAddress", &jvalue)) {
 		l_info("Bad config: Unicast address must be present");
@@ -1235,7 +1280,7 @@ bool mesh_config_read_node(json_object *jnode, mesh_config_node_cb cb,
 	}
 
 	str = (char *)json_object_get_string(jvalue);
-	if (sscanf(str, "%04hx", &node.unicast) != 1)
+	if (sscanf(str, "%04hx", &node->unicast) != 1)
 		return false;
 
 	if (json_object_object_get_ex(jnode, "defaultTTL", &jvalue)) {
@@ -1243,55 +1288,45 @@ bool mesh_config_read_node(json_object *jnode, mesh_config_node_cb cb,
 
 		if (ttl < 0 || ttl == 1 || ttl > DEFAULT_TTL)
 			return false;
-		node.ttl = (uint8_t) ttl;
+		node->ttl = (uint8_t) ttl;
 	}
 
 	if (json_object_object_get_ex(jnode, "sequenceNumber", &jvalue))
-		node.seq_number = json_object_get_int(jvalue);
+		node->seq_number = json_object_get_int(jvalue);
 
 	/* Check for required "elements" property */
 	if (!json_object_object_get_ex(jnode, "elements", &jvalue))
 		return false;
 
-	if (!read_net_transmit(jnode, &node)) {
+	if (!read_net_transmit(jnode, node)) {
 		l_info("Failed to read node net transmit parameters");
 		return false;
 	}
 
-	if (!read_net_keys(jnode, &node)) {
+	if (!read_net_keys(jnode, node)) {
 		l_info("Failed to read net keys");
-		goto done;
+		return false;
 	}
 
-	if (!read_app_keys(jnode, &node)) {
+	if (!read_app_keys(jnode, node)) {
 		l_info("Failed to read app keys");
-		goto done;
+		return false;
 	}
 
-	if (!parse_elements(jvalue, &node)) {
+	if (!parse_elements(jvalue, node)) {
 		l_info("Failed to parse elements");
-		goto done;
+		return false;
 	}
 
-	result = cb(&node, user_data);
-
-done:
-	l_free(node.net_transmit);
-	l_queue_destroy(node.netkeys, l_free);
-	l_queue_destroy(node.netkeys, l_free);
-
-	return result;
+	return true;
 }
 
-bool mesh_config_write_uint16_hex(json_object *jobj, const char *desc,
+static bool write_uint16_hex(json_object *jobj, const char *desc,
 								uint16_t value)
 {
 	json_object *jstring;
 	char buf[5];
 
-	if (!jobj)
-		return false;
-
 	snprintf(buf, 5, "%4.4x", value);
 	jstring = json_object_new_string(buf);
 	if (!jstring)
@@ -1301,15 +1336,21 @@ bool mesh_config_write_uint16_hex(json_object *jobj, const char *desc,
 	return true;
 }
 
-bool mesh_config_write_uint32_hex(json_object *jobj, const char *desc,
+bool mesh_config_write_uint16_hex(struct mesh_config *cfg, const char *desc,
+								uint16_t value)
+{
+	if (!cfg)
+		return false;
+
+	return write_uint16_hex(cfg->jnode, desc, value);
+}
+
+static bool write_uint32_hex(json_object *jobj, const char *desc,
 								uint32_t value)
 {
 	json_object *jstring;
 	char buf[9];
 
-	if (!jobj)
-		return false;
-
 	snprintf(buf, 9, "%8.8x", value);
 	jstring = json_object_new_string(buf);
 	if (!jstring)
@@ -1319,13 +1360,19 @@ bool mesh_config_write_uint32_hex(json_object *jobj, const char *desc,
 	return true;
 }
 
-bool mesh_config_write_int(json_object *jobj, const char *keyword, int value)
+bool mesh_config_write_uint32_hex(struct mesh_config *cfg, const char *desc,
+								uint32_t value)
 {
-	json_object *jvalue;
-
-	if (!jobj)
+	if (!cfg)
 		return false;
 
+	return write_uint32_hex(cfg->jnode, desc, value);
+}
+
+static bool write_int(json_object *jobj, const char *keyword, int value)
+{
+	json_object *jvalue;
+
 	json_object_object_del(jobj, keyword);
 
 	jvalue = json_object_new_int(value);
@@ -1336,20 +1383,32 @@ bool mesh_config_write_int(json_object *jobj, const char *keyword, int value)
 	return true;
 }
 
-bool mesh_config_write_bool(json_object *jobj, const char *keyword, bool value)
+bool mesh_config_write_int(struct mesh_config *cfg, const char *keyword,
+								int value)
 {
-	json_object *jvalue;
+	if (!cfg)
+		return false;
+
+	return write_int(cfg->jnode, keyword, value);
+}
 
-	if (!jobj)
+bool mesh_config_write_bool(struct mesh_config *cfg, const char *keyword,
+								bool value)
+{
+	json_object *jnode, *jvalue;
+
+	if (!cfg)
 		return false;
 
-	json_object_object_del(jobj, keyword);
+	jnode = cfg->jnode;
+
+	json_object_object_del(jnode, keyword);
 
 	jvalue = json_object_new_boolean(value);
 	if (!jvalue)
 		return false;
 
-	json_object_object_add(jobj, keyword, jvalue);
+	json_object_object_add(jnode, keyword, jvalue);
 	return true;
 }
 
@@ -1365,13 +1424,10 @@ static const char *mode_to_string(int mode)
 	}
 }
 
-bool mesh_config_write_mode(json_object *jobj, const char *keyword, int value)
+static bool write_mode(json_object *jobj, const char *keyword, int value)
 {
 	json_object *jstring;
 
-	if (!jobj)
-		return false;
-
 	jstring = json_object_new_string(mode_to_string(value));
 
 	if (!jstring)
@@ -1382,30 +1438,36 @@ bool mesh_config_write_mode(json_object *jobj, const char *keyword, int value)
 	return true;
 }
 
-bool mesh_config_write_relay_mode(json_object *jnode, uint8_t mode,
+bool mesh_config_write_mode(struct mesh_config *cfg, const char *keyword,
+								int value)
+{
+	if (!cfg)
+		return false;
+
+	return write_mode(cfg->jnode, keyword, value);
+}
+
+static bool write_relay_mode(json_object *jobj, uint8_t mode,
 					uint8_t count, uint16_t interval)
 {
 	json_object *jrelay;
 
-	if (!jnode)
-		return false;
-
-	json_object_object_del(jnode, "relay");
+	json_object_object_del(jobj, "relay");
 
 	jrelay = json_object_new_object();
 	if (!jrelay)
 		return false;
 
-	if (!mesh_config_write_mode(jrelay, "mode", mode))
+	if (!write_mode(jrelay, "mode", mode))
 		goto fail;
 
-	if (!mesh_config_write_int(jrelay, "count", count))
+	if (!write_int(jrelay, "count", count))
 		goto fail;
 
-	if (!mesh_config_write_int(jrelay, "interval", interval))
+	if (!write_int(jrelay, "interval", interval))
 		goto fail;
 
-	json_object_object_add(jnode, "relay", jrelay);
+	json_object_object_add(jobj, "relay", jrelay);
 
 	return true;
 fail:
@@ -1413,27 +1475,38 @@ fail:
 	return false;
 }
 
-bool mesh_config_write_net_transmit(json_object *jobj, uint8_t cnt,
+bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode,
+					uint8_t count, uint16_t interval)
+{
+
+	if (!cfg)
+		return false;
+
+	return write_relay_mode(cfg->jnode, mode, count, interval);
+}
+
+bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
 							uint16_t interval)
 {
-	json_object *jretransmit;
+	json_object *jnode, *jretransmit;
 
-	if (!jobj)
+	if (!cfg)
 		return false;
+	jnode = cfg->jnode;
 
-	json_object_object_del(jobj, "retransmit");
+	json_object_object_del(jnode, "retransmit");
 
 	jretransmit = json_object_new_object();
 	if (jretransmit)
 		return false;
 
-	if (!mesh_config_write_int(jretransmit, "count", cnt))
+	if (!write_int(jretransmit, "count", cnt))
 		goto fail;
 
-	if (!mesh_config_write_int(jretransmit, "interval", interval))
+	if (!write_int(jretransmit, "interval", interval))
 		goto fail;
 
-	json_object_object_add(jobj, "retransmit", jretransmit);
+	json_object_object_add(jnode, "retransmit", jretransmit);
 
 	return true;
 fail:
@@ -1442,28 +1515,26 @@ fail:
 
 }
 
-bool mesh_config_write_iv_index(json_object *jobj, uint32_t idx, bool update)
+bool mesh_config_write_iv_index(struct mesh_config *cfg, uint32_t idx,
+								bool update)
 {
+	json_object *jnode;
 	int tmp = update ? 1 : 0;
 
-	if (!jobj)
+	if (!cfg)
 		return false;
 
-	if (!mesh_config_write_int(jobj, "IVindex", idx))
+	jnode = cfg->jnode;
+
+	if (!write_int(jnode, "IVindex", idx))
 		return false;
 
-	if (!mesh_config_write_int(jobj, "IVupdate", tmp))
+	if (!write_int(jnode, "IVupdate", tmp))
 		return false;
 
 	return true;
 }
 
-void mesh_config_remove_property(json_object *jobj, const char *desc)
-{
-	if (jobj)
-		json_object_object_del(jobj, desc);
-}
-
 static void add_model(void *a, void *b)
 {
 	struct mesh_config_model *mod = a;
@@ -1474,55 +1545,59 @@ static void add_model(void *a, void *b)
 		return;
 
 	if (!mod->vendor)
-		mesh_config_write_uint16_hex(jmodel, "modelId",
+		write_uint16_hex(jmodel, "modelId",
 						(uint16_t) mod->id);
 	else
-		mesh_config_write_uint32_hex(jmodel, "modelId", mod->id);
+		write_uint32_hex(jmodel, "modelId", mod->id);
 
 	json_object_array_add(jmodels, jmodel);
 }
 
 /* Add unprovisioned node (local) */
-bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node)
+struct mesh_config *mesh_config_create(const char *cfg_path,
+						const uint8_t uuid[16],
+						struct mesh_config_node *node)
 {
 	struct mesh_config_modes *modes = &node->modes;
 	const struct l_queue_entry *entry;
-	json_object *jelems;
+	json_object *jnode, *jelems;
+	struct mesh_config *cfg;
 
-	if (!jnode)
-		return false;
+	if (!cfg_path || !node)
+		return NULL;
+
+	jnode = json_object_new_object();
 
 	/* CID, PID, VID, crpl */
-	if (!mesh_config_write_uint16_hex(jnode, "cid", node->cid))
-		return false;
+	if (!write_uint16_hex(jnode, "cid", node->cid))
+		return NULL;
 
-	if (!mesh_config_write_uint16_hex(jnode, "pid", node->pid))
-		return false;
+	if (!write_uint16_hex(jnode, "pid", node->pid))
+		return NULL;
 
-	if (!mesh_config_write_uint16_hex(jnode, "vid", node->vid))
-		return false;
+	if (!write_uint16_hex(jnode, "vid", node->vid))
+		return NULL;
 
-	if (!mesh_config_write_uint16_hex(jnode, "crpl", node->crpl))
-		return false;
+	if (!write_uint16_hex(jnode, "crpl", node->crpl))
+		return NULL;
 
 	/* Features: relay, LPN, friend, proxy*/
-	if (!mesh_config_write_relay_mode(jnode, modes->relay.state,
-						modes->relay.cnt,
-						modes->relay.interval))
-		return false;
+	if (!write_relay_mode(jnode, modes->relay.state,
+				modes->relay.cnt, modes->relay.interval))
+		return NULL;
 
-	if (!mesh_config_write_mode(jnode, "lowPower", modes->lpn))
-		return false;
+	if (!write_mode(jnode, "lowPower", modes->lpn))
+		return NULL;
 
-	if (!mesh_config_write_mode(jnode, "friend", modes->friend))
-		return false;
+	if (!write_mode(jnode, "friend", modes->friend))
+		return NULL;
 
-	if (!mesh_config_write_mode(jnode, "proxy", modes->proxy))
-		return false;
+	if (!write_mode(jnode, "proxy", modes->proxy))
+		return NULL;
 
 	/* Beaconing state */
-	if (!mesh_config_write_mode(jnode, "beacon", modes->beacon))
-		return false;
+	if (!write_mode(jnode, "beacon", modes->beacon))
+		return NULL;
 
 	/* Sequence number */
 	json_object_object_add(jnode, "sequenceNumber",
@@ -1535,7 +1610,7 @@ bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node)
 	/* Elements */
 	jelems = json_object_new_array();
 	if (!jelems)
-		return false;
+		return NULL;
 
 	entry = l_queue_get_entries(node->elements);
 
@@ -1547,12 +1622,11 @@ bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node)
 
 		if (!jelement) {
 			json_object_put(jelems);
-			return false;
+			return NULL;
 		}
 
-		mesh_config_write_int(jelement, "elementIndex", ele->index);
-		mesh_config_write_uint16_hex(jelement, "location",
-								ele->location);
+		write_int(jelement, "elementIndex", ele->index);
+		write_uint16_hex(jelement, "location", ele->location);
 		json_object_array_add(jelems, jelement);
 
 		/* Models */
@@ -1562,7 +1636,7 @@ bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node)
 		jmodels = json_object_new_array();
 		if (!jmodels) {
 			json_object_put(jelems);
-			return false;
+			return NULL;
 		}
 
 		json_object_object_add(jelement, "models", jmodels);
@@ -1571,7 +1645,13 @@ bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node)
 
 	json_object_object_add(jnode, "elements", jelems);
 
-	return true;
+	cfg = l_new(struct mesh_config, 1);
+
+	cfg->jnode = jnode;
+	memcpy(cfg->uuid, uuid, 16);
+	cfg->node_path = l_strdup(cfg_path);
+
+	return cfg;
 }
 
 static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
@@ -1605,15 +1685,17 @@ static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
 
 }
 
-bool mesh_config_net_key_set_phase(json_object *jobj, uint16_t idx,
+bool mesh_config_net_key_set_phase(struct mesh_config *cfg, uint16_t idx,
 								uint8_t phase)
 {
-	json_object *jarray, *jentry = NULL;
+	json_object *jnode, *jarray, *jentry = NULL;
 
-	if (!jobj)
+	if (!cfg)
 		return false;
 
-	if (json_object_object_get_ex(jobj, "netKeys", &jarray))
+	jnode = cfg->jnode;
+
+	if (json_object_object_get_ex(jnode, "netKeys", &jarray))
 		jentry = get_key_object(jarray, idx);
 
 	if (!jentry)
@@ -1625,23 +1707,25 @@ bool mesh_config_net_key_set_phase(json_object *jobj, uint16_t idx,
 
 	if (phase == KEY_REFRESH_PHASE_NONE) {
 		json_object_object_del(jentry, "oldKey");
-		finish_key_refresh(jobj, idx);
+		finish_key_refresh(jnode, idx);
 	}
 
 	return true;
 }
 
-bool mesh_config_model_pub_add(json_object *jnode, uint16_t addr,
+bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t addr,
 					uint32_t mod_id, bool vendor,
 					struct mesh_config_pub *pub)
 {
-	json_object *jmodel, *jpub, *jretransmit;
+	json_object *jnode, *jmodel, *jpub, *jretransmit;
 	bool res;
 	int ele_idx;
 
-	if (!jnode)
+	if (!cfg)
 		return false;
 
+	jnode = cfg->jnode;
+
 	ele_idx = get_element_index(jnode, addr);
 	if (ele_idx < 0)
 		return false;
@@ -1659,21 +1743,21 @@ bool mesh_config_model_pub_add(json_object *jnode, uint16_t addr,
 	if (pub->virt)
 		res = add_key_value(jpub, "address", pub->virt_addr);
 	else
-		res = mesh_config_write_uint16_hex(jpub, "address", pub->addr);
+		res = write_uint16_hex(jpub, "address", pub->addr);
 
 	if (!res)
 		goto fail;
 
-	if (!mesh_config_write_uint16_hex(jpub, "index", pub->idx))
+	if (!write_uint16_hex(jpub, "index", pub->idx))
 		goto fail;
 
-	if (!mesh_config_write_int(jpub, "ttl", pub->ttl))
+	if (!write_int(jpub, "ttl", pub->ttl))
 		goto fail;
 
-	if (!mesh_config_write_int(jpub, "period", pub->period))
+	if (!write_int(jpub, "period", pub->period))
 		goto fail;
 
-	if (!mesh_config_write_int(jpub, "credentials",
+	if (!write_int(jpub, "credentials",
 						pub->credential ? 1 : 0))
 		goto fail;
 
@@ -1681,10 +1765,10 @@ bool mesh_config_model_pub_add(json_object *jnode, uint16_t addr,
 	if (!jretransmit)
 		goto fail;
 
-	if (!mesh_config_write_int(jretransmit, "count", pub->count))
+	if (!write_int(jretransmit, "count", pub->count))
 		goto fail;
 
-	if (!mesh_config_write_int(jretransmit, "interval", pub->interval))
+	if (!write_int(jretransmit, "interval", pub->interval))
 		goto fail;
 
 	json_object_object_add(jpub, "retransmit", jretransmit);
@@ -1715,26 +1799,29 @@ static bool delete_model_property(json_object *jnode, uint16_t addr,
 	return true;
 }
 
-bool mesh_config_model_pub_del(json_object *jnode, uint16_t addr,
+bool mesh_config_model_pub_del(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor)
 {
-	if (!jnode)
+	if (!cfg)
 		return false;
 
-	return delete_model_property(jnode, addr, mod_id, vendor, "publish");
+	return delete_model_property(cfg->jnode, addr, mod_id, vendor,
+								"publish");
 }
 
-bool mesh_config_model_sub_add(json_object *jnode, uint16_t addr,
+bool mesh_config_model_sub_add(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor,
 						struct mesh_config_sub *sub)
 {
-	json_object *jmodel, *jstring, *jarray = NULL;
+	json_object *jnode, *jmodel, *jstring, *jarray = NULL;
 	int ele_idx, len;
 	char buf[33];
 
-	if (!jnode)
+	if (!cfg)
 		return false;
 
+	jnode = cfg->jnode;
+
 	ele_idx = get_element_index(jnode, addr);
 	if (ele_idx < 0)
 		return false;
@@ -1773,17 +1860,19 @@ bool mesh_config_model_sub_add(json_object *jnode, uint16_t addr,
 	return true;
 }
 
-bool mesh_config_model_sub_del(json_object *jnode, uint16_t addr,
+bool mesh_config_model_sub_del(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor,
 						struct mesh_config_sub *sub)
 {
-	json_object *jmodel, *jarray, *jarray_new;
+	json_object *jnode, *jmodel, *jarray, *jarray_new;
 	char buf[33];
 	int len, ele_idx;
 
-	if (!jnode)
+	if (!cfg)
 		return false;
 
+	jnode = cfg->jnode;
+
 	ele_idx = get_element_index(jnode, addr);
 	if (ele_idx < 0)
 		return false;
@@ -1826,11 +1915,126 @@ bool mesh_config_model_sub_del(json_object *jnode, uint16_t addr,
 	return true;
 }
 
-bool mesh_config_model_sub_del_all(json_object *jnode, uint16_t addr,
+bool mesh_config_model_sub_del_all(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor)
 {
+	if (!cfg)
+		return false;
+
+	return delete_model_property(cfg->jnode, addr, mod_id, vendor,
+								"subscribe");
+}
+
+bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
+					mesh_config_node_cb cb, void *user_data)
+{
+	int fd;
+	char *str;
+	struct stat st;
+	ssize_t sz;
+	bool result = false;
+	json_object *jnode;
+	struct mesh_config_node node;
+
+	if (!cb) {
+		l_info("Node read callback is required");
+		return false;
+	}
+
+	l_info("Loading configuration from %s", cfg_path);
+
+	fd = open(cfg_path, O_RDONLY);
+	if (fd < 0)
+		return false;
+
+	if (fstat(fd, &st) == -1) {
+		close(fd);
+		return false;
+	}
+
+	str = (char *) l_new(char, st.st_size + 1);
+	if (!str) {
+		close(fd);
+		return false;
+	}
+
+	sz = read(fd, str, st.st_size);
+	if (sz != st.st_size) {
+		l_error("Failed to read configuration file %s", cfg_path);
+		goto done;
+	}
+
+	jnode = json_tokener_parse(str);
 	if (!jnode)
+		goto done;
+
+	memset(&node, 0, sizeof(node));
+	result = read_node(jnode, &node);
+
+	if (result) {
+		struct mesh_config *cfg = l_new(struct mesh_config, 1);
+
+		cfg->jnode = jnode;
+		memcpy(cfg->uuid, uuid, 16);
+		cfg->node_path = l_strdup(cfg_path);
+		result = cb(&node, uuid, cfg, user_data);
+
+		if (!result) {
+			l_free(cfg->node_path);
+			l_free(cfg);
+		}
+	}
+
+	/* Done with the node: free resources */
+	l_free(node.net_transmit);
+	l_queue_destroy(node.netkeys, l_free);
+	l_queue_destroy(node.appkeys, l_free);
+
+	if (!result)
+		json_object_put(jnode);
+
+done:
+	close(fd);
+	if (str)
+		l_free(str);
+
+	return result;
+}
+
+void mesh_config_release(struct mesh_config *cfg)
+{
+	if (!cfg)
+		return;
+
+	l_free(cfg->node_path);
+	json_object_put(cfg->jnode);
+	l_free(cfg);
+}
+
+bool mesh_config_save_config(struct mesh_config *cfg, const char *fname)
+{
+	FILE *outfile;
+	const char *str;
+	bool result = false;
+
+	if (!cfg)
+		return false;
+
+	outfile = fopen(fname, "w");
+	if (!outfile) {
+		l_error("Failed to save configuration to %s", fname);
 		return false;
+	}
+
+	str = json_object_to_json_string_ext(cfg->jnode,
+						JSON_C_TO_STRING_PRETTY);
+
+	if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
+		l_warn("Incomplete write of mesh configuration");
+	else
+		result = true;
+
+	fclose(outfile);
 
-	return delete_model_property(jnode, addr, mod_id, vendor, "subscribe");
+	return result;
 }
diff --git a/mesh/mesh-config.h b/mesh/mesh-config.h
index 4ba02babb..8d01e760c 100644
--- a/mesh/mesh-config.h
+++ b/mesh/mesh-config.h
@@ -17,10 +17,12 @@
  *
  */
 
+struct mesh_config;
+
 struct mesh_config_sub {
 	bool virt;
 	union {
-		uint16_t addr;
+		uint16_t	addr;
 		uint8_t	virt_addr[16];
 	} src;
 };
@@ -104,59 +106,70 @@ struct mesh_config_node {
 };
 
 typedef bool (*mesh_config_node_cb)(struct mesh_config_node *node,
+							const uint8_t uuid[16],
+							struct mesh_config *cfg,
 							void *user_data);
 
-bool mesh_config_read_node(json_object *jobj, mesh_config_node_cb cb,
-							void *user_data);
-bool mesh_config_add_node(json_object *jnode, struct mesh_config_node *node);
-bool mesh_config_write_net_transmit(json_object *jobj, uint8_t cnt,
+bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
+				mesh_config_node_cb cb, void *user_data);
+void mesh_config_release(struct mesh_config *cfg);
+bool mesh_config_save_config(struct mesh_config *cfg, const char *fname);
+struct mesh_config *mesh_config_create(const char *cfg_path,
+						const uint8_t uuid[16],
+						struct mesh_config_node *node);
+
+bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
 							uint16_t interval);
-bool mesh_config_write_device_key(json_object *jobj, uint8_t *key);
-bool mesh_config_write_token(json_object *jobj, uint8_t *token);
-bool mesh_config_write_network_key(json_object *jobj, uint16_t idx,
+bool mesh_config_write_device_key(struct mesh_config *cfg, uint8_t *key);
+bool mesh_config_write_token(struct mesh_config *cfg, uint8_t *token);
+bool mesh_config_write_network_key(struct mesh_config *cfg, uint16_t idx,
 				uint8_t *key, uint8_t *new_key, int phase);
-bool mesh_config_write_app_key(json_object *jobj, uint16_t net_idx,
+bool mesh_config_write_app_key(struct mesh_config *cfg, uint16_t net_idx,
 			uint16_t app_idx, uint8_t *key, uint8_t *new_key);
-bool mesh_config_write_int(json_object *jobj, const char *keyword, int value);
-bool mesh_config_write_uint16_hex(json_object *jobj, const char *desc,
+bool mesh_config_write_int(struct mesh_config *cfg,
+						const char *keyword, int value);
+bool mesh_config_write_uint16_hex(struct mesh_config *cfg, const char *desc,
 								uint16_t value);
-bool mesh_config_write_uint32_hex(json_object *jobj, const char *desc,
+bool mesh_config_write_uint32_hex(struct mesh_config *cfg, const char *desc,
 								uint32_t value);
-bool mesh_config_write_bool(json_object *jobj, const char *keyword, bool value);
-bool mesh_config_write_relay_mode(json_object *jnode, uint8_t mode,
+bool mesh_config_write_bool(struct mesh_config *cfg, const char *keyword,
+								bool value);
+bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode,
 					uint8_t count, uint16_t interval);
-bool mesh_config_write_mode(json_object *jobj, const char *keyword, int value);
-bool mesh_config_model_binding_add(json_object *jnode, uint8_t ele_idx,
+bool mesh_config_write_mode(struct mesh_config *cfg, const char *keyword,
+								int value);
+bool mesh_config_model_binding_add(struct mesh_config *cfg, uint8_t ele_idx,
 						bool vendor, uint32_t mod_id,
 							uint16_t app_idx);
-bool mesh_config_model_binding_del(json_object *jnode, uint8_t ele_idx,
+bool mesh_config_model_binding_del(struct mesh_config *cfg, uint8_t ele_idx,
 						bool vendor, uint32_t mod_id,
 							uint16_t app_idx);
-bool mesh_config_model_pub_add(json_object *jnode, uint16_t ele_addr,
+bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t ele_addr,
 						uint32_t mod_id, bool vendor,
 						struct mesh_config_pub *pub);
-bool mesh_config_model_pub_del(json_object *jnode, uint16_t ele_addr,
+bool mesh_config_model_pub_del(struct mesh_config *cfg, uint16_t ele_addr,
 						uint32_t mod_id, bool vendor);
-bool mesh_config_model_sub_add(json_object *jnode, uint16_t addr,
+bool mesh_config_model_sub_add(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor,
 						struct mesh_config_sub *sub);
-bool mesh_config_model_sub_del(json_object *jnode, uint16_t addr,
+bool mesh_config_model_sub_del(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor,
 						struct mesh_config_sub *sub);
-bool mesh_config_model_sub_del_all(json_object *jnode, uint16_t addr,
+bool mesh_config_model_sub_del_all(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor);
-bool mesh_config_app_key_add(json_object *jnode, uint16_t net_idx,
+bool mesh_config_app_key_add(struct mesh_config *cfg, uint16_t net_idx,
 				uint16_t app_idx, const uint8_t key[16]);
-bool mesh_config_app_key_update(json_object *jobj, uint16_t app_idx,
+bool mesh_config_app_key_update(struct mesh_config *cfg, uint16_t app_idx,
 							const uint8_t key[16]);
-bool mesh_config_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx);
-bool mesh_config_net_key_add(json_object *jobj, uint16_t net_idx,
+bool mesh_config_app_key_del(struct mesh_config *cfg, uint16_t net_idx,
+								uint16_t idx);
+bool mesh_config_net_key_add(struct mesh_config *cfg, uint16_t net_idx,
 							const uint8_t key[16]);
-bool mesh_config_net_key_update(json_object *jobj, uint16_t idx,
+bool mesh_config_net_key_update(struct mesh_config *cfg, uint16_t idx,
 							const uint8_t key[16]);
-bool mesh_config_net_key_del(json_object *jobj, uint16_t net_idx);
-bool mesh_config_net_key_set_phase(json_object *jobj, uint16_t idx,
+bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t net_idx);
+bool mesh_config_net_key_set_phase(struct mesh_config *cfg, uint16_t idx,
 								uint8_t phase);
-bool mesh_config_write_address(json_object *jobj, uint16_t address);
-bool mesh_config_write_iv_index(json_object *jobj, uint32_t idx, bool update);
-void mesh_config_remove_property(json_object *jobj, const char *desc);
+bool mesh_config_write_address(struct mesh_config *cfg, uint16_t address);
+bool mesh_config_write_iv_index(struct mesh_config *cfg, uint32_t idx,
+								bool update);
diff --git a/mesh/model.c b/mesh/model.c
index 9331e1044..0f10727b4 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -23,7 +23,6 @@
 
 #include <sys/time.h>
 #include <ell/ell.h>
-#include <json-c/json.h>
 
 #include "mesh/mesh-defs.h"
 
diff --git a/mesh/node.c b/mesh/node.c
index fd344ddd7..025c7b59d 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -26,7 +26,6 @@
 #include <sys/time.h>
 
 #include <ell/ell.h>
-#include <json-c/json.h>
 
 #include "mesh/mesh-defs.h"
 #include "mesh/mesh.h"
@@ -83,7 +82,8 @@ struct mesh_node {
 	char *owner;
 	char *obj_path;
 	struct mesh_agent *agent;
-	void *jconfig;
+	char *path;
+	struct mesh_config *cfg;
 	char *node_path;
 	uint32_t disc_watch;
 	time_t upd_sec;
@@ -393,9 +393,9 @@ static void set_app_key(void *a, void *b)
 						appkey->key, appkey->new_key);
 }
 
-bool node_init_from_storage(struct mesh_node *node, void *data)
+bool node_init_from_storage(struct mesh_node *node, const uint8_t uuid[16],
+					struct mesh_config_node *db_node)
 {
-	struct mesh_config_node *db_node = data;
 	unsigned int num_ele;
 	uint8_t mode;
 
@@ -759,7 +759,7 @@ bool node_proxy_mode_set(struct mesh_node *node, bool enable)
 		return false;
 
 	proxy = enable ? MESH_MODE_ENABLED : MESH_MODE_DISABLED;
-	res = storage_set_mode(node->jconfig, proxy, "proxy");
+	res = storage_set_mode(node, proxy, "proxy");
 
 	if (res) {
 		node->proxy = proxy;
@@ -786,7 +786,7 @@ bool node_beacon_mode_set(struct mesh_node *node, bool enable)
 		return false;
 
 	beacon = enable ? MESH_MODE_ENABLED : MESH_MODE_DISABLED;
-	res = storage_set_mode(node->jconfig, beacon, "beacon");
+	res = storage_set_mode(node, beacon, "beacon");
 
 	if (res) {
 		node->beacon = beacon;
@@ -813,7 +813,7 @@ bool node_friend_mode_set(struct mesh_node *node, bool enable)
 		return false;
 
 	friend = enable ? MESH_MODE_ENABLED : MESH_MODE_DISABLED;
-	res = storage_set_mode(node->jconfig, friend, "friend");
+	res = storage_set_mode(node, friend, "friend");
 
 	if (res) {
 		node->friend = friend;
@@ -1356,14 +1356,14 @@ static void convert_node_to_storage(struct mesh_node *node,
 
 }
 
-static bool create_node_config(struct mesh_node *node)
+static bool create_node_config(struct mesh_node *node, const uint8_t uuid[16])
 {
 	struct mesh_config_node db_node;
 	const struct l_queue_entry *entry;
 	bool res;
 
 	convert_node_to_storage(node, &db_node);
-	res = storage_create_node_config(node, &db_node);
+	res = storage_create_node_config(node, uuid, &db_node);
 
 	/* Free temporarily allocated resources */
 	entry = l_queue_get_entries(db_node.elements);
@@ -1471,16 +1471,16 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 
 	mesh_net_set_iv_index(node->net, iv_idx, ivu);
 
-	if (!mesh_config_write_uint16_hex(node->jconfig, "unicastAddress",
+	if (!mesh_config_write_uint16_hex(node->cfg, "unicastAddress",
 								unicast))
 		return false;
 
 	l_getrandom(node->token, sizeof(node->token));
-	if (!mesh_config_write_token(node->jconfig, node->token))
+	if (!mesh_config_write_token(node->cfg, node->token))
 		return false;
 
 	memcpy(node->dev_key, dev_key, 16);
-	if (!mesh_config_write_device_key(node->jconfig, dev_key))
+	if (!mesh_config_write_device_key(node->cfg, dev_key))
 		return false;
 
 	node->primary = unicast;
@@ -1496,7 +1496,7 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 							MESH_STATUS_SUCCESS)
 			return false;
 
-		if (!mesh_config_net_key_set_phase(node->jconfig, net_key_idx,
+		if (!mesh_config_net_key_set_phase(node->cfg, net_key_idx,
 							KEY_REFRESH_PHASE_TWO))
 			return false;
 	}
@@ -1634,7 +1634,7 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data)
 		set_defaults(node);
 		memcpy(node->uuid, req->data, 16);
 
-		if (!create_node_config(node))
+		if (!create_node_config(node, node->uuid))
 			goto fail;
 
 		cb(node, agent);
@@ -1649,7 +1649,7 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data)
 		set_defaults(node);
 		memcpy(node->uuid, req->data, 16);
 
-		if (!create_node_config(node))
+		if (!create_node_config(node, node->uuid))
 			goto fail;
 
 		/* Generate device and primary network keys */
@@ -2059,14 +2059,14 @@ bool node_add_pending_local(struct mesh_node *node, void *prov_node_info)
 			info->device_key, info->net_index, info->net_key);
 }
 
-void node_jconfig_set(struct mesh_node *node, void *jconfig)
+void node_config_set(struct mesh_node *node, struct mesh_config *cfg)
 {
-	node->jconfig = jconfig;
+	node->cfg = cfg;
 }
 
-void *node_jconfig_get(struct mesh_node *node)
+struct mesh_config *node_config_get(struct mesh_node *node)
 {
-	return node->jconfig;
+	return node->cfg;
 }
 
 void node_path_set(struct mesh_node *node, char *path)
diff --git a/mesh/node.h b/mesh/node.h
index d69887ed1..ee62737fc 100644
--- a/mesh/node.h
+++ b/mesh/node.h
@@ -21,6 +21,8 @@ struct mesh_net;
 struct mesh_node;
 struct mesh_io;
 struct mesh_agent;
+struct mesh_config;
+struct mesh_config_node;
 
 /* To prevent local node JSON cache thrashing, minimum update times */
 #define MIN_SEQ_TRIGGER	32
@@ -67,7 +69,8 @@ int node_get_element_idx(struct mesh_node *node, uint16_t ele_addr);
 struct l_queue *node_get_element_models(struct mesh_node *node, uint8_t ele_idx,
 								int *status);
 uint16_t node_get_crpl(struct mesh_node *node);
-bool node_init_from_storage(struct mesh_node *node, void *data);
+bool node_init_from_storage(struct mesh_node *node, const uint8_t uuid[16],
+					struct mesh_config_node *db_node);
 uint16_t node_generate_comp(struct mesh_node *node, uint8_t *buf, uint16_t sz);
 uint8_t node_lpn_mode_get(struct mesh_node *node);
 bool node_relay_mode_set(struct mesh_node *node, bool enable, uint8_t cnt,
@@ -97,8 +100,8 @@ void node_id_set(struct mesh_node *node, uint16_t node_id);
 uint16_t node_id_get(struct mesh_node *node);
 bool node_dbus_init(struct l_dbus *bus);
 void node_cleanup_all(void);
-void node_jconfig_set(struct mesh_node *node, void *jconfig);
-void *node_jconfig_get(struct mesh_node *node);
+void node_config_set(struct mesh_node *node, struct mesh_config *cfg);
+struct mesh_config *node_config_get(struct mesh_node *node);
 void node_path_set(struct mesh_node *node, char *path);
 char *node_path_get(struct mesh_node *node);
 struct mesh_agent *node_get_agent(struct mesh_node *node);
diff --git a/mesh/storage.c b/mesh/storage.c
index 645d84c97..869c6d70e 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -29,7 +29,6 @@
 #include <libgen.h>
 #include <ftw.h>
 
-#include <json-c/json.h>
 #include <ell/ell.h>
 
 #include "mesh/mesh-defs.h"
@@ -41,7 +40,7 @@
 #include "mesh/storage.h"
 
 struct write_info {
-	json_object *jnode;
+	struct mesh_config *cfg;
 	const char *node_path;
 	void *user_data;
 	mesh_status_func_t cb;
@@ -52,80 +51,41 @@ static const char *bak_ext = ".bak";
 static const char *tmp_ext = ".tmp";
 static const char *storage_dir;
 
-static bool read_node_cb(struct mesh_config_node *db_node, void *user_data)
+static bool read_node_cb(struct mesh_config_node *db_node,
+			const uint8_t uuid[16], struct mesh_config *cfg,
+			void *user_data)
 {
 	struct mesh_node *node = user_data;
 
-	if (!node_init_from_storage(node, db_node)) {
+	if (!node_init_from_storage(node, uuid, db_node)) {
 		node_remove(node);
 		return false;
 	}
 
+	node_config_set(node, cfg);
 	return true;
 }
 
 static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
 {
-	int fd;
-	char *str;
-	struct stat st;
-	ssize_t sz;
-	json_object *jnode = NULL;
 	bool result = false;
 	struct mesh_node *node;
 
-	l_info("Loading configuration from %s", in_file);
-
-	fd = open(in_file, O_RDONLY);
-	if (fd < 0)
-		return false;
-
-	if (fstat(fd, &st) == -1) {
-		close(fd);
-		return false;
-	}
-
-	str = (char *) l_new(char, st.st_size + 1);
-	if (!str) {
-		close(fd);
-		return false;
-	}
-
-	sz = read(fd, str, st.st_size);
-	if (sz != st.st_size) {
-		l_error("Failed to read configuration file %s", in_file);
-		goto done;
-	}
-
-	jnode = json_tokener_parse(str);
-	if (!jnode)
-		goto done;
-
 	node = node_new(uuid);
 
-	result = mesh_config_read_node(jnode, read_node_cb, node);
+	result = mesh_config_load_node(in_file, uuid, read_node_cb, node);
 
-	if (!result) {
-		json_object_put(jnode);
+	if (!result)
 		node_remove(node);
-	}
-
-	node_jconfig_set(node, jnode);
-	node_path_set(node, out_dir);
-
-done:
-	close(fd);
-	if (str)
-		l_free(str);
+	else
+		node_path_set(node, out_dir);
 
 	return result;
 }
 
 bool storage_set_ttl(struct mesh_node *node, uint8_t ttl)
 {
-	json_object *jnode = node_jconfig_get(node);
-
-	if (!mesh_config_write_int(jnode, "defaultTTL", ttl))
+	if (!mesh_config_write_int(node_config_get(node), "defaultTTL", ttl))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -135,9 +95,8 @@ bool storage_set_ttl(struct mesh_node *node, uint8_t ttl)
 bool storage_set_relay(struct mesh_node *node, bool enable,
 				uint8_t count, uint8_t interval)
 {
-	json_object *jnode = node_jconfig_get(node);
-
-	if (!mesh_config_write_relay_mode(jnode, enable, count, interval))
+	if (!mesh_config_write_relay_mode(node_config_get(node), enable, count,
+								interval))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -147,9 +106,8 @@ bool storage_set_relay(struct mesh_node *node, bool enable,
 bool storage_set_transmit_params(struct mesh_node *node, uint8_t count,
 							uint8_t interval)
 {
-	json_object *jnode = node_jconfig_get(node);
-
-	if (!mesh_config_write_net_transmit(jnode, count, interval))
+	if (!mesh_config_write_net_transmit(node_config_get(node), count,
+								interval))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -159,9 +117,7 @@ bool storage_set_transmit_params(struct mesh_node *node, uint8_t count,
 bool storage_set_mode(struct mesh_node *node, uint8_t mode,
 						const char *mode_name)
 {
-	json_object *jnode = node_jconfig_get(node);
-
-	if (!mesh_config_write_mode(jnode, mode_name, mode))
+	if (!mesh_config_write_mode(node_config_get(node), mode_name, mode))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -171,7 +127,7 @@ bool storage_set_mode(struct mesh_node *node, uint8_t mode,
 bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t mod_id,
 				uint16_t app_idx, bool unbind)
 {
-	json_object *jnode;
+	struct mesh_config *cfg;
 	int ele_idx;
 	bool stored, is_vendor = (mod_id > 0xffff);
 
@@ -179,14 +135,14 @@ bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t mod_id,
 	if (ele_idx < 0)
 		return false;
 
-	jnode = node_jconfig_get(node);
+	cfg = node_config_get(node);
 
 	if (unbind)
-		stored = mesh_config_model_binding_del(jnode, ele_idx,
-						is_vendor, mod_id, app_idx);
+		stored = mesh_config_model_binding_del(cfg, ele_idx, is_vendor,
+							mod_id, app_idx);
 	else
-		stored = mesh_config_model_binding_add(jnode, ele_idx,
-						is_vendor, mod_id, app_idx);
+		stored = mesh_config_model_binding_add(cfg, ele_idx, is_vendor,
+							mod_id, app_idx);
 
 	if (stored)
 		storage_save_config(node, true, NULL, NULL);
@@ -197,18 +153,16 @@ bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t mod_id,
 bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
 			uint16_t app_idx, const uint8_t key[16], bool update)
 {
-	json_object *jnode;
+	struct mesh_config *cfg;
 	struct mesh_node *node = mesh_net_node_get(net);
 	bool stored;
 
-	jnode = node_jconfig_get(node);
-	if (!jnode)
-		return false;
+	cfg = node_config_get(node);
 
 	if (update)
-		stored = mesh_config_app_key_update(jnode, app_idx, key);
+		stored = mesh_config_app_key_update(cfg, app_idx, key);
 	else
-		stored = mesh_config_app_key_add(jnode, net_idx, app_idx, key);
+		stored = mesh_config_app_key_add(cfg, net_idx, app_idx, key);
 
 	if (stored)
 		storage_save_config(node, true, NULL, NULL);
@@ -219,14 +173,12 @@ bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
 bool storage_app_key_del(struct mesh_net *net, uint16_t net_idx,
 					uint16_t app_idx)
 {
-	json_object *jnode;
+	struct mesh_config *cfg;
 	struct mesh_node *node = mesh_net_node_get(net);
 
-	jnode = node_jconfig_get(node);
-	if (!jnode)
-		return false;
+	cfg = node_config_get(node);
 
-	if (!mesh_config_app_key_del(jnode, net_idx, app_idx))
+	if (!mesh_config_app_key_del(cfg, net_idx, app_idx))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -237,13 +189,13 @@ bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
 					const uint8_t key[16], bool update)
 {
 	struct mesh_node *node = mesh_net_node_get(net);
-	json_object *jnode = node_jconfig_get(node);
+	struct mesh_config *cfg = node_config_get(node);
 	bool stored;
 
 	if (!update)
-		stored = mesh_config_net_key_add(jnode, net_idx, key);
+		stored = mesh_config_net_key_add(cfg, net_idx, key);
 	else
-		stored = mesh_config_net_key_update(jnode, net_idx, key);
+		stored = mesh_config_net_key_update(cfg, net_idx, key);
 
 	if (stored)
 		storage_save_config(node, true, NULL, NULL);
@@ -254,9 +206,9 @@ bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
 bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx)
 {
 	struct mesh_node *node = mesh_net_node_get(net);
-	json_object *jnode = node_jconfig_get(node);
+	struct mesh_config *cfg = node_config_get(node);
 
-	if (!mesh_config_net_key_del(jnode, net_idx))
+	if (!mesh_config_net_key_del(cfg, net_idx))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -267,9 +219,9 @@ bool storage_set_iv_index(struct mesh_net *net, uint32_t iv_index,
 								bool update)
 {
 	struct mesh_node *node = mesh_net_node_get(net);
-	json_object *jnode = node_jconfig_get(node);
+	struct mesh_config *cfg = node_config_get(node);
 
-	if (!mesh_config_write_iv_index(jnode, iv_index, update))
+	if (!mesh_config_write_iv_index(cfg, iv_index, update))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -280,9 +232,9 @@ bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
 								uint8_t phase)
 {
 	struct mesh_node *node = mesh_net_node_get(net);
-	json_object *jnode = node_jconfig_get(node);
+	struct mesh_config *cfg = node_config_get(node);
 
-	if (!mesh_config_net_key_set_phase(jnode, net_idx, phase))
+	if (!mesh_config_net_key_set_phase(cfg, net_idx, phase))
 		return false;
 
 	storage_save_config(node, true, NULL, NULL);
@@ -292,39 +244,15 @@ bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
 bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq)
 {
 	struct mesh_node *node = mesh_net_node_get(net);
-	json_object *jnode = node_jconfig_get(node);
+	struct mesh_config *cfg = node_config_get(node);
 
-	if (!mesh_config_write_int(jnode, "sequenceNumber", seq))
+	if (!mesh_config_write_int(cfg, "sequenceNumber", seq))
 		return false;
 
 	storage_save_config(node, false, NULL, NULL);
 	return true;
 }
 
-static bool save_config(json_object *jnode, const char *config_name)
-{
-	FILE *outfile;
-	const char *str;
-	bool result = false;
-
-	outfile = fopen(config_name, "w");
-	if (!outfile) {
-		l_error("Failed to save configuration to %s", config_name);
-		return false;
-	}
-
-	str = json_object_to_json_string_ext(jnode, JSON_C_TO_STRING_PRETTY);
-
-	if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
-		l_warn("Incomplete write of mesh configuration");
-	else
-		result = true;
-
-	fclose(outfile);
-
-	return result;
-}
-
 static void idle_save_config(void *user_data)
 {
 	struct write_info *info = user_data;
@@ -337,7 +265,7 @@ static void idle_save_config(void *user_data)
 	remove(tmp);
 
 	l_debug("Storage-Wrote");
-	result = save_config(info->jnode, tmp);
+	result = mesh_config_save_config(info->cfg, tmp);
 
 	if (result) {
 		remove(bak);
@@ -362,7 +290,7 @@ void storage_save_config(struct mesh_node *node, bool no_wait,
 	struct write_info *info;
 
 	info = l_new(struct write_info, 1);
-	info->jnode = node_jconfig_get(node);
+	info->cfg = node_config_get(node);
 	info->node_path = node_path_get(node);
 	info->cb = cb;
 	info->user_data = user_data;
@@ -462,48 +390,47 @@ bool storage_load_nodes(const char *dir_name)
 	return true;
 }
 
-bool storage_create_node_config(struct mesh_node *node, void *data)
+bool storage_create_node_config(struct mesh_node *node, const uint8_t uuid[16],
+					struct mesh_config_node *db_node)
 {
-	struct mesh_config_node *db_node = data;
-	char uuid[33];
+	char uuid_buf[33];
 	char name_buf[PATH_MAX];
-	json_object *jnode;
+	struct mesh_config *cfg;
 	size_t max_len = strlen(cfg_name) + strlen(bak_ext);
 
 	if (!storage_dir)
 		return false;
 
-	jnode = json_object_new_object();
-
-	if (!mesh_config_add_node(jnode, db_node))
+	if (!hex2str((uint8_t *) uuid, 16, uuid_buf, sizeof(uuid_buf)))
 		return false;
 
-	if (!hex2str(node_uuid_get(node), 16, uuid, sizeof(uuid)))
-		goto fail;
-
-	snprintf(name_buf, PATH_MAX, "%s/%s", storage_dir, uuid);
+	snprintf(name_buf, PATH_MAX, "%s/%s", storage_dir, uuid_buf);
 
 	if (strlen(name_buf) + max_len >= PATH_MAX)
-		goto fail;
+		return false;
 
 	/* Create a new directory and node.json file */
 	if (mkdir(name_buf, 0755) != 0)
-		goto fail;
+		return false;
 
 	node_path_set(node, name_buf);
 
-	snprintf(name_buf, PATH_MAX, "%s/%s%s", storage_dir, uuid, cfg_name);
+	snprintf(name_buf, PATH_MAX, "%s/%s%s", storage_dir, uuid_buf,
+								cfg_name);
 	l_debug("New node config %s", name_buf);
 
-	if (!save_config(jnode, name_buf))
-		goto fail;
+	cfg = mesh_config_create(name_buf, uuid, db_node);
+	if (!cfg)
+		return false;
 
-	node_jconfig_set(node, jnode);
+	if (!mesh_config_save_config(cfg, name_buf)) {
+		mesh_config_release(cfg);
+		return false;
+	}
+
+	node_config_set(node, cfg);
 
 	return true;
-fail:
-	json_object_put(jnode);
-	return false;
 }
 
 static int del_fobject(const char *fpath, const struct stat *sb, int typeflag,
@@ -529,17 +456,13 @@ void storage_remove_node_config(struct mesh_node *node)
 {
 	char *node_path, *node_name;
 	char uuid[33];
-	struct json_object *jnode;
 
 	if (!node)
 		return;
 
-	/* Free the node config json object */
-	jnode = node_jconfig_get(node);
-	if (jnode)
-		json_object_put(jnode);
-
-	node_jconfig_set(node, NULL);
+	/* Release node config object */
+	mesh_config_release(node_config_get(node));
+	node_config_set(node, NULL);
 
 	node_path = node_path_get(node);
 	l_debug("Delete node config %s", node_path);
diff --git a/mesh/storage.h b/mesh/storage.h
index a537ddb25..1fa48ad7a 100644
--- a/mesh/storage.h
+++ b/mesh/storage.h
@@ -19,9 +19,11 @@
 
 struct mesh_net;
 struct mesh_node;
+struct mesh_config_node;
 
 bool storage_load_nodes(const char *dir);
-bool storage_create_node_config(struct mesh_node *node, void *db_node);
+bool storage_create_node_config(struct mesh_node *node, const uint8_t uuid[16],
+					struct mesh_config_node *db_node);
 void storage_remove_node_config(struct mesh_node *node);
 void storage_save_config(struct mesh_node *node, bool no_wait,
 					mesh_status_func_t cb, void *user_data);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 06/10 v3] mesh: Replace storage_save_config with mesh_config_save_config
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (4 preceding siblings ...)
  2019-07-14 23:23 ` [PATCH BlueZ 05/10 v3] mesh: Confine dependency on json-c to mesh-config-json.c Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 07/10 v3] mesh: Use mesh_config APIs to store node configuration Inga Stotland
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This moves writing out of node configuration from storage.c down to
mesh-config-<format-specific>.c to allow for more generic storage layout.

New generalized API in mesh-config.h:
mesh_config_save_config(struct mesh_config *cfg, bool no_wait,
				mesh_config_status_func_t cb, void *user_data)

replaces the old one in storage.h:
storage_save_config(struct mesh_node *node, bool no_wait,
					mesh_status_func_t cb, void *user_data)

Currently, only JSON format is supported for storing node configuration:
mesh_config_save_config is implemented in mesh-config-json.c
---
 mesh/mesh-config-json.c | 70 +++++++++++++++++++++++++++++++----
 mesh/mesh-config.h      |  9 +++--
 mesh/node.c             |  6 +--
 mesh/storage.c          | 82 +++++++----------------------------------
 mesh/storage.h          |  2 -
 5 files changed, 84 insertions(+), 85 deletions(-)

diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c
index 096b93249..57b0d6e7b 100644
--- a/mesh/mesh-config-json.c
+++ b/mesh/mesh-config-json.c
@@ -46,6 +46,15 @@ struct mesh_config {
 	uint8_t uuid[16];
 };
 
+struct write_info {
+	struct mesh_config *cfg;
+	void *user_data;
+	mesh_config_status_func_t cb;
+};
+
+static const char *bak_ext = ".bak";
+static const char *tmp_ext = ".tmp";
+
 static bool get_int(json_object *jobj, const char *keyword, int *value)
 {
 	json_object *jvalue;
@@ -1926,7 +1935,7 @@ bool mesh_config_model_sub_del_all(struct mesh_config *cfg, uint16_t addr,
 }
 
 bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
-					mesh_config_node_cb cb, void *user_data)
+				mesh_config_node_func_t cb, void *user_data)
 {
 	int fd;
 	char *str;
@@ -2011,23 +2020,19 @@ void mesh_config_release(struct mesh_config *cfg)
 	l_free(cfg);
 }
 
-bool mesh_config_save_config(struct mesh_config *cfg, const char *fname)
+static bool save_config(json_object *jnode, const char *fname)
 {
 	FILE *outfile;
 	const char *str;
 	bool result = false;
 
-	if (!cfg)
-		return false;
-
 	outfile = fopen(fname, "w");
 	if (!outfile) {
 		l_error("Failed to save configuration to %s", fname);
 		return false;
 	}
 
-	str = json_object_to_json_string_ext(cfg->jnode,
-						JSON_C_TO_STRING_PRETTY);
+	str = json_object_to_json_string_ext(jnode, JSON_C_TO_STRING_PRETTY);
 
 	if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
 		l_warn("Incomplete write of mesh configuration");
@@ -2038,3 +2043,54 @@ bool mesh_config_save_config(struct mesh_config *cfg, const char *fname)
 
 	return result;
 }
+
+static void idle_save_config(void *user_data)
+{
+	struct write_info *info = user_data;
+	char *fname_tmp, *fname_bak, *fname_cfg;
+	bool result = false;
+
+	fname_cfg = info->cfg->node_path;
+	fname_tmp = l_strdup_printf("%s%s", fname_cfg, tmp_ext);
+	fname_bak = l_strdup_printf("%s%s", fname_cfg, bak_ext);
+	remove(fname_tmp);
+
+	result = save_config(info->cfg->jnode, fname_tmp);
+
+	if (result) {
+		remove(fname_bak);
+		rename(fname_cfg, fname_bak);
+		rename(fname_tmp, fname_cfg);
+	}
+
+	remove(fname_tmp);
+
+	l_free(fname_tmp);
+	l_free(fname_bak);
+
+	if (info->cb)
+		info->cb(info->user_data, result);
+
+	l_free(info);
+}
+
+bool mesh_config_save_config(struct mesh_config *cfg, bool no_wait,
+				mesh_config_status_func_t cb, void *user_data)
+{
+	struct write_info *info;
+
+	if (!cfg)
+		return false;
+
+	info = l_new(struct write_info, 1);
+	info->cfg = cfg;
+	info->cb = cb;
+	info->user_data = user_data;
+
+	if (no_wait)
+		idle_save_config(info);
+	else
+		l_idle_oneshot(idle_save_config, info, NULL);
+
+	return true;
+}
diff --git a/mesh/mesh-config.h b/mesh/mesh-config.h
index 8d01e760c..5241dde2d 100644
--- a/mesh/mesh-config.h
+++ b/mesh/mesh-config.h
@@ -104,16 +104,17 @@ struct mesh_config_node {
 	uint8_t dev_key[16];
 	uint8_t token[8];
 };
-
-typedef bool (*mesh_config_node_cb)(struct mesh_config_node *node,
+typedef void (*mesh_config_status_func_t)(void *user_data, bool result);
+typedef bool (*mesh_config_node_func_t)(struct mesh_config_node *node,
 							const uint8_t uuid[16],
 							struct mesh_config *cfg,
 							void *user_data);
 
 bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
-				mesh_config_node_cb cb, void *user_data);
+				mesh_config_node_func_t cb, void *user_data);
 void mesh_config_release(struct mesh_config *cfg);
-bool mesh_config_save_config(struct mesh_config *cfg, const char *fname);
+bool mesh_config_save_config(struct mesh_config *cfg, bool no_wait,
+				mesh_config_status_func_t cb, void *user_data);
 struct mesh_config *mesh_config_create(const char *cfg_path,
 						const uint8_t uuid[16],
 						struct mesh_config_node *node);
diff --git a/mesh/node.c b/mesh/node.c
index 025c7b59d..5f4f95cc4 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -484,12 +484,12 @@ static void cleanup_node(void *data)
 	struct mesh_net *net = node->net;
 
 	/* Save local node configuration */
-	if (node->node_path) {
+	if (node->cfg) {
 
 		/* Preserve the last sequence number */
 		storage_write_sequence_number(net, mesh_net_get_seq_num(net));
 
-		storage_save_config(node, true, NULL, NULL);
+		mesh_config_save_config(node->cfg, true, NULL, NULL);
 	}
 
 	free_node_resources(node);
@@ -1501,7 +1501,7 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 			return false;
 	}
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(node->cfg, true, NULL, NULL);
 
 	/* Initialize configuration server model */
 	mesh_config_srv_init(node, PRIMARY_ELE_IDX);
diff --git a/mesh/storage.c b/mesh/storage.c
index 869c6d70e..15077cb5d 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -39,16 +39,8 @@
 #include "mesh/util.h"
 #include "mesh/storage.h"
 
-struct write_info {
-	struct mesh_config *cfg;
-	const char *node_path;
-	void *user_data;
-	mesh_status_func_t cb;
-};
-
 static const char *cfg_name = "/node.json";
 static const char *bak_ext = ".bak";
-static const char *tmp_ext = ".tmp";
 static const char *storage_dir;
 
 static bool read_node_cb(struct mesh_config_node *db_node,
@@ -88,7 +80,7 @@ bool storage_set_ttl(struct mesh_node *node, uint8_t ttl)
 	if (!mesh_config_write_int(node_config_get(node), "defaultTTL", ttl))
 		return false;
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(node_config_get(node), true, NULL, NULL);
 	return true;
 }
 
@@ -99,7 +91,7 @@ bool storage_set_relay(struct mesh_node *node, bool enable,
 								interval))
 		return false;
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(node_config_get(node), true, NULL, NULL);
 	return true;
 }
 
@@ -110,7 +102,7 @@ bool storage_set_transmit_params(struct mesh_node *node, uint8_t count,
 								interval))
 		return false;
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(node_config_get(node), true, NULL, NULL);
 	return true;
 }
 
@@ -120,7 +112,7 @@ bool storage_set_mode(struct mesh_node *node, uint8_t mode,
 	if (!mesh_config_write_mode(node_config_get(node), mode_name, mode))
 		return false;
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(node_config_get(node), true, NULL, NULL);
 	return true;
 }
 
@@ -145,7 +137,7 @@ bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t mod_id,
 							mod_id, app_idx);
 
 	if (stored)
-		storage_save_config(node, true, NULL, NULL);
+		mesh_config_save_config(cfg, true, NULL, NULL);
 
 	return stored;
 }
@@ -165,7 +157,7 @@ bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
 		stored = mesh_config_app_key_add(cfg, net_idx, app_idx, key);
 
 	if (stored)
-		storage_save_config(node, true, NULL, NULL);
+		mesh_config_save_config(cfg, true, NULL, NULL);
 
 	return stored;
 }
@@ -181,7 +173,7 @@ bool storage_app_key_del(struct mesh_net *net, uint16_t net_idx,
 	if (!mesh_config_app_key_del(cfg, net_idx, app_idx))
 		return false;
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(cfg, true, NULL, NULL);
 	return true;
 }
 
@@ -198,7 +190,7 @@ bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
 		stored = mesh_config_net_key_update(cfg, net_idx, key);
 
 	if (stored)
-		storage_save_config(node, true, NULL, NULL);
+		mesh_config_save_config(cfg, true, NULL, NULL);
 
 	return stored;
 }
@@ -211,7 +203,7 @@ bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx)
 	if (!mesh_config_net_key_del(cfg, net_idx))
 		return false;
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(cfg, true, NULL, NULL);
 	return true;
 }
 
@@ -224,7 +216,7 @@ bool storage_set_iv_index(struct mesh_net *net, uint32_t iv_index,
 	if (!mesh_config_write_iv_index(cfg, iv_index, update))
 		return false;
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(cfg, true, NULL, NULL);
 	return true;
 }
 
@@ -237,7 +229,7 @@ bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
 	if (!mesh_config_net_key_set_phase(cfg, net_idx, phase))
 		return false;
 
-	storage_save_config(node, true, NULL, NULL);
+	mesh_config_save_config(cfg, true, NULL, NULL);
 	return true;
 }
 
@@ -249,58 +241,10 @@ bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq)
 	if (!mesh_config_write_int(cfg, "sequenceNumber", seq))
 		return false;
 
-	storage_save_config(node, false, NULL, NULL);
+	mesh_config_save_config(cfg, false, NULL, NULL);
 	return true;
 }
 
-static void idle_save_config(void *user_data)
-{
-	struct write_info *info = user_data;
-	char *tmp, *bak, *cfg;
-	bool result = false;
-
-	cfg = l_strdup_printf("%s%s", info->node_path, cfg_name);
-	tmp = l_strdup_printf("%s%s", cfg, tmp_ext);
-	bak = l_strdup_printf("%s%s", cfg, bak_ext);
-	remove(tmp);
-
-	l_debug("Storage-Wrote");
-	result = mesh_config_save_config(info->cfg, tmp);
-
-	if (result) {
-		remove(bak);
-		rename(cfg, bak);
-		rename(tmp, cfg);
-	}
-
-	remove(tmp);
-	l_free(tmp);
-	l_free(bak);
-	l_free(cfg);
-
-	if (info->cb)
-		info->cb(info->user_data, result);
-
-	l_free(info);
-}
-
-void storage_save_config(struct mesh_node *node, bool no_wait,
-					mesh_status_func_t cb, void *user_data)
-{
-	struct write_info *info;
-
-	info = l_new(struct write_info, 1);
-	info->cfg = node_config_get(node);
-	info->node_path = node_path_get(node);
-	info->cb = cb;
-	info->user_data = user_data;
-
-	if (no_wait)
-		idle_save_config(info);
-	else
-		l_idle_oneshot(idle_save_config, info, NULL);
-}
-
 static int create_dir(const char *dir_name)
 {
 	struct stat st;
@@ -423,7 +367,7 @@ bool storage_create_node_config(struct mesh_node *node, const uint8_t uuid[16],
 	if (!cfg)
 		return false;
 
-	if (!mesh_config_save_config(cfg, name_buf)) {
+	if (!mesh_config_save_config(cfg, true, NULL, NULL)) {
 		mesh_config_release(cfg);
 		return false;
 	}
diff --git a/mesh/storage.h b/mesh/storage.h
index 1fa48ad7a..f70544ad6 100644
--- a/mesh/storage.h
+++ b/mesh/storage.h
@@ -25,8 +25,6 @@ bool storage_load_nodes(const char *dir);
 bool storage_create_node_config(struct mesh_node *node, const uint8_t uuid[16],
 					struct mesh_config_node *db_node);
 void storage_remove_node_config(struct mesh_node *node);
-void storage_save_config(struct mesh_node *node, bool no_wait,
-					mesh_status_func_t cb, void *user_data);
 bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t id,
 						uint16_t app_idx, bool unbind);
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 07/10 v3] mesh: Use mesh_config APIs to store node configuration
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (5 preceding siblings ...)
  2019-07-14 23:23 ` [PATCH BlueZ 06/10 v3] mesh: Replace storage_save_config with mesh_config_save_config Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 08/10 v3] mesh: Manage node config directory in mesh-config Inga Stotland
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This eliminates storage_set...() routines as an intermediate
layer between mesh_config layer and the rest of the daemon when
storing updated node configuration values.
For the JSON based implementation, each call to mesh_config_write...()
routines results in writing to the node configuration file.
---
 mesh/appkey.c           |  19 +++-
 mesh/cfgmod-server.c    |   4 +-
 mesh/mesh-config-json.c | 203 +++++++++++++++++++---------------------
 mesh/mesh-config.h      |  11 +--
 mesh/model.c            |  15 ++-
 mesh/net.c              |  26 +++--
 mesh/node.c             |  23 ++---
 mesh/storage.c          | 170 ---------------------------------
 mesh/storage.h          |  24 -----
 9 files changed, 155 insertions(+), 340 deletions(-)

diff --git a/mesh/appkey.c b/mesh/appkey.c
index 412a2c48c..286a77e98 100644
--- a/mesh/appkey.c
+++ b/mesh/appkey.c
@@ -31,7 +31,7 @@
 #include "mesh/crypto.h"
 #include "mesh/util.h"
 #include "mesh/model.h"
-#include "mesh/storage.h"
+#include "mesh/mesh-config.h"
 #include "mesh/appkey.h"
 
 struct mesh_app_key {
@@ -368,6 +368,7 @@ int appkey_key_update(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
 	struct mesh_app_key *key;
 	struct l_queue *app_keys;
 	uint8_t phase = KEY_REFRESH_PHASE_NONE;
+	struct mesh_node *node;
 
 	app_keys = mesh_net_get_app_keys(net);
 	if (!app_keys)
@@ -395,7 +396,10 @@ int appkey_key_update(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
 	if (!set_key(key, app_idx, new_key, true))
 		return MESH_STATUS_INSUFF_RESOURCES;
 
-	if (!storage_app_key_add(net, net_idx, app_idx, new_key, true))
+	node = mesh_net_node_get(net);
+
+	if (!mesh_config_app_key_update(node_config_get(node), app_idx,
+								new_key))
 		return MESH_STATUS_STORAGE_FAIL;
 
 	return MESH_STATUS_SUCCESS;
@@ -406,6 +410,7 @@ int appkey_key_add(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
 {
 	struct mesh_app_key *key;
 	struct l_queue *app_keys;
+	struct mesh_node *node;
 
 	app_keys = mesh_net_get_app_keys(net);
 	if (!app_keys)
@@ -432,7 +437,10 @@ int appkey_key_add(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx,
 		return MESH_STATUS_INSUFF_RESOURCES;
 	}
 
-	if (!storage_app_key_add(net, net_idx, app_idx, new_key, false)) {
+	node = mesh_net_node_get(net);
+
+	if (!mesh_config_app_key_add(node_config_get(node), net_idx, app_idx,
+								new_key)) {
 		appkey_key_free(key);
 		return MESH_STATUS_STORAGE_FAIL;
 	}
@@ -451,6 +459,7 @@ int appkey_key_delete(struct mesh_net *net, uint16_t net_idx,
 {
 	struct mesh_app_key *key;
 	struct l_queue *app_keys;
+	struct mesh_node *node;
 
 	app_keys = mesh_net_get_app_keys(net);
 	if (!app_keys)
@@ -469,7 +478,9 @@ int appkey_key_delete(struct mesh_net *net, uint16_t net_idx,
 	l_queue_remove(app_keys, key);
 	appkey_key_free(key);
 
-	if (!storage_app_key_del(net, net_idx, app_idx))
+	node = mesh_net_node_get(net);
+
+	if (!mesh_config_app_key_del(node_config_get(node), net_idx, app_idx))
 		return MESH_STATUS_STORAGE_FAIL;
 
 	return MESH_STATUS_SUCCESS;
diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index c73e63b4e..033ab41ea 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -876,7 +876,9 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst,
 
 		count = (pkt[0] >> 5) + 1;
 		interval = ((pkt[0] & 0x1f) + 1) * 10;
-		if (storage_set_transmit_params(node, count, interval))
+
+		if (mesh_config_write_net_transmit(node_config_get(node), count,
+								interval))
 			mesh_net_transmit_params_set(net, count, interval);
 		/* Fall Through */
 
diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c
index 57b0d6e7b..62c674afd 100644
--- a/mesh/mesh-config-json.c
+++ b/mesh/mesh-config-json.c
@@ -55,6 +55,30 @@ struct write_info {
 static const char *bak_ext = ".bak";
 static const char *tmp_ext = ".tmp";
 
+static bool save_config(json_object *jnode, const char *fname)
+{
+	FILE *outfile;
+	const char *str;
+	bool result = false;
+
+	outfile = fopen(fname, "w");
+	if (!outfile) {
+		l_error("Failed to save configuration to %s", fname);
+		return false;
+	}
+
+	str = json_object_to_json_string_ext(jnode, JSON_C_TO_STRING_PRETTY);
+
+	if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
+		l_warn("Incomplete write of mesh configuration");
+	else
+		result = true;
+
+	fclose(outfile);
+
+	return result;
+}
+
 static bool get_int(json_object *jobj, const char *keyword, int *value)
 {
 	json_object *jvalue;
@@ -511,7 +535,8 @@ bool mesh_config_net_key_add(struct mesh_config *cfg, uint16_t idx,
 
 	json_object_array_add(jarray, jentry);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
+
 fail:
 	if (jentry)
 		json_object_put(jentry);
@@ -552,7 +577,7 @@ bool mesh_config_net_key_update(struct mesh_config *cfg, uint16_t idx,
 	json_object_object_add(jentry, "keyRefresh",
 				json_object_new_int(KEY_REFRESH_PHASE_ONE));
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
@@ -564,6 +589,7 @@ bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
 
 	jnode = cfg->jnode;
 
+	/* TODO: Decide if we treat this as an error: no network keys??? */
 	if (!json_object_object_get_ex(jnode, "netKeys", &jarray))
 		return true;
 
@@ -573,7 +599,9 @@ bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
 
 	if (json_object_array_length(jarray) == 1) {
 		json_object_object_del(jnode, "netKeys");
-		return true;
+		/* TODO: Do we raise an error here? */
+		l_warn("Removing the last network key! Zero keys left.");
+		return save_config(jnode, cfg->node_path);
 	}
 
 	/*
@@ -588,23 +616,23 @@ bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
 	json_object_object_del(jnode, "netKeys");
 	json_object_object_add(jnode, "netKeys", jarray_new);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 bool mesh_config_write_device_key(struct mesh_config *cfg, uint8_t *key)
 {
-	if (!cfg)
+	if (!cfg || !add_key_value(cfg->jnode, "deviceKey", key))
 		return false;
 
-	return add_key_value(cfg->jnode, "deviceKey", key);
+	return save_config(cfg->jnode, cfg->node_path);
 }
 
 bool mesh_config_write_token(struct mesh_config *cfg, uint8_t *token)
 {
-	if (!cfg)
+	if (!cfg || !add_u64_value(cfg->jnode, "token", token))
 		return false;
 
-	return add_u64_value(cfg->jnode, "token", token);
+	return save_config(cfg->jnode, cfg->node_path);
 }
 
 bool mesh_config_app_key_add(struct mesh_config *cfg, uint16_t net_idx,
@@ -656,7 +684,8 @@ bool mesh_config_app_key_add(struct mesh_config *cfg, uint16_t net_idx,
 
 	json_object_array_add(jarray, jentry);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
+
 fail:
 
 	if (jentry)
@@ -690,9 +719,14 @@ bool mesh_config_app_key_update(struct mesh_config *cfg, uint16_t app_idx,
 	str = json_object_get_string(jstring);
 	jstring = json_object_new_string(str);
 	json_object_object_add(jentry, "oldKey", jstring);
+
 	json_object_object_del(jentry, "key");
 
-	return add_key_value(jentry, "key", key);
+	/* TODO: "Rewind" if add_key_value fails */
+	if (!add_key_value(jentry, "key", key))
+		return false;
+
+	return save_config(jnode, cfg->node_path);
 }
 
 bool mesh_config_app_key_del(struct mesh_config *cfg, uint16_t net_idx,
@@ -729,7 +763,7 @@ bool mesh_config_app_key_del(struct mesh_config *cfg, uint16_t net_idx,
 	json_object_object_del(jnode, "appKeys");
 	json_object_object_add(jnode, "appKeys", jarray_new);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 bool mesh_config_model_binding_add(struct mesh_config *cfg, uint8_t ele_idx,
@@ -769,7 +803,7 @@ bool mesh_config_model_binding_add(struct mesh_config *cfg, uint8_t ele_idx,
 
 	json_object_array_add(jarray, jstring);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 bool mesh_config_model_binding_del(struct mesh_config *cfg, uint8_t ele_idx,
@@ -813,7 +847,7 @@ bool mesh_config_model_binding_del(struct mesh_config *cfg, uint8_t ele_idx,
 	json_object_object_del(jmodel, "bind");
 	json_object_object_add(jmodel, "bind", jarray_new);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 static void free_model(void *data)
@@ -1345,22 +1379,12 @@ static bool write_uint16_hex(json_object *jobj, const char *desc,
 	return true;
 }
 
-bool mesh_config_write_uint16_hex(struct mesh_config *cfg, const char *desc,
-								uint16_t value)
-{
-	if (!cfg)
-		return false;
-
-	return write_uint16_hex(cfg->jnode, desc, value);
-}
-
-static bool write_uint32_hex(json_object *jobj, const char *desc,
-								uint32_t value)
+static bool write_uint32_hex(json_object *jobj, const char *desc, uint32_t val)
 {
 	json_object *jstring;
 	char buf[9];
 
-	snprintf(buf, 9, "%8.8x", value);
+	snprintf(buf, 9, "%8.8x", val);
 	jstring = json_object_new_string(buf);
 	if (!jstring)
 		return false;
@@ -1369,22 +1393,13 @@ static bool write_uint32_hex(json_object *jobj, const char *desc,
 	return true;
 }
 
-bool mesh_config_write_uint32_hex(struct mesh_config *cfg, const char *desc,
-								uint32_t value)
-{
-	if (!cfg)
-		return false;
-
-	return write_uint32_hex(cfg->jnode, desc, value);
-}
-
-static bool write_int(json_object *jobj, const char *keyword, int value)
+static bool write_int(json_object *jobj, const char *keyword, int val)
 {
 	json_object *jvalue;
 
 	json_object_object_del(jobj, keyword);
 
-	jvalue = json_object_new_int(value);
+	jvalue = json_object_new_int(val);
 	if (!jvalue)
 		return false;
 
@@ -1392,35 +1407,6 @@ static bool write_int(json_object *jobj, const char *keyword, int value)
 	return true;
 }
 
-bool mesh_config_write_int(struct mesh_config *cfg, const char *keyword,
-								int value)
-{
-	if (!cfg)
-		return false;
-
-	return write_int(cfg->jnode, keyword, value);
-}
-
-bool mesh_config_write_bool(struct mesh_config *cfg, const char *keyword,
-								bool value)
-{
-	json_object *jnode, *jvalue;
-
-	if (!cfg)
-		return false;
-
-	jnode = cfg->jnode;
-
-	json_object_object_del(jnode, keyword);
-
-	jvalue = json_object_new_boolean(value);
-	if (!jvalue)
-		return false;
-
-	json_object_object_add(jnode, keyword, jvalue);
-	return true;
-}
-
 static const char *mode_to_string(int mode)
 {
 	switch (mode) {
@@ -1450,10 +1436,10 @@ static bool write_mode(json_object *jobj, const char *keyword, int value)
 bool mesh_config_write_mode(struct mesh_config *cfg, const char *keyword,
 								int value)
 {
-	if (!cfg)
+	if (!cfg || !write_mode(cfg->jnode, keyword, value))
 		return false;
 
-	return write_mode(cfg->jnode, keyword, value);
+	return save_config(cfg->jnode, cfg->node_path);
 }
 
 static bool write_relay_mode(json_object *jobj, uint8_t mode,
@@ -1484,14 +1470,22 @@ fail:
 	return false;
 }
 
+bool mesh_config_write_unicast(struct mesh_config *cfg, uint16_t unicast)
+{
+	if (!cfg || !write_uint16_hex(cfg->jnode, "unicastAddress", unicast))
+		return false;
+
+	return save_config(cfg->jnode, cfg->node_path);
+}
+
 bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode,
 					uint8_t count, uint16_t interval)
 {
 
-	if (!cfg)
+	if (!cfg || !write_relay_mode(cfg->jnode, mode, count, interval))
 		return false;
 
-	return write_relay_mode(cfg->jnode, mode, count, interval);
+	return save_config(cfg->jnode, cfg->node_path);
 }
 
 bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
@@ -1501,9 +1495,8 @@ bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
 
 	if (!cfg)
 		return false;
-	jnode = cfg->jnode;
 
-	json_object_object_del(jnode, "retransmit");
+	jnode = cfg->jnode;
 
 	jretransmit = json_object_new_object();
 	if (jretransmit)
@@ -1515,9 +1508,11 @@ bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
 	if (!write_int(jretransmit, "interval", interval))
 		goto fail;
 
+	json_object_object_del(jnode, "retransmit");
 	json_object_object_add(jnode, "retransmit", jretransmit);
 
-	return true;
+	return save_config(cfg->jnode, cfg->node_path);
+
 fail:
 	json_object_put(jretransmit);
 	return false;
@@ -1541,7 +1536,7 @@ bool mesh_config_write_iv_index(struct mesh_config *cfg, uint32_t idx,
 	if (!write_int(jnode, "IVupdate", tmp))
 		return false;
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 static void add_model(void *a, void *b)
@@ -1719,7 +1714,7 @@ bool mesh_config_net_key_set_phase(struct mesh_config *cfg, uint16_t idx,
 		finish_key_refresh(jnode, idx);
 	}
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t addr,
@@ -1783,7 +1778,8 @@ bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t addr,
 	json_object_object_add(jpub, "retransmit", jretransmit);
 	json_object_object_add(jmodel, "publish", jpub);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
+
 fail:
 	json_object_put(jpub);
 	return false;
@@ -1811,11 +1807,11 @@ static bool delete_model_property(json_object *jnode, uint16_t addr,
 bool mesh_config_model_pub_del(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor)
 {
-	if (!cfg)
+	if (!cfg || !delete_model_property(cfg->jnode, addr, mod_id, vendor,
+								"publish"))
 		return false;
 
-	return delete_model_property(cfg->jnode, addr, mod_id, vendor,
-								"publish");
+	return save_config(cfg->jnode, cfg->node_path);
 }
 
 bool mesh_config_model_sub_add(struct mesh_config *cfg, uint16_t addr,
@@ -1866,7 +1862,7 @@ bool mesh_config_model_sub_add(struct mesh_config *cfg, uint16_t addr,
 
 	json_object_array_add(jarray, jstring);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 bool mesh_config_model_sub_del(struct mesh_config *cfg, uint16_t addr,
@@ -1921,17 +1917,34 @@ bool mesh_config_model_sub_del(struct mesh_config *cfg, uint16_t addr,
 	json_object_object_del(jmodel, "subscribe");
 	json_object_object_add(jmodel, "subscribe", jarray_new);
 
-	return true;
+	return save_config(jnode, cfg->node_path);
 }
 
 bool mesh_config_model_sub_del_all(struct mesh_config *cfg, uint16_t addr,
 						uint32_t mod_id, bool vendor)
 {
-	if (!cfg)
+	if (!cfg || !delete_model_property(cfg->jnode, addr, mod_id, vendor,
+								"subscribe"))
 		return false;
 
-	return delete_model_property(cfg->jnode, addr, mod_id, vendor,
-								"subscribe");
+	return save_config(cfg->jnode, cfg->node_path);
+}
+
+bool mesh_config_write_seq_number(struct mesh_config *cfg, uint32_t seq)
+{
+	if (!cfg || !write_int(cfg->jnode, "sequenceNumber", seq))
+		return false;
+
+	mesh_config_save_config(cfg, false, NULL, NULL);
+	return true;
+}
+
+bool mesh_config_write_ttl(struct mesh_config *cfg, uint8_t ttl)
+{
+	if (!cfg || !write_int(cfg->jnode, "defaultTTL", ttl))
+		return false;
+
+	return save_config(cfg->jnode, cfg->node_path);
 }
 
 bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
@@ -2020,30 +2033,6 @@ void mesh_config_release(struct mesh_config *cfg)
 	l_free(cfg);
 }
 
-static bool save_config(json_object *jnode, const char *fname)
-{
-	FILE *outfile;
-	const char *str;
-	bool result = false;
-
-	outfile = fopen(fname, "w");
-	if (!outfile) {
-		l_error("Failed to save configuration to %s", fname);
-		return false;
-	}
-
-	str = json_object_to_json_string_ext(jnode, JSON_C_TO_STRING_PRETTY);
-
-	if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
-		l_warn("Incomplete write of mesh configuration");
-	else
-		result = true;
-
-	fclose(outfile);
-
-	return result;
-}
-
 static void idle_save_config(void *user_data)
 {
 	struct write_info *info = user_data;
diff --git a/mesh/mesh-config.h b/mesh/mesh-config.h
index 5241dde2d..83ba33bf9 100644
--- a/mesh/mesh-config.h
+++ b/mesh/mesh-config.h
@@ -127,16 +127,11 @@ bool mesh_config_write_network_key(struct mesh_config *cfg, uint16_t idx,
 				uint8_t *key, uint8_t *new_key, int phase);
 bool mesh_config_write_app_key(struct mesh_config *cfg, uint16_t net_idx,
 			uint16_t app_idx, uint8_t *key, uint8_t *new_key);
-bool mesh_config_write_int(struct mesh_config *cfg,
-						const char *keyword, int value);
-bool mesh_config_write_uint16_hex(struct mesh_config *cfg, const char *desc,
-								uint16_t value);
-bool mesh_config_write_uint32_hex(struct mesh_config *cfg, const char *desc,
-								uint32_t value);
-bool mesh_config_write_bool(struct mesh_config *cfg, const char *keyword,
-								bool value);
+bool mesh_config_write_seq_number(struct mesh_config *cfg, uint32_t seq);
+bool mesh_config_write_unicast(struct mesh_config *cfg, uint16_t unicast);
 bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode,
 					uint8_t count, uint16_t interval);
+bool mesh_config_write_ttl(struct mesh_config *cfg, uint8_t ttl);
 bool mesh_config_write_mode(struct mesh_config *cfg, const char *keyword,
 								int value);
 bool mesh_config_model_binding_add(struct mesh_config *cfg, uint8_t ele_idx,
diff --git a/mesh/model.c b/mesh/model.c
index 0f10727b4..ef62a223a 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -532,7 +532,8 @@ static int update_binding(struct mesh_node *node, uint16_t addr, uint32_t id,
 {
 	int status;
 	struct mesh_model *mod;
-	bool is_present;
+	bool is_present, is_vendor;
+	uint8_t ele_idx;
 
 	mod = find_model(node, addr, id, &status);
 	if (!mod) {
@@ -540,7 +541,8 @@ static int update_binding(struct mesh_node *node, uint16_t addr, uint32_t id,
 		return status;
 	}
 
-	id = (id >= VENDOR_ID_MASK) ? (id & 0xffff) : id;
+	is_vendor = id < VENDOR_ID_MASK && id > 0xffff;
+	id = !is_vendor ? (id & 0xffff) : id;
 
 	if (id == CONFIG_SRV_MODEL || id == CONFIG_CLI_MODEL)
 		return MESH_STATUS_INVALID_MODEL;
@@ -556,10 +558,12 @@ static int update_binding(struct mesh_node *node, uint16_t addr, uint32_t id,
 	if (is_present && !unbind)
 		return MESH_STATUS_SUCCESS;
 
+	ele_idx = (uint8_t) node_get_element_idx(node, addr);
+
 	if (unbind) {
 		model_unbind_idx(node, mod, app_idx);
-
-		if (!storage_model_bind(node, addr, id, app_idx, true))
+		if (!mesh_config_model_binding_del(node_config_get(node),
+					ele_idx, is_vendor, id, app_idx))
 			return MESH_STATUS_STORAGE_FAIL;
 
 		return MESH_STATUS_SUCCESS;
@@ -568,7 +572,8 @@ static int update_binding(struct mesh_node *node, uint16_t addr, uint32_t id,
 	if (l_queue_length(mod->bindings) >= MAX_BINDINGS)
 		return MESH_STATUS_INSUFF_RESOURCES;
 
-	if (!storage_model_bind(node, addr, id, app_idx, false))
+	if (!mesh_config_model_binding_add(node_config_get(node),
+					ele_idx, is_vendor, id, app_idx))
 		return MESH_STATUS_STORAGE_FAIL;
 
 	model_bind_idx(node, mod, app_idx);
diff --git a/mesh/net.c b/mesh/net.c
index a5693f154..f7f37675b 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -33,7 +33,7 @@
 #include "mesh/net.h"
 #include "mesh/mesh-io.h"
 #include "mesh/friend.h"
-#include "mesh/storage.h"
+#include "mesh/mesh-config.h"
 #include "mesh/model.h"
 #include "mesh/appkey.h"
 
@@ -971,7 +971,7 @@ int mesh_net_del_key(struct mesh_net *net, uint16_t idx)
 	l_queue_remove(net->subnets, subnet);
 	subnet_free(subnet);
 
-	if (!storage_net_key_del(net, idx))
+	if (!mesh_config_net_key_del(node_config_get(net->node), idx))
 		return MESH_STATUS_STORAGE_FAIL;
 
 	return MESH_STATUS_SUCCESS;
@@ -1024,7 +1024,7 @@ int mesh_net_add_key(struct mesh_net *net, uint16_t idx, const uint8_t *value)
 	if (!subnet)
 		return MESH_STATUS_INSUFF_RESOURCES;
 
-	if (!storage_net_key_add(net, idx, value, false)) {
+	if (!mesh_config_net_key_add(node_config_get(net->node), idx, value)) {
 		l_queue_remove(net->subnets, subnet);
 		subnet_free(subnet);
 		return MESH_STATUS_STORAGE_FAIL;
@@ -2662,7 +2662,8 @@ static int key_refresh_phase_two(struct mesh_net *net, uint16_t idx)
 	else
 		l_queue_foreach(net->friends, frnd_kr_phase2, net);
 
-	storage_set_key_refresh_phase(net, idx, KEY_REFRESH_PHASE_TWO);
+	mesh_config_net_key_set_phase(node_config_get(net->node), idx,
+						KEY_REFRESH_PHASE_TWO);
 
 	return MESH_STATUS_SUCCESS;
 }
@@ -2697,7 +2698,8 @@ static int key_refresh_finish(struct mesh_net *net, uint16_t idx)
 	else
 		l_queue_foreach(net->friends, frnd_kr_phase3, net);
 
-	storage_set_key_refresh_phase(net, idx, KEY_REFRESH_PHASE_NONE);
+	mesh_config_net_key_set_phase(node_config_get(net->node), idx,
+							KEY_REFRESH_PHASE_NONE);
 
 	return MESH_STATUS_SUCCESS;
 }
@@ -2749,7 +2751,8 @@ static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
 			net->iv_upd_state = IV_UPD_NORMAL;
 		}
 
-		storage_set_iv_index(net, iv_index, net->iv_upd_state);
+		mesh_config_write_iv_index(node_config_get(net->node), iv_index,
+							net->iv_upd_state);
 
 		/* Figure out the key refresh phase */
 		if (kr_transition) {
@@ -2771,7 +2774,8 @@ static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
 		net->iv_upd_state = IV_UPD_UPDATING;
 		net->iv_update_timeout = l_timeout_create(IV_IDX_UPD_MIN,
 							iv_upd_to, net, NULL);
-		storage_set_iv_index(net, iv_index, net->iv_upd_state);
+		mesh_config_write_iv_index(node_config_get(net->node), iv_index,
+							net->iv_upd_state);
 	} else if (iv_update && iv_index != net->iv_index) {
 		l_error("Update attempted too soon (iv idx already updated)");
 		return;
@@ -2784,7 +2788,8 @@ static void update_iv_kr_state(struct mesh_subnet *subnet, uint32_t iv_index,
 	if (iv_index > net->iv_index) {
 		l_queue_clear(net->msg_cache, mesh_msg_free);
 		net->iv_index = iv_index;
-		storage_set_iv_index(net, iv_index, net->iv_upd_state);
+		mesh_config_write_iv_index(node_config_get(net->node), iv_index,
+							net->iv_upd_state);
 	}
 
 	/* Figure out the key refresh phase */
@@ -3122,7 +3127,8 @@ bool mesh_net_iv_index_update(struct mesh_net *net)
 	mesh_net_flush_msg_queues(net);
 	net->iv_upd_state = IV_UPD_UPDATING;
 	net->iv_index++;
-	if (!storage_set_iv_index(net, net->iv_index, IV_UPD_UPDATING))
+	if (!mesh_config_write_iv_index(node_config_get(net->node),
+					net->iv_index, IV_UPD_UPDATING))
 		return false;
 
 	l_queue_foreach(net->subnets, set_network_beacon, net);
@@ -3739,7 +3745,7 @@ int mesh_net_update_key(struct mesh_net *net, uint16_t idx,
 
 	l_info("key refresh phase 1: Key ID %d", subnet->net_key_upd);
 
-	if (!storage_net_key_add(net, idx, value, true))
+	if (!mesh_config_net_key_update(node_config_get(net->node), idx, value))
 		return MESH_STATUS_STORAGE_FAIL;
 
 	subnet->kr_phase = KEY_REFRESH_PHASE_ONE;
diff --git a/mesh/node.c b/mesh/node.c
index 5f4f95cc4..d90ca2ad1 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -487,7 +487,8 @@ static void cleanup_node(void *data)
 	if (node->cfg) {
 
 		/* Preserve the last sequence number */
-		storage_write_sequence_number(net, mesh_net_get_seq_num(net));
+		mesh_config_write_seq_number(node->cfg,
+						mesh_net_get_seq_num(net));
 
 		mesh_config_save_config(node->cfg, true, NULL, NULL);
 	}
@@ -532,7 +533,8 @@ bool node_app_key_delete(struct mesh_net *net, uint16_t addr,
 
 		mesh_model_app_key_delete(node, ele->models, app_idx);
 	}
-	return true;
+
+	return mesh_config_app_key_del(node->cfg, net_idx, app_idx);
 }
 
 uint16_t node_get_primary(struct mesh_node *node)
@@ -613,7 +615,7 @@ bool node_default_ttl_set(struct mesh_node *node, uint8_t ttl)
 	if (!node)
 		return false;
 
-	res = storage_set_ttl(node, ttl);
+	res = mesh_config_write_ttl(node->cfg, ttl);
 
 	if (res) {
 		node->ttl = ttl;
@@ -660,7 +662,7 @@ bool node_set_sequence_number(struct mesh_node *node, uint32_t seq)
 
 	node->upd_sec = write_time.tv_sec;
 
-	return storage_write_sequence_number(node->net, seq);
+	return mesh_config_write_seq_number(node->cfg, seq);
 }
 
 uint32_t node_get_sequence_number(struct mesh_node *node)
@@ -737,7 +739,7 @@ bool node_relay_mode_set(struct mesh_node *node, bool enable, uint8_t cnt,
 	if (!node || node->relay.mode == MESH_MODE_UNSUPPORTED)
 		return false;
 
-	res = storage_set_relay(node, enable, cnt, interval);
+	res = mesh_config_write_relay_mode(node->cfg, enable, cnt, interval);
 
 	if (res) {
 		node->relay.mode = enable ? MESH_MODE_ENABLED :
@@ -759,7 +761,7 @@ bool node_proxy_mode_set(struct mesh_node *node, bool enable)
 		return false;
 
 	proxy = enable ? MESH_MODE_ENABLED : MESH_MODE_DISABLED;
-	res = storage_set_mode(node, proxy, "proxy");
+	res = mesh_config_write_mode(node->cfg, "proxy", proxy);
 
 	if (res) {
 		node->proxy = proxy;
@@ -786,7 +788,7 @@ bool node_beacon_mode_set(struct mesh_node *node, bool enable)
 		return false;
 
 	beacon = enable ? MESH_MODE_ENABLED : MESH_MODE_DISABLED;
-	res = storage_set_mode(node, beacon, "beacon");
+	res = mesh_config_write_mode(node->cfg, "beacon", beacon);
 
 	if (res) {
 		node->beacon = beacon;
@@ -813,7 +815,7 @@ bool node_friend_mode_set(struct mesh_node *node, bool enable)
 		return false;
 
 	friend = enable ? MESH_MODE_ENABLED : MESH_MODE_DISABLED;
-	res = storage_set_mode(node, friend, "friend");
+	res = mesh_config_write_mode(node->cfg, "friend", friend);
 
 	if (res) {
 		node->friend = friend;
@@ -1466,13 +1468,12 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 
 	l_queue_push_tail(nodes, node);
 
-	if (!storage_set_iv_index(node->net, iv_idx, ivu))
+	if (!mesh_config_write_iv_index(node->cfg, iv_idx, ivu))
 		return false;
 
 	mesh_net_set_iv_index(node->net, iv_idx, ivu);
 
-	if (!mesh_config_write_uint16_hex(node->cfg, "unicastAddress",
-								unicast))
+	if (!mesh_config_write_unicast(node->cfg, unicast))
 		return false;
 
 	l_getrandom(node->token, sizeof(node->token));
diff --git a/mesh/storage.c b/mesh/storage.c
index 15077cb5d..6a8766257 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -75,176 +75,6 @@ static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
 	return result;
 }
 
-bool storage_set_ttl(struct mesh_node *node, uint8_t ttl)
-{
-	if (!mesh_config_write_int(node_config_get(node), "defaultTTL", ttl))
-		return false;
-
-	mesh_config_save_config(node_config_get(node), true, NULL, NULL);
-	return true;
-}
-
-bool storage_set_relay(struct mesh_node *node, bool enable,
-				uint8_t count, uint8_t interval)
-{
-	if (!mesh_config_write_relay_mode(node_config_get(node), enable, count,
-								interval))
-		return false;
-
-	mesh_config_save_config(node_config_get(node), true, NULL, NULL);
-	return true;
-}
-
-bool storage_set_transmit_params(struct mesh_node *node, uint8_t count,
-							uint8_t interval)
-{
-	if (!mesh_config_write_net_transmit(node_config_get(node), count,
-								interval))
-		return false;
-
-	mesh_config_save_config(node_config_get(node), true, NULL, NULL);
-	return true;
-}
-
-bool storage_set_mode(struct mesh_node *node, uint8_t mode,
-						const char *mode_name)
-{
-	if (!mesh_config_write_mode(node_config_get(node), mode_name, mode))
-		return false;
-
-	mesh_config_save_config(node_config_get(node), true, NULL, NULL);
-	return true;
-}
-
-bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t mod_id,
-				uint16_t app_idx, bool unbind)
-{
-	struct mesh_config *cfg;
-	int ele_idx;
-	bool stored, is_vendor = (mod_id > 0xffff);
-
-	ele_idx = node_get_element_idx(node, addr);
-	if (ele_idx < 0)
-		return false;
-
-	cfg = node_config_get(node);
-
-	if (unbind)
-		stored = mesh_config_model_binding_del(cfg, ele_idx, is_vendor,
-							mod_id, app_idx);
-	else
-		stored = mesh_config_model_binding_add(cfg, ele_idx, is_vendor,
-							mod_id, app_idx);
-
-	if (stored)
-		mesh_config_save_config(cfg, true, NULL, NULL);
-
-	return stored;
-}
-
-bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
-			uint16_t app_idx, const uint8_t key[16], bool update)
-{
-	struct mesh_config *cfg;
-	struct mesh_node *node = mesh_net_node_get(net);
-	bool stored;
-
-	cfg = node_config_get(node);
-
-	if (update)
-		stored = mesh_config_app_key_update(cfg, app_idx, key);
-	else
-		stored = mesh_config_app_key_add(cfg, net_idx, app_idx, key);
-
-	if (stored)
-		mesh_config_save_config(cfg, true, NULL, NULL);
-
-	return stored;
-}
-
-bool storage_app_key_del(struct mesh_net *net, uint16_t net_idx,
-					uint16_t app_idx)
-{
-	struct mesh_config *cfg;
-	struct mesh_node *node = mesh_net_node_get(net);
-
-	cfg = node_config_get(node);
-
-	if (!mesh_config_app_key_del(cfg, net_idx, app_idx))
-		return false;
-
-	mesh_config_save_config(cfg, true, NULL, NULL);
-	return true;
-}
-
-bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
-					const uint8_t key[16], bool update)
-{
-	struct mesh_node *node = mesh_net_node_get(net);
-	struct mesh_config *cfg = node_config_get(node);
-	bool stored;
-
-	if (!update)
-		stored = mesh_config_net_key_add(cfg, net_idx, key);
-	else
-		stored = mesh_config_net_key_update(cfg, net_idx, key);
-
-	if (stored)
-		mesh_config_save_config(cfg, true, NULL, NULL);
-
-	return stored;
-}
-
-bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx)
-{
-	struct mesh_node *node = mesh_net_node_get(net);
-	struct mesh_config *cfg = node_config_get(node);
-
-	if (!mesh_config_net_key_del(cfg, net_idx))
-		return false;
-
-	mesh_config_save_config(cfg, true, NULL, NULL);
-	return true;
-}
-
-bool storage_set_iv_index(struct mesh_net *net, uint32_t iv_index,
-								bool update)
-{
-	struct mesh_node *node = mesh_net_node_get(net);
-	struct mesh_config *cfg = node_config_get(node);
-
-	if (!mesh_config_write_iv_index(cfg, iv_index, update))
-		return false;
-
-	mesh_config_save_config(cfg, true, NULL, NULL);
-	return true;
-}
-
-bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
-								uint8_t phase)
-{
-	struct mesh_node *node = mesh_net_node_get(net);
-	struct mesh_config *cfg = node_config_get(node);
-
-	if (!mesh_config_net_key_set_phase(cfg, net_idx, phase))
-		return false;
-
-	mesh_config_save_config(cfg, true, NULL, NULL);
-	return true;
-}
-
-bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq)
-{
-	struct mesh_node *node = mesh_net_node_get(net);
-	struct mesh_config *cfg = node_config_get(node);
-
-	if (!mesh_config_write_int(cfg, "sequenceNumber", seq))
-		return false;
-
-	mesh_config_save_config(cfg, false, NULL, NULL);
-	return true;
-}
-
 static int create_dir(const char *dir_name)
 {
 	struct stat st;
diff --git a/mesh/storage.h b/mesh/storage.h
index f70544ad6..21fd3f5ab 100644
--- a/mesh/storage.h
+++ b/mesh/storage.h
@@ -25,27 +25,3 @@ bool storage_load_nodes(const char *dir);
 bool storage_create_node_config(struct mesh_node *node, const uint8_t uuid[16],
 					struct mesh_config_node *db_node);
 void storage_remove_node_config(struct mesh_node *node);
-bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t id,
-						uint16_t app_idx, bool unbind);
-
-bool storage_set_ttl(struct mesh_node *node, uint8_t ttl);
-bool storage_set_relay(struct mesh_node *node, bool enable, uint8_t count,
-							uint8_t interval);
-bool storage_set_transmit_params(struct mesh_node *node, uint8_t count,
-							uint8_t interval);
-bool storage_set_mode(struct mesh_node *node, uint8_t mode,
-						const char *mode_name);
-bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
-					const uint8_t key[16], bool update);
-bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx);
-bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
-			uint16_t app_idx, const uint8_t key[16], bool update);
-bool storage_app_key_del(struct mesh_net *net, uint16_t net_idx,
-							uint16_t app_idx);
-bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq);
-bool storage_set_iv_index(struct mesh_net *net, uint32_t iv_index,
-								bool update);
-bool storage_set_device_key(struct mesh_node *node, uint8_t dev_key[16]);
-bool storage_set_unicast(struct mesh_node *node, uint16_t unicast);
-bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
-								uint8_t phase);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 08/10 v3] mesh: Manage node config directory in mesh-config
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (6 preceding siblings ...)
  2019-07-14 23:23 ` [PATCH BlueZ 07/10 v3] mesh: Use mesh_config APIs to store node configuration Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 09/10 v3] mesh: Create or re-use a node storage directory for keyring Inga Stotland
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This completely removes storage.c file. Instead, the handling
of mesh node configuration storage is done completely in
mesh-config layer by calling the following API functions:
bool mesh_config_load_nodes(const char *cfg_dir,
                            mesh_config_node_func_t cb,
                            void *user_data)

void mesh_config_release(struct mesh_config *cfg)
void mesh_config_destroy(struct mesh_config *cfg)

bool mesh_config_save(struct mesh_config *cfg, bool no_wait,
                      mesh_config_status_func_t cb, void *user_data)

struct mesh_config *mesh_config_create(const char *cfg_path,
                                       const uint8_t uuid[16],
                                       struct mesh_config_node *node)
---
 Makefile.mesh           |   1 -
 mesh/cfgmod-server.c    |   1 -
 mesh/mesh-config-json.c | 211 +++++++++++++++++++++++++++------
 mesh/mesh-config.h      |   7 +-
 mesh/mesh.c             |  15 ++-
 mesh/mesh.h             |   1 +
 mesh/model.c            |   1 -
 mesh/node.c             |  48 ++++----
 mesh/node.h             |   3 +-
 mesh/storage.c          | 254 ----------------------------------------
 mesh/storage.h          |  27 -----
 mesh/util.c             |  39 +++++-
 mesh/util.h             |   1 +
 13 files changed, 255 insertions(+), 354 deletions(-)
 delete mode 100644 mesh/storage.c
 delete mode 100644 mesh/storage.h

diff --git a/Makefile.mesh b/Makefile.mesh
index 502ba2a47..02b457e46 100644
--- a/Makefile.mesh
+++ b/Makefile.mesh
@@ -16,7 +16,6 @@ mesh_sources = mesh/mesh.h mesh/mesh.c \
 				mesh/error.h mesh/mesh-io-api.h \
 				mesh/mesh-io-generic.h \
 				mesh/mesh-io-generic.c \
-				mesh/storage.h mesh/storage.c \
 				mesh/net.h mesh/net.c \
 				mesh/crypto.h mesh/crypto.c \
 				mesh/friend.h mesh/friend.c \
diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index 033ab41ea..b256cdd48 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -29,7 +29,6 @@
 #include "mesh/net.h"
 #include "mesh/appkey.h"
 #include "mesh/model.h"
-#include "mesh/storage.h"
 #include "mesh/mesh-config.h"
 #include "mesh/cfgmod.h"
 
diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c
index 62c674afd..75015e607 100644
--- a/mesh/mesh-config-json.c
+++ b/mesh/mesh-config-json.c
@@ -22,7 +22,7 @@
 #endif
 
 #define _GNU_SOURCE
-//#include <dirent.h>
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <ftw.h>
@@ -42,7 +42,7 @@
 
 struct mesh_config {
 	json_object *jnode;
-	char *node_path;
+	char *node_dir_path;
 	uint8_t uuid[16];
 };
 
@@ -52,6 +52,7 @@ struct write_info {
 	mesh_config_status_func_t cb;
 };
 
+static const char *cfg_name = "/node.json";
 static const char *bak_ext = ".bak";
 static const char *tmp_ext = ".tmp";
 
@@ -535,7 +536,7 @@ bool mesh_config_net_key_add(struct mesh_config *cfg, uint16_t idx,
 
 	json_object_array_add(jarray, jentry);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 
 fail:
 	if (jentry)
@@ -577,7 +578,7 @@ bool mesh_config_net_key_update(struct mesh_config *cfg, uint16_t idx,
 	json_object_object_add(jentry, "keyRefresh",
 				json_object_new_int(KEY_REFRESH_PHASE_ONE));
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
@@ -601,7 +602,7 @@ bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
 		json_object_object_del(jnode, "netKeys");
 		/* TODO: Do we raise an error here? */
 		l_warn("Removing the last network key! Zero keys left.");
-		return save_config(jnode, cfg->node_path);
+		return save_config(jnode, cfg->node_dir_path);
 	}
 
 	/*
@@ -616,7 +617,7 @@ bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
 	json_object_object_del(jnode, "netKeys");
 	json_object_object_add(jnode, "netKeys", jarray_new);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_write_device_key(struct mesh_config *cfg, uint8_t *key)
@@ -624,7 +625,7 @@ bool mesh_config_write_device_key(struct mesh_config *cfg, uint8_t *key)
 	if (!cfg || !add_key_value(cfg->jnode, "deviceKey", key))
 		return false;
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_write_token(struct mesh_config *cfg, uint8_t *token)
@@ -632,7 +633,7 @@ bool mesh_config_write_token(struct mesh_config *cfg, uint8_t *token)
 	if (!cfg || !add_u64_value(cfg->jnode, "token", token))
 		return false;
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_app_key_add(struct mesh_config *cfg, uint16_t net_idx,
@@ -684,7 +685,7 @@ bool mesh_config_app_key_add(struct mesh_config *cfg, uint16_t net_idx,
 
 	json_object_array_add(jarray, jentry);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 
 fail:
 
@@ -726,7 +727,7 @@ bool mesh_config_app_key_update(struct mesh_config *cfg, uint16_t app_idx,
 	if (!add_key_value(jentry, "key", key))
 		return false;
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_app_key_del(struct mesh_config *cfg, uint16_t net_idx,
@@ -763,7 +764,7 @@ bool mesh_config_app_key_del(struct mesh_config *cfg, uint16_t net_idx,
 	json_object_object_del(jnode, "appKeys");
 	json_object_object_add(jnode, "appKeys", jarray_new);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_model_binding_add(struct mesh_config *cfg, uint8_t ele_idx,
@@ -803,7 +804,7 @@ bool mesh_config_model_binding_add(struct mesh_config *cfg, uint8_t ele_idx,
 
 	json_object_array_add(jarray, jstring);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_model_binding_del(struct mesh_config *cfg, uint8_t ele_idx,
@@ -847,7 +848,7 @@ bool mesh_config_model_binding_del(struct mesh_config *cfg, uint8_t ele_idx,
 	json_object_object_del(jmodel, "bind");
 	json_object_object_add(jmodel, "bind", jarray_new);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 static void free_model(void *data)
@@ -1439,7 +1440,7 @@ bool mesh_config_write_mode(struct mesh_config *cfg, const char *keyword,
 	if (!cfg || !write_mode(cfg->jnode, keyword, value))
 		return false;
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 }
 
 static bool write_relay_mode(json_object *jobj, uint8_t mode,
@@ -1475,7 +1476,7 @@ bool mesh_config_write_unicast(struct mesh_config *cfg, uint16_t unicast)
 	if (!cfg || !write_uint16_hex(cfg->jnode, "unicastAddress", unicast))
 		return false;
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode,
@@ -1485,7 +1486,7 @@ bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode,
 	if (!cfg || !write_relay_mode(cfg->jnode, mode, count, interval))
 		return false;
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
@@ -1511,7 +1512,7 @@ bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
 	json_object_object_del(jnode, "retransmit");
 	json_object_object_add(jnode, "retransmit", jretransmit);
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 
 fail:
 	json_object_put(jretransmit);
@@ -1536,7 +1537,7 @@ bool mesh_config_write_iv_index(struct mesh_config *cfg, uint32_t idx,
 	if (!write_int(jnode, "IVupdate", tmp))
 		return false;
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 static void add_model(void *a, void *b)
@@ -1558,9 +1559,9 @@ static void add_model(void *a, void *b)
 }
 
 /* Add unprovisioned node (local) */
-struct mesh_config *mesh_config_create(const char *cfg_path,
-						const uint8_t uuid[16],
-						struct mesh_config_node *node)
+static struct mesh_config *create_config(const char *cfg_path,
+					const uint8_t uuid[16],
+					struct mesh_config_node *node)
 {
 	struct mesh_config_modes *modes = &node->modes;
 	const struct l_queue_entry *entry;
@@ -1653,7 +1654,43 @@ struct mesh_config *mesh_config_create(const char *cfg_path,
 
 	cfg->jnode = jnode;
 	memcpy(cfg->uuid, uuid, 16);
-	cfg->node_path = l_strdup(cfg_path);
+	cfg->node_dir_path = l_strdup(cfg_path);
+
+	return cfg;
+}
+
+struct mesh_config *mesh_config_create(const char *cfg_dir,
+		const uint8_t uuid[16], struct mesh_config_node *db_node)
+{
+	char uuid_buf[33];
+	char name_buf[PATH_MAX];
+	struct mesh_config *cfg;
+	size_t max_len = strlen(cfg_name) + strlen(bak_ext);
+
+	if (!hex2str((uint8_t *) uuid, 16, uuid_buf, sizeof(uuid_buf)))
+		return NULL;
+
+	snprintf(name_buf, PATH_MAX, "%s/%s", cfg_dir, uuid_buf);
+
+	if (strlen(name_buf) + max_len >= PATH_MAX)
+		return NULL;
+
+	/* Create a new directory and node.json file */
+	if (mkdir(name_buf, 0755) != 0)
+		return NULL;
+
+	snprintf(name_buf, PATH_MAX, "%s/%s%s", cfg_dir, uuid_buf,
+								cfg_name);
+	l_debug("New node config %s", name_buf);
+
+	cfg = create_config(name_buf, uuid, db_node);
+	if (!cfg)
+		return NULL;
+
+	if (!mesh_config_save(cfg, true, NULL, NULL)) {
+		mesh_config_release(cfg);
+		return NULL;
+	}
 
 	return cfg;
 }
@@ -1714,7 +1751,7 @@ bool mesh_config_net_key_set_phase(struct mesh_config *cfg, uint16_t idx,
 		finish_key_refresh(jnode, idx);
 	}
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t addr,
@@ -1778,7 +1815,7 @@ bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t addr,
 	json_object_object_add(jpub, "retransmit", jretransmit);
 	json_object_object_add(jmodel, "publish", jpub);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 
 fail:
 	json_object_put(jpub);
@@ -1811,7 +1848,7 @@ bool mesh_config_model_pub_del(struct mesh_config *cfg, uint16_t addr,
 								"publish"))
 		return false;
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_model_sub_add(struct mesh_config *cfg, uint16_t addr,
@@ -1862,7 +1899,7 @@ bool mesh_config_model_sub_add(struct mesh_config *cfg, uint16_t addr,
 
 	json_object_array_add(jarray, jstring);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_model_sub_del(struct mesh_config *cfg, uint16_t addr,
@@ -1917,7 +1954,7 @@ bool mesh_config_model_sub_del(struct mesh_config *cfg, uint16_t addr,
 	json_object_object_del(jmodel, "subscribe");
 	json_object_object_add(jmodel, "subscribe", jarray_new);
 
-	return save_config(jnode, cfg->node_path);
+	return save_config(jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_model_sub_del_all(struct mesh_config *cfg, uint16_t addr,
@@ -1927,7 +1964,7 @@ bool mesh_config_model_sub_del_all(struct mesh_config *cfg, uint16_t addr,
 								"subscribe"))
 		return false;
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 }
 
 bool mesh_config_write_seq_number(struct mesh_config *cfg, uint32_t seq)
@@ -1935,7 +1972,7 @@ bool mesh_config_write_seq_number(struct mesh_config *cfg, uint32_t seq)
 	if (!cfg || !write_int(cfg->jnode, "sequenceNumber", seq))
 		return false;
 
-	mesh_config_save_config(cfg, false, NULL, NULL);
+	mesh_config_save(cfg, false, NULL, NULL);
 	return true;
 }
 
@@ -1944,10 +1981,10 @@ bool mesh_config_write_ttl(struct mesh_config *cfg, uint8_t ttl)
 	if (!cfg || !write_int(cfg->jnode, "defaultTTL", ttl))
 		return false;
 
-	return save_config(cfg->jnode, cfg->node_path);
+	return save_config(cfg->jnode, cfg->node_dir_path);
 }
 
-bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
+static bool load_node(const char *fname, const uint8_t uuid[16],
 				mesh_config_node_func_t cb, void *user_data)
 {
 	int fd;
@@ -1963,9 +2000,9 @@ bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
 		return false;
 	}
 
-	l_info("Loading configuration from %s", cfg_path);
+	l_info("Loading configuration from %s", fname);
 
-	fd = open(cfg_path, O_RDONLY);
+	fd = open(fname, O_RDONLY);
 	if (fd < 0)
 		return false;
 
@@ -1982,7 +2019,7 @@ bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
 
 	sz = read(fd, str, st.st_size);
 	if (sz != st.st_size) {
-		l_error("Failed to read configuration file %s", cfg_path);
+		l_error("Failed to read configuration file %s", fname);
 		goto done;
 	}
 
@@ -1998,11 +2035,11 @@ bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
 
 		cfg->jnode = jnode;
 		memcpy(cfg->uuid, uuid, 16);
-		cfg->node_path = l_strdup(cfg_path);
+		cfg->node_dir_path = l_strdup(fname);
 		result = cb(&node, uuid, cfg, user_data);
 
 		if (!result) {
-			l_free(cfg->node_path);
+			l_free(cfg->node_dir_path);
 			l_free(cfg);
 		}
 	}
@@ -2028,7 +2065,7 @@ void mesh_config_release(struct mesh_config *cfg)
 	if (!cfg)
 		return;
 
-	l_free(cfg->node_path);
+	l_free(cfg->node_dir_path);
 	json_object_put(cfg->jnode);
 	l_free(cfg);
 }
@@ -2039,7 +2076,7 @@ static void idle_save_config(void *user_data)
 	char *fname_tmp, *fname_bak, *fname_cfg;
 	bool result = false;
 
-	fname_cfg = info->cfg->node_path;
+	fname_cfg = info->cfg->node_dir_path;
 	fname_tmp = l_strdup_printf("%s%s", fname_cfg, tmp_ext);
 	fname_bak = l_strdup_printf("%s%s", fname_cfg, bak_ext);
 	remove(fname_tmp);
@@ -2063,7 +2100,7 @@ static void idle_save_config(void *user_data)
 	l_free(info);
 }
 
-bool mesh_config_save_config(struct mesh_config *cfg, bool no_wait,
+bool mesh_config_save(struct mesh_config *cfg, bool no_wait,
 				mesh_config_status_func_t cb, void *user_data)
 {
 	struct write_info *info;
@@ -2083,3 +2120,99 @@ bool mesh_config_save_config(struct mesh_config *cfg, bool no_wait,
 
 	return true;
 }
+
+bool mesh_config_load_nodes(const char *cfg_dir, mesh_config_node_func_t cb,
+							void *user_data)
+{
+	DIR *dir;
+	struct dirent *entry;
+	size_t path_len = strlen(cfg_dir) + strlen(cfg_name) + strlen(bak_ext);
+
+	create_dir(cfg_dir);
+	dir = opendir(cfg_dir);
+	if (!dir) {
+		l_error("Failed to open mesh node storage directory: %s",
+								cfg_dir);
+		return false;
+	}
+
+	while ((entry = readdir(dir)) != NULL) {
+		char *dir, *fname, *bak;
+		uint8_t uuid[16];
+		size_t node_len;
+
+		if (entry->d_type != DT_DIR)
+			continue;
+
+		/* Check path length */
+		node_len = strlen(entry->d_name);
+		if (path_len + node_len + 1 >= PATH_MAX)
+			continue;
+
+		if (!str2hex(entry->d_name, node_len, uuid, sizeof(uuid)))
+			continue;
+
+		dir = l_strdup_printf("%s/%s", cfg_dir, entry->d_name);
+		fname = l_strdup_printf("%s%s", dir, cfg_name);
+
+		if (!load_node(fname, uuid, cb, user_data)) {
+
+			/* Fall-back to Backup version */
+			bak = l_strdup_printf("%s%s", fname, bak_ext);
+
+			if (load_node(bak, uuid, cb, user_data)) {
+				remove(fname);
+				rename(bak, fname);
+			}
+			l_free(bak);
+		}
+		l_free(fname);
+		l_free(dir);
+	}
+
+	return true;
+}
+
+static int del_fobject(const char *fpath, const struct stat *sb, int typeflag,
+						struct FTW *ftwbuf)
+{
+	switch (typeflag) {
+	case FTW_DP:
+		rmdir(fpath);
+		l_debug("RMDIR %s", fpath);
+		break;
+
+	case FTW_SL:
+	default:
+		remove(fpath);
+		l_debug("RM %s", fpath);
+		break;
+	}
+	return 0;
+}
+
+void mesh_config_destroy(struct mesh_config *cfg)
+{
+	char *node_dir, *node_name;
+	char uuid[33];
+
+	if (!cfg)
+		return;
+
+	node_dir = dirname(cfg->node_dir_path);
+	l_debug("Delete node config %s", node_dir);
+
+	if (!hex2str(cfg->uuid, 16, uuid, sizeof(uuid)))
+		return;
+
+	node_name = basename(node_dir);
+
+	/* Make sure path name of node follows expected guidelines */
+	if (strcmp(node_name, uuid))
+		return;
+
+	nftw(node_dir, del_fobject, 5, FTW_DEPTH | FTW_PHYS);
+
+	/* Release node config object */
+	mesh_config_release(cfg);
+}
diff --git a/mesh/mesh-config.h b/mesh/mesh-config.h
index 83ba33bf9..44e3b3ad6 100644
--- a/mesh/mesh-config.h
+++ b/mesh/mesh-config.h
@@ -110,10 +110,11 @@ typedef bool (*mesh_config_node_func_t)(struct mesh_config_node *node,
 							struct mesh_config *cfg,
 							void *user_data);
 
-bool mesh_config_load_node(const char *cfg_path, const uint8_t uuid[16],
-				mesh_config_node_func_t cb, void *user_data);
+bool mesh_config_load_nodes(const char *cfg_dir, mesh_config_node_func_t cb,
+							void *user_data);
 void mesh_config_release(struct mesh_config *cfg);
-bool mesh_config_save_config(struct mesh_config *cfg, bool no_wait,
+void mesh_config_destroy(struct mesh_config *cfg);
+bool mesh_config_save(struct mesh_config *cfg, bool no_wait,
 				mesh_config_status_func_t cb, void *user_data);
 struct mesh_config *mesh_config_create(const char *cfg_path,
 						const uint8_t uuid[16],
diff --git a/mesh/mesh.c b/mesh/mesh.c
index b9e3162eb..9c6b9a70e 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -27,7 +27,6 @@
 #include "mesh/mesh-io.h"
 #include "mesh/node.h"
 #include "mesh/net.h"
-#include "mesh/storage.h"
 #include "mesh/provision.h"
 #include "mesh/model.h"
 #include "mesh/dbus.h"
@@ -78,6 +77,8 @@ static struct join_data *join_pending;
 /* Pending method requests */
 static struct l_queue *pending_queue;
 
+static const char *storage_dir;
+
 static bool simple_match(const void *a, const void *b)
 {
 	return a == b;
@@ -150,12 +151,11 @@ bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts)
 	mesh.prov_timeout = DEFAULT_PROV_TIMEOUT;
 	mesh.algorithms = DEFAULT_ALGORITHMS;
 
-	if (!config_dir)
-		config_dir = MESH_STORAGEDIR;
+	storage_dir = config_dir ? config_dir : MESH_STORAGEDIR;
 
-	l_info("Loading node configuration from %s", config_dir);
+	l_info("Loading node configuration from %s", storage_dir);
 
-	if (!storage_load_nodes(config_dir))
+	if (!node_load_from_storage(storage_dir))
 		return false;
 
 	mesh.io = mesh_io_new(type, opts);
@@ -638,3 +638,8 @@ bool mesh_dbus_init(struct l_dbus *dbus)
 
 	return true;
 }
+
+const char *mesh_get_storage_dir(void)
+{
+	return storage_dir;
+}
diff --git a/mesh/mesh.h b/mesh/mesh.h
index 78d4d4926..e0a3e1b96 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
@@ -42,3 +42,4 @@ bool mesh_send_cancel(const uint8_t *filter, uint8_t len);
 bool mesh_reg_prov_rx(prov_rx_cb_t cb, void *user_data);
 void mesh_unreg_prov_rx(prov_rx_cb_t cb);
 const char *mesh_prov_status_str(uint8_t status);
+const char *mesh_get_storage_dir(void);
diff --git a/mesh/model.c b/mesh/model.c
index ef62a223a..785becb5f 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -33,7 +33,6 @@
 #include "mesh/net.h"
 #include "mesh/appkey.h"
 #include "mesh/cfgmod.h"
-#include "mesh/storage.h"
 #include "mesh/error.h"
 #include "mesh/dbus.h"
 #include "mesh/util.h"
diff --git a/mesh/node.c b/mesh/node.c
index d90ca2ad1..56489a8db 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -33,7 +33,6 @@
 #include "mesh/appkey.h"
 #include "mesh/mesh-config.h"
 #include "mesh/provision.h"
-#include "mesh/storage.h"
 #include "mesh/keyring.h"
 #include "mesh/model.h"
 #include "mesh/cfgmod.h"
@@ -195,7 +194,7 @@ uint8_t *node_uuid_get(struct mesh_node *node)
 	return node->uuid;
 }
 
-struct mesh_node *node_new(const uint8_t uuid[16])
+static struct mesh_node *node_new(const uint8_t uuid[16])
 {
 	struct mesh_node *node;
 
@@ -284,8 +283,8 @@ void node_remove(struct mesh_node *node)
 
 	l_queue_remove(nodes, node);
 
-	if (node->node_path)
-		storage_remove_node_config(node);
+	if (node->cfg)
+		mesh_config_destroy(node->cfg);
 
 	free_node_resources(node);
 }
@@ -393,12 +392,15 @@ static void set_app_key(void *a, void *b)
 						appkey->key, appkey->new_key);
 }
 
-bool node_init_from_storage(struct mesh_node *node, const uint8_t uuid[16],
-					struct mesh_config_node *db_node)
+static bool init_from_storage(struct mesh_config_node *db_node,
+			const uint8_t uuid[16], struct mesh_config *cfg,
+			void *user_data)
 {
 	unsigned int num_ele;
 	uint8_t mode;
 
+	struct mesh_node *node = node_new(uuid);
+
 	node->comp = l_new(struct node_composition, 1);
 	node->comp->cid = db_node->cid;
 	node->comp->pid = db_node->pid;
@@ -424,17 +426,17 @@ bool node_init_from_storage(struct mesh_node *node, const uint8_t uuid[16],
 
 	num_ele = l_queue_length(db_node->elements);
 	if (num_ele > 0xff)
-		return false;
+		goto fail;
 
 	node->num_ele = num_ele;
 
 	if (num_ele != 0 && !add_elements(node, db_node))
-		return false;
+		goto fail;
 
 	node->primary = db_node->unicast;
 
 	if (!db_node->netkeys)
-		return false;
+		goto fail;
 
 	mesh_net_set_iv_index(node->net, db_node->iv_index, db_node->iv_update);
 
@@ -470,12 +472,17 @@ bool node_init_from_storage(struct mesh_node *node, const uint8_t uuid[16],
 
 	if (!IS_UNASSIGNED(node->primary) &&
 		!mesh_net_register_unicast(node->net, node->primary, num_ele))
-		return false;
+		goto fail;
 
 	/* Initialize configuration server model */
 	mesh_config_srv_init(node, PRIMARY_ELE_IDX);
 
+	node->cfg = cfg;
+
 	return true;
+fail:
+	node_remove(node);
+	return false;
 }
 
 static void cleanup_node(void *data)
@@ -490,7 +497,7 @@ static void cleanup_node(void *data)
 		mesh_config_write_seq_number(node->cfg,
 						mesh_net_get_seq_num(net));
 
-		mesh_config_save_config(node->cfg, true, NULL, NULL);
+		mesh_config_save(node->cfg, true, NULL, NULL);
 	}
 
 	free_node_resources(node);
@@ -1362,10 +1369,11 @@ static bool create_node_config(struct mesh_node *node, const uint8_t uuid[16])
 {
 	struct mesh_config_node db_node;
 	const struct l_queue_entry *entry;
-	bool res;
+	const char *storage_dir;
 
 	convert_node_to_storage(node, &db_node);
-	res = storage_create_node_config(node, uuid, &db_node);
+	storage_dir = mesh_get_storage_dir();
+	node->cfg = mesh_config_create(storage_dir, uuid, &db_node);
 
 	/* Free temporarily allocated resources */
 	entry = l_queue_get_entries(db_node.elements);
@@ -1377,7 +1385,7 @@ static bool create_node_config(struct mesh_node *node, const uint8_t uuid[16])
 
 	l_queue_destroy(db_node.elements, l_free);
 
-	return res;
+	return node->cfg != NULL;
 }
 
 static void set_defaults(struct mesh_node *node)
@@ -1502,7 +1510,7 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 			return false;
 	}
 
-	mesh_config_save_config(node->cfg, true, NULL, NULL);
+	mesh_config_save(node->cfg, true, NULL, NULL);
 
 	/* Initialize configuration server model */
 	mesh_config_srv_init(node, PRIMARY_ELE_IDX);
@@ -2060,11 +2068,6 @@ bool node_add_pending_local(struct mesh_node *node, void *prov_node_info)
 			info->device_key, info->net_index, info->net_key);
 }
 
-void node_config_set(struct mesh_node *node, struct mesh_config *cfg)
-{
-	node->cfg = cfg;
-}
-
 struct mesh_config *node_config_get(struct mesh_node *node)
 {
 	return node->cfg;
@@ -2098,3 +2101,8 @@ struct mesh_agent *node_get_agent(struct mesh_node *node)
 {
 	return node->agent;
 }
+
+bool node_load_from_storage(const char *storage_dir)
+{
+	return mesh_config_load_nodes(storage_dir, init_from_storage, NULL);
+}
diff --git a/mesh/node.h b/mesh/node.h
index ee62737fc..e387b4d09 100644
--- a/mesh/node.h
+++ b/mesh/node.h
@@ -35,7 +35,6 @@ typedef void (*node_ready_func_t) (void *user_data, int status,
 typedef void (*node_join_ready_func_t) (struct mesh_node *node,
 						struct mesh_agent *agent);
 
-struct mesh_node *node_new(const uint8_t uuid[16]);
 void node_remove(struct mesh_node *node);
 void node_join(const char *app_path, const char *sender, const uint8_t *uuid,
 						node_join_ready_func_t cb);
@@ -100,8 +99,8 @@ void node_id_set(struct mesh_node *node, uint16_t node_id);
 uint16_t node_id_get(struct mesh_node *node);
 bool node_dbus_init(struct l_dbus *bus);
 void node_cleanup_all(void);
-void node_config_set(struct mesh_node *node, struct mesh_config *cfg);
 struct mesh_config *node_config_get(struct mesh_node *node);
 void node_path_set(struct mesh_node *node, char *path);
 char *node_path_get(struct mesh_node *node);
 struct mesh_agent *node_get_agent(struct mesh_node *node);
+bool node_load_from_storage(const char *storage_dir);
diff --git a/mesh/storage.c b/mesh/storage.c
deleted file mode 100644
index 6a8766257..000000000
--- a/mesh/storage.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2017-2019  Intel Corporation. All rights reserved.
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define _GNU_SOURCE
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <libgen.h>
-#include <ftw.h>
-
-#include <ell/ell.h>
-
-#include "mesh/mesh-defs.h"
-#include "mesh/node.h"
-#include "mesh/net.h"
-#include "mesh/appkey.h"
-#include "mesh/mesh-config.h"
-#include "mesh/util.h"
-#include "mesh/storage.h"
-
-static const char *cfg_name = "/node.json";
-static const char *bak_ext = ".bak";
-static const char *storage_dir;
-
-static bool read_node_cb(struct mesh_config_node *db_node,
-			const uint8_t uuid[16], struct mesh_config *cfg,
-			void *user_data)
-{
-	struct mesh_node *node = user_data;
-
-	if (!node_init_from_storage(node, uuid, db_node)) {
-		node_remove(node);
-		return false;
-	}
-
-	node_config_set(node, cfg);
-	return true;
-}
-
-static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
-{
-	bool result = false;
-	struct mesh_node *node;
-
-	node = node_new(uuid);
-
-	result = mesh_config_load_node(in_file, uuid, read_node_cb, node);
-
-	if (!result)
-		node_remove(node);
-	else
-		node_path_set(node, out_dir);
-
-	return result;
-}
-
-static int create_dir(const char *dir_name)
-{
-	struct stat st;
-	char dir[PATH_MAX + 1], *prev, *next;
-	int err;
-
-	err = stat(dir_name, &st);
-	if (!err && S_ISREG(st.st_mode))
-		return 0;
-
-	memset(dir, 0, PATH_MAX + 1);
-	strcat(dir, "/");
-
-	prev = strchr(dir_name, '/');
-
-	while (prev) {
-		next = strchr(prev + 1, '/');
-		if (!next)
-			break;
-
-		if (next - prev == 1) {
-			prev = next;
-			continue;
-		}
-
-		strncat(dir, prev + 1, next - prev);
-		mkdir(dir, 0755);
-
-		prev = next;
-	}
-
-	mkdir(dir_name, 0755);
-
-	return 0;
-}
-
-bool storage_load_nodes(const char *dir_name)
-{
-	DIR *dir;
-	struct dirent *entry;
-	size_t path_len = strlen(dir_name) + strlen(cfg_name) + strlen(bak_ext);
-
-	create_dir(dir_name);
-	dir = opendir(dir_name);
-	if (!dir) {
-		l_error("Failed to open mesh node storage directory: %s",
-								dir_name);
-		return false;
-	}
-
-	storage_dir = dir_name;
-
-	while ((entry = readdir(dir)) != NULL) {
-		char *dir, *cfg, *bak;
-		uint8_t uuid[16];
-		size_t node_len;
-
-		if (entry->d_type != DT_DIR)
-			continue;
-
-		/* Check path length */
-		node_len = strlen(entry->d_name);
-		if (path_len + node_len + 1 >= PATH_MAX)
-			continue;
-
-		if (!str2hex(entry->d_name, node_len, uuid, sizeof(uuid)))
-			continue;
-
-		dir = l_strdup_printf("%s/%s", dir_name, entry->d_name);
-		cfg = l_strdup_printf("%s%s", dir, cfg_name);
-
-		if (!parse_config(cfg, dir, uuid)) {
-
-			/* Fall-back to Backup version */
-			bak = l_strdup_printf("%s%s", cfg, bak_ext);
-
-			if (parse_config(bak, dir, uuid)) {
-				remove(cfg);
-				rename(bak, cfg);
-			}
-			l_free(bak);
-		}
-		l_free(cfg);
-		l_free(dir);
-	}
-
-	return true;
-}
-
-bool storage_create_node_config(struct mesh_node *node, const uint8_t uuid[16],
-					struct mesh_config_node *db_node)
-{
-	char uuid_buf[33];
-	char name_buf[PATH_MAX];
-	struct mesh_config *cfg;
-	size_t max_len = strlen(cfg_name) + strlen(bak_ext);
-
-	if (!storage_dir)
-		return false;
-
-	if (!hex2str((uint8_t *) uuid, 16, uuid_buf, sizeof(uuid_buf)))
-		return false;
-
-	snprintf(name_buf, PATH_MAX, "%s/%s", storage_dir, uuid_buf);
-
-	if (strlen(name_buf) + max_len >= PATH_MAX)
-		return false;
-
-	/* Create a new directory and node.json file */
-	if (mkdir(name_buf, 0755) != 0)
-		return false;
-
-	node_path_set(node, name_buf);
-
-	snprintf(name_buf, PATH_MAX, "%s/%s%s", storage_dir, uuid_buf,
-								cfg_name);
-	l_debug("New node config %s", name_buf);
-
-	cfg = mesh_config_create(name_buf, uuid, db_node);
-	if (!cfg)
-		return false;
-
-	if (!mesh_config_save_config(cfg, true, NULL, NULL)) {
-		mesh_config_release(cfg);
-		return false;
-	}
-
-	node_config_set(node, cfg);
-
-	return true;
-}
-
-static int del_fobject(const char *fpath, const struct stat *sb, int typeflag,
-						struct FTW *ftwbuf)
-{
-	switch (typeflag) {
-	case FTW_DP:
-		rmdir(fpath);
-		l_debug("RMDIR %s", fpath);
-		break;
-
-	case FTW_SL:
-	default:
-		remove(fpath);
-		l_debug("RM %s", fpath);
-		break;
-	}
-	return 0;
-}
-
-/* Permanently remove node configuration */
-void storage_remove_node_config(struct mesh_node *node)
-{
-	char *node_path, *node_name;
-	char uuid[33];
-
-	if (!node)
-		return;
-
-	/* Release node config object */
-	mesh_config_release(node_config_get(node));
-	node_config_set(node, NULL);
-
-	node_path = node_path_get(node);
-	l_debug("Delete node config %s", node_path);
-
-	/* Make sure path name of node follows expected guidelines */
-	if (!hex2str(node_uuid_get(node), 16, uuid, sizeof(uuid)))
-		return;
-
-	node_name = basename(node_path);
-
-	if (strcmp(node_name, uuid))
-		return;
-
-	nftw(node_path, del_fobject, 5, FTW_DEPTH | FTW_PHYS);
-}
diff --git a/mesh/storage.h b/mesh/storage.h
deleted file mode 100644
index 21fd3f5ab..000000000
--- a/mesh/storage.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2017-2019  Intel Corporation. All rights reserved.
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- */
-
-struct mesh_net;
-struct mesh_node;
-struct mesh_config_node;
-
-bool storage_load_nodes(const char *dir);
-bool storage_create_node_config(struct mesh_node *node, const uint8_t uuid[16],
-					struct mesh_config_node *db_node);
-void storage_remove_node_config(struct mesh_node *node);
diff --git a/mesh/util.c b/mesh/util.c
index 861232266..1455bdec3 100644
--- a/mesh/util.c
+++ b/mesh/util.c
@@ -22,7 +22,8 @@
 #endif
 
 #define _GNU_SOURCE
-
+#include <dirent.h>
+#include <ftw.h>
 #include <stdio.h>
 #include <time.h>
 #include <sys/time.h>
@@ -91,3 +92,39 @@ size_t hex2str(uint8_t *in, size_t in_len, char *out, size_t out_len)
 	out[in_len * 2] = '\0';
 	return i;
 }
+
+int create_dir(const char *dir_name)
+{
+	struct stat st;
+	char dir[PATH_MAX + 1], *prev, *next;
+	int err;
+
+	err = stat(dir_name, &st);
+	if (!err && S_ISREG(st.st_mode))
+		return 0;
+
+	memset(dir, 0, PATH_MAX + 1);
+	strcat(dir, "/");
+
+	prev = strchr(dir_name, '/');
+
+	while (prev) {
+		next = strchr(prev + 1, '/');
+		if (!next)
+			break;
+
+		if (next - prev == 1) {
+			prev = next;
+			continue;
+		}
+
+		strncat(dir, prev + 1, next - prev);
+		mkdir(dir, 0755);
+
+		prev = next;
+	}
+
+	mkdir(dir_name, 0755);
+
+	return 0;
+}
diff --git a/mesh/util.h b/mesh/util.h
index 007ea368e..d1e83b573 100644
--- a/mesh/util.h
+++ b/mesh/util.h
@@ -22,3 +22,4 @@ bool str2hex(const char *str, uint16_t in_len, uint8_t *out,
 							uint16_t out_len);
 size_t hex2str(uint8_t *in, size_t in_len, char *out, size_t out_len);
 void print_packet(const char *label, const void *data, uint16_t size);
+int create_dir(const char *dir_name);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 09/10 v3] mesh: Create or re-use a node storage directory for keyring
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (7 preceding siblings ...)
  2019-07-14 23:23 ` [PATCH BlueZ 08/10 v3] mesh: Manage node config directory in mesh-config Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-14 23:23 ` [PATCH BlueZ 10/10 v3] mesh: Rename mesh_config_srv_init() to cfgmod_server_init() Inga Stotland
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This adds APIs to set a directory for storing node's key ring info.
The directory is named MESH_STORAGE_DIR/<node uuid>. This directory
may contain additional node info plus node configuration, if node
configuration storage follows the same layout (as it does when
JSON based config file format is used).
---
 mesh/keyring.c | 36 ++++++++++++++++++------------------
 mesh/node.c    | 41 ++++++++++++++++++++++++++++++++---------
 mesh/node.h    |  3 +--
 3 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/mesh/keyring.c b/mesh/keyring.c
index 4c6d2986d..3ea83194c 100644
--- a/mesh/keyring.c
+++ b/mesh/keyring.c
@@ -43,7 +43,7 @@ const char *net_key_dir = "/net_keys";
 bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx,
 						struct keyring_net_key *key)
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 	bool result = false;
 	int fd;
@@ -51,7 +51,7 @@ bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx,
 	if (!node || !key)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 
 	if (strlen(node_path) + strlen(net_key_dir) + 1 + 3 >= PATH_MAX)
 		return false;
@@ -76,7 +76,7 @@ bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx,
 bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx,
 				uint16_t net_idx, struct keyring_app_key *key)
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 	bool result = false;
 	int fd;
@@ -84,7 +84,7 @@ bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx,
 	if (!node || !key)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 
 	if (strlen(node_path) + strlen(app_key_dir) + 1 + 3 >= PATH_MAX)
 		return false;
@@ -123,7 +123,7 @@ bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx,
 bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast,
 					uint8_t count, uint8_t dev_key[16])
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 	bool result = true;
 	int fd, i;
@@ -131,7 +131,7 @@ bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast,
 	if (!node)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 
 	if (strlen(node_path) + strlen(dev_key_dir) + 1 + 4 >= PATH_MAX)
 		return false;
@@ -161,7 +161,7 @@ bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast,
 bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx,
 						struct keyring_net_key *key)
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 	bool result = false;
 	int fd;
@@ -169,7 +169,7 @@ bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx,
 	if (!node || !key)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir,
 								net_idx);
 
@@ -187,7 +187,7 @@ bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx,
 bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx,
 						struct keyring_app_key *key)
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 	bool result = false;
 	int fd;
@@ -195,7 +195,7 @@ bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx,
 	if (!node || !key)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir,
 								app_idx);
 
@@ -213,7 +213,7 @@ bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx,
 bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast,
 							uint8_t dev_key[16])
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 	bool result = false;
 	int fd;
@@ -221,7 +221,7 @@ bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast,
 	if (!node)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 	snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path, dev_key_dir,
 								unicast);
 
@@ -238,13 +238,13 @@ bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast,
 
 bool keyring_del_net_key(struct mesh_node *node, uint16_t net_idx)
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 
 	if (!node)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir,
 								net_idx);
 	l_debug("RM Net Key %s", key_file);
@@ -258,13 +258,13 @@ bool keyring_del_net_key(struct mesh_node *node, uint16_t net_idx)
 
 bool keyring_del_app_key(struct mesh_node *node, uint16_t app_idx)
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 
 	if (!node)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 	snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir,
 								app_idx);
 	l_debug("RM App Key %s", key_file);
@@ -276,14 +276,14 @@ bool keyring_del_app_key(struct mesh_node *node, uint16_t app_idx)
 bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast,
 								uint8_t count)
 {
-	char *node_path;
+	const char *node_path;
 	char key_file[PATH_MAX];
 	int i;
 
 	if (!node)
 		return false;
 
-	node_path = node_path_get(node);
+	node_path = node_get_storage_dir(node);
 	for (i = 0; i < count; i++) {
 		snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path,
 						dev_key_dir, unicast + i);
diff --git a/mesh/node.c b/mesh/node.c
index 56489a8db..79e165fca 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -22,6 +22,8 @@
 #endif
 
 #define _GNU_SOURCE
+#include <dirent.h>
+#include <stdio.h>
 
 #include <sys/time.h>
 
@@ -83,7 +85,7 @@ struct mesh_node {
 	struct mesh_agent *agent;
 	char *path;
 	struct mesh_config *cfg;
-	char *node_path;
+	char *storage_dir;
 	uint32_t disc_watch;
 	time_t upd_sec;
 	uint32_t seq_number;
@@ -269,6 +271,7 @@ static void free_node_resources(void *data)
 
 	mesh_net_free(node->net);
 	l_free(node->comp);
+	l_free(node->storage_dir);
 	l_free(node);
 }
 
@@ -1518,6 +1521,29 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 	return true;
 }
 
+static bool init_storage_dir(struct mesh_node *node)
+{
+	char uuid[33];
+	char dir_name[PATH_MAX];
+
+	if (node->storage_dir)
+		return true;
+
+	if (!hex2str(node->uuid, 16, uuid, sizeof(uuid)))
+		return false;
+
+	snprintf(dir_name, PATH_MAX, "%s/%s", mesh_get_storage_dir(), uuid);
+
+	if (strlen(dir_name) >= PATH_MAX)
+		return false;
+
+	create_dir(dir_name);
+
+	node->storage_dir = l_strdup(dir_name);
+
+	return true;
+}
+
 static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data)
 {
 	struct l_dbus_message_iter objects, interfaces;
@@ -1673,6 +1699,9 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data)
 						net_key.old_key))
 			goto fail;
 
+		/* Initialize directory for storing keyring info */
+		init_storage_dir(node);
+
 		if (!keyring_put_remote_dev_key(node, DEFAULT_NEW_UNICAST,
 							num_ele, dev_key))
 			goto fail;
@@ -2073,15 +2102,9 @@ struct mesh_config *node_config_get(struct mesh_node *node)
 	return node->cfg;
 }
 
-void node_path_set(struct mesh_node *node, char *path)
-{
-	l_free(node->node_path);
-	node->node_path = l_strdup(path);
-}
-
-char *node_path_get(struct mesh_node *node)
+const char *node_get_storage_dir(struct mesh_node *node)
 {
-	return node->node_path;
+	return node->storage_dir;
 }
 
 const char *node_get_app_path(struct mesh_node *node)
diff --git a/mesh/node.h b/mesh/node.h
index e387b4d09..56ca796cd 100644
--- a/mesh/node.h
+++ b/mesh/node.h
@@ -100,7 +100,6 @@ uint16_t node_id_get(struct mesh_node *node);
 bool node_dbus_init(struct l_dbus *bus);
 void node_cleanup_all(void);
 struct mesh_config *node_config_get(struct mesh_node *node);
-void node_path_set(struct mesh_node *node, char *path);
-char *node_path_get(struct mesh_node *node);
 struct mesh_agent *node_get_agent(struct mesh_node *node);
+const char *node_get_storage_dir(struct mesh_node *node);
 bool node_load_from_storage(const char *storage_dir);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH BlueZ 10/10 v3] mesh: Rename mesh_config_srv_init() to cfgmod_server_init()
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (8 preceding siblings ...)
  2019-07-14 23:23 ` [PATCH BlueZ 09/10 v3] mesh: Create or re-use a node storage directory for keyring Inga Stotland
@ 2019-07-14 23:23 ` Inga Stotland
  2019-07-15  8:07 ` [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Michał Lowas-Rzechonek
  2019-07-15 22:27 ` Gix, Brian
  11 siblings, 0 replies; 14+ messages in thread
From: Inga Stotland @ 2019-07-14 23:23 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: brian.gix, michal.lowas-rzechonek, jakub.witowski, Inga Stotland

This renames mesh_config_srv_init() to cfgmod_server_init() to avoid
confusion with mesh_config_..> API and to reflect that the call pertains
to configuration server model.
---
 mesh/cfgmod-server.c | 2 +-
 mesh/cfgmod.h        | 2 +-
 mesh/node.c          | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index b256cdd48..71d59fd40 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -1284,7 +1284,7 @@ static const struct mesh_model_ops ops = {
 	.pub = NULL
 };
 
-void mesh_config_srv_init(struct mesh_node *node, uint8_t ele_idx)
+void cfgmod_server_init(struct mesh_node *node, uint8_t ele_idx)
 {
 	l_debug("%2.2x", ele_idx);
 	mesh_model_register(node, ele_idx, CONFIG_SRV_MODEL, &ops, node);
diff --git a/mesh/cfgmod.h b/mesh/cfgmod.h
index 84fa184e5..da8b5b32b 100644
--- a/mesh/cfgmod.h
+++ b/mesh/cfgmod.h
@@ -94,4 +94,4 @@
 #define OP_VEND_MODEL_APP_GET			0x804C
 #define OP_VEND_MODEL_APP_LIST			0x804E
 
-void mesh_config_srv_init(struct mesh_node *node, uint8_t ele_idx);
+void cfgmod_server_init(struct mesh_node *node, uint8_t ele_idx);
diff --git a/mesh/node.c b/mesh/node.c
index 79e165fca..652551756 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -478,7 +478,7 @@ static bool init_from_storage(struct mesh_config_node *db_node,
 		goto fail;
 
 	/* Initialize configuration server model */
-	mesh_config_srv_init(node, PRIMARY_ELE_IDX);
+	cfgmod_server_init(node, PRIMARY_ELE_IDX);
 
 	node->cfg = cfg;
 
@@ -1516,7 +1516,7 @@ static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr,
 	mesh_config_save(node->cfg, true, NULL, NULL);
 
 	/* Initialize configuration server model */
-	mesh_config_srv_init(node, PRIMARY_ELE_IDX);
+	cfgmod_server_init(node, PRIMARY_ELE_IDX);
 
 	return true;
 }
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (9 preceding siblings ...)
  2019-07-14 23:23 ` [PATCH BlueZ 10/10 v3] mesh: Rename mesh_config_srv_init() to cfgmod_server_init() Inga Stotland
@ 2019-07-15  8:07 ` Michał Lowas-Rzechonek
  2019-07-15 16:59   ` Stotland, Inga
  2019-07-15 22:27 ` Gix, Brian
  11 siblings, 1 reply; 14+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-07-15  8:07 UTC (permalink / raw)
  To: Inga Stotland; +Cc: linux-bluetooth, brian.gix, jakub.witowski

Hello,

On 07/14, Inga Stotland wrote:
> + rebase off the tip
> 
> This set of patches introduces the notion of generic mesh-config API
> that allows the daemon to be agnostic of the underlying node configuration
> directory layout and the format of the file(s) in which node configuration
> is saved. 
> 
> Currently, the daemon supports only JSON-based configuration format.
> It is expected that other configuration formats may be added in future.
> 
> As a result of these changes, storage.c and storage.h are obsolete
> and are removed.
> 
> Inga Stotland (10):
>   mesh: Move network config setup from storage.c to node.c
>   mesh: Rename mesh-db.c to mesh-config-json.c
>   mesh: Change mesh_db prefix to mesh_config
>   mesh: Move load from storage functionality into node.c
>   mesh: Confine dependency on json-c to mesh-config-json.c
>   mesh: Replace storage_save_config with mesh_config_save_config
>   mesh: Use mesh_config APIs to store node configuration
>   mesh: Manage node config directory in mesh-config
>   mesh: Create or re-use a node storage directory for keyring
>   mesh: Rename mesh_config_srv_init() to cfgmod_server_init()
> 
>  Makefile.mesh                          |    3 +-
>  mesh/appkey.c                          |   19 +-
>  mesh/cfgmod-server.c                   |   31 +-
>  mesh/cfgmod.h                          |    2 +-
>  mesh/keyring.c                         |   36 +-
>  mesh/{mesh-db.c => mesh-config-json.c} | 1071 +++++++++++++++++-------
>  mesh/mesh-config.h                     |  172 ++++
>  mesh/mesh-db.h                         |  157 ----
>  mesh/mesh.c                            |   15 +-
>  mesh/mesh.h                            |    1 +
>  mesh/model.c                           |   23 +-
>  mesh/net.c                             |   26 +-
>  mesh/node.c                            |  224 +++--
>  mesh/node.h                            |   13 +-
>  mesh/storage.c                         |  656 ---------------
>  mesh/storage.h                         |   51 --
>  mesh/util.c                            |   39 +-
>  mesh/util.h                            |    1 +
>  18 files changed, 1219 insertions(+), 1321 deletions(-)
>  rename mesh/{mesh-db.c => mesh-config-json.c} (58%)
>  create mode 100644 mesh/mesh-config.h
>  delete mode 100644 mesh/mesh-db.h
>  delete mode 100644 mesh/storage.c
>  delete mode 100644 mesh/storage.h
> 
> -- 
> 2.21.0
> 

Reviewed-by: Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>


I have a style question (as usual, unrelated to this patchset ;) - do we
have a preferred way for verb usage in (public) function names?

At the moment I see:
 - mesh_config_create vs mesh_net_new - my preference is _new/_free
 - mesh_net_node_get vs mesh_net_get_io - my preference is to place verbs at the end

-- 
Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org
  2019-07-15  8:07 ` [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Michał Lowas-Rzechonek
@ 2019-07-15 16:59   ` Stotland, Inga
  0 siblings, 0 replies; 14+ messages in thread
From: Stotland, Inga @ 2019-07-15 16:59 UTC (permalink / raw)
  To: michal.lowas-rzechonek; +Cc: jakub.witowski, linux-bluetooth, Gix, Brian

[-- Attachment #1: Type: text/plain, Size: 3551 bytes --]

Hi Michal,

On Mon, 2019-07-15 at 10:07 +0200, Michał Lowas-Rzechonek wrote:
> Hello,
> 
> On 07/14, Inga Stotland wrote:
> > + rebase off the tip
> > 
> > This set of patches introduces the notion of generic mesh-config
> > API
> > that allows the daemon to be agnostic of the underlying node
> > configuration
> > directory layout and the format of the file(s) in which node
> > configuration
> > is saved. 
> > 
> > Currently, the daemon supports only JSON-based configuration
> > format.
> > It is expected that other configuration formats may be added in
> > future.
> > 
> > As a result of these changes, storage.c and storage.h are obsolete
> > and are removed.
> > 
> > Inga Stotland (10):
> >   mesh: Move network config setup from storage.c to node.c
> >   mesh: Rename mesh-db.c to mesh-config-json.c
> >   mesh: Change mesh_db prefix to mesh_config
> >   mesh: Move load from storage functionality into node.c
> >   mesh: Confine dependency on json-c to mesh-config-json.c
> >   mesh: Replace storage_save_config with mesh_config_save_config
> >   mesh: Use mesh_config APIs to store node configuration
> >   mesh: Manage node config directory in mesh-config
> >   mesh: Create or re-use a node storage directory for keyring
> >   mesh: Rename mesh_config_srv_init() to cfgmod_server_init()
> > 
> >  Makefile.mesh                          |    3 +-
> >  mesh/appkey.c                          |   19 +-
> >  mesh/cfgmod-server.c                   |   31 +-
> >  mesh/cfgmod.h                          |    2 +-
> >  mesh/keyring.c                         |   36 +-
> >  mesh/{mesh-db.c => mesh-config-json.c} | 1071 +++++++++++++++++---
> > ----
> >  mesh/mesh-config.h                     |  172 ++++
> >  mesh/mesh-db.h                         |  157 ----
> >  mesh/mesh.c                            |   15 +-
> >  mesh/mesh.h                            |    1 +
> >  mesh/model.c                           |   23 +-
> >  mesh/net.c                             |   26 +-
> >  mesh/node.c                            |  224 +++--
> >  mesh/node.h                            |   13 +-
> >  mesh/storage.c                         |  656 ---------------
> >  mesh/storage.h                         |   51 --
> >  mesh/util.c                            |   39 +-
> >  mesh/util.h                            |    1 +
> >  18 files changed, 1219 insertions(+), 1321 deletions(-)
> >  rename mesh/{mesh-db.c => mesh-config-json.c} (58%)
> >  create mode 100644 mesh/mesh-config.h
> >  delete mode 100644 mesh/mesh-db.h
> >  delete mode 100644 mesh/storage.c
> >  delete mode 100644 mesh/storage.h
> > 
> > -- 
> > 2.21.0
> > 
> 
> Reviewed-by: Michał Lowas-Rzechonek <
> michal.lowas-rzechonek@silvair.com>
> 
> 
> I have a style question (as usual, unrelated to this patchset ;) - do
> we
> have a preferred way for verb usage in (public) function names?
> 
> At the moment I see:
>  - mesh_config_create vs mesh_net_new - my preference is _new/_free
>  - mesh_net_node_get vs mesh_net_get_io - my preference is to place
> verbs at the end
> 

My preference is to have verb at the end, but it seems (and maybe I am
mistaken), that bluez in general favors this style:

uint16_t bt_att_get_mtu(struct bt_att *att);
bool bt_att_set_mtu(struct bt_att *att, uint16_t mtu);

I personally don't relly like mixing the styles (although I am guilty
of this myself). So in this patch set tried to stick to the one that's
prevalent in bluez.

Best regards,
Inga

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 3265 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org
  2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
                   ` (10 preceding siblings ...)
  2019-07-15  8:07 ` [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Michał Lowas-Rzechonek
@ 2019-07-15 22:27 ` Gix, Brian
  11 siblings, 0 replies; 14+ messages in thread
From: Gix, Brian @ 2019-07-15 22:27 UTC (permalink / raw)
  To: linux-bluetooth, Stotland, Inga; +Cc: michal.lowas-rzechonek, jakub.witowski

Patch-Set applied, Thanks.

On Sun, 2019-07-14 at 16:23 -0700, Inga Stotland wrote:
> + rebase off the tip
> 
> This set of patches introduces the notion of generic mesh-config API
> that allows the daemon to be agnostic of the underlying node configuration
> directory layout and the format of the file(s) in which node configuration
> is saved. 
> 
> Currently, the daemon supports only JSON-based configuration format.
> It is expected that other configuration formats may be added in future.
> 
> As a result of these changes, storage.c and storage.h are obsolete
> and are removed.
> 
> Inga Stotland (10):
>   mesh: Move network config setup from storage.c to node.c
>   mesh: Rename mesh-db.c to mesh-config-json.c
>   mesh: Change mesh_db prefix to mesh_config
>   mesh: Move load from storage functionality into node.c
>   mesh: Confine dependency on json-c to mesh-config-json.c
>   mesh: Replace storage_save_config with mesh_config_save_config
>   mesh: Use mesh_config APIs to store node configuration
>   mesh: Manage node config directory in mesh-config
>   mesh: Create or re-use a node storage directory for keyring
>   mesh: Rename mesh_config_srv_init() to cfgmod_server_init()
> 
>  Makefile.mesh                          |    3 +-
>  mesh/appkey.c                          |   19 +-
>  mesh/cfgmod-server.c                   |   31 +-
>  mesh/cfgmod.h                          |    2 +-
>  mesh/keyring.c                         |   36 +-
>  mesh/{mesh-db.c => mesh-config-json.c} | 1071 +++++++++++++++++-------
>  mesh/mesh-config.h                     |  172 ++++
>  mesh/mesh-db.h                         |  157 ----
>  mesh/mesh.c                            |   15 +-
>  mesh/mesh.h                            |    1 +
>  mesh/model.c                           |   23 +-
>  mesh/net.c                             |   26 +-
>  mesh/node.c                            |  224 +++--
>  mesh/node.h                            |   13 +-
>  mesh/storage.c                         |  656 ---------------
>  mesh/storage.h                         |   51 --
>  mesh/util.c                            |   39 +-
>  mesh/util.h                            |    1 +
>  18 files changed, 1219 insertions(+), 1321 deletions(-)
>  rename mesh/{mesh-db.c => mesh-config-json.c} (58%)
>  create mode 100644 mesh/mesh-config.h
>  delete mode 100644 mesh/mesh-db.h
>  delete mode 100644 mesh/storage.c
>  delete mode 100644 mesh/storage.h
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2019-07-15 22:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-14 23:23 [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 01/10 v3] mesh: Move network config setup from storage.c to node.c Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 02/10 v3] mesh: Rename mesh-db.c to mesh-config-json.c Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 03/10 v3] mesh: Change mesh_db prefix to mesh_config Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 04/10 v3] mesh: Move load from storage functionality into node.c Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 05/10 v3] mesh: Confine dependency on json-c to mesh-config-json.c Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 06/10 v3] mesh: Replace storage_save_config with mesh_config_save_config Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 07/10 v3] mesh: Use mesh_config APIs to store node configuration Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 08/10 v3] mesh: Manage node config directory in mesh-config Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 09/10 v3] mesh: Create or re-use a node storage directory for keyring Inga Stotland
2019-07-14 23:23 ` [PATCH BlueZ 10/10 v3] mesh: Rename mesh_config_srv_init() to cfgmod_server_init() Inga Stotland
2019-07-15  8:07 ` [PATCH BlueZ 00/10 v3] mesh: Configuration storage re-org Michał Lowas-Rzechonek
2019-07-15 16:59   ` Stotland, Inga
2019-07-15 22:27 ` Gix, Brian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).