linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Inga Stotland <inga.stotland@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: brian.gix@intel.com, michal.lowas-rzechonek@silvair.com,
	jakub.witowski@silvair.com,
	Inga Stotland <inga.stotland@intel.com>
Subject: [PATCH BlueZ 08/10 v2] mesh: Manage node config directory in mesh-config
Date: Sat, 13 Jul 2019 23:28:10 -0700	[thread overview]
Message-ID: <20190714062812.31041-9-inga.stotland@intel.com> (raw)
In-Reply-To: <20190714062812.31041-1-inga.stotland@intel.com>

This completely remove 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 26acfd4dc..9712cc459 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 14b1fb517..f59ef30f2 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
@@ -42,3 +42,4 @@ bool mesh_send_pkt(uint8_t count, uint16_t interval, uint8_t *data,
 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_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 c54c27f9f..decd3d6fc 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"
@@ -193,7 +192,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;
 
@@ -282,8 +281,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);
 }
@@ -391,12 +390,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;
@@ -422,17 +424,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);
 
@@ -468,12 +470,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)
@@ -488,7 +495,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);
@@ -1355,10 +1362,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);
@@ -1370,7 +1378,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)
@@ -1495,7 +1503,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);
@@ -2050,11 +2058,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;
@@ -2075,3 +2078,8 @@ struct mesh_net *node_get_net(struct mesh_node *node)
 {
 	return node->net;
 }
+
+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 b7e4bc761..17c89da26 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);
@@ -98,7 +97,7 @@ 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);
+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


  parent reply	other threads:[~2019-07-14  6:28 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-14  6:28 [PATCH BlueZ 00/10 v2] mesh: Configuration storage re-org Inga Stotland
2019-07-14  6:28 ` [PATCH BlueZ 01/10 v2] mesh: Move network config setup from storage.c to node.c Inga Stotland
2019-07-14  6:28 ` [PATCH BlueZ 02/10 v2] mesh: Rename mesh-db.c to mesh-config-json.c Inga Stotland
2019-07-14  6:28 ` [PATCH BlueZ 03/10 v2] mesh: Change mesh_db prefix to mesh_config Inga Stotland
2019-07-14  6:28 ` [PATCH BlueZ 04/10 v2] mesh: Move load from storage functionality into node.c Inga Stotland
2019-07-14  6:28 ` [PATCH BlueZ 05/10 v2] mesh: Confine dependency on json-c to mesh-config-json.c Inga Stotland
2019-07-14  6:28 ` [PATCH BlueZ 06/10 v2] mesh: Replace storage_save_config with mesh_config_save_config Inga Stotland
2019-07-14  6:28 ` [PATCH BlueZ 07/10 v2] mesh: Use mesh_config APIs to store node configuration Inga Stotland
2019-07-14  6:28 ` Inga Stotland [this message]
2019-07-14  6:28 ` [PATCH BlueZ 09/10 v2] mesh: Create or re-use a node storage directory for keyring Inga Stotland
2019-07-14  6:28 ` [PATCH BlueZ 10/10 v2] mesh: Rename mesh_config_srv_init() to cfgmod_server_init() Inga Stotland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190714062812.31041-9-inga.stotland@intel.com \
    --to=inga.stotland@intel.com \
    --cc=brian.gix@intel.com \
    --cc=jakub.witowski@silvair.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=michal.lowas-rzechonek@silvair.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).