summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.mesh1
-rw-r--r--mesh/cfgmod-server.c1
-rw-r--r--mesh/mesh-config-json.c209
-rw-r--r--mesh/mesh-config.h7
-rw-r--r--mesh/mesh.c15
-rw-r--r--mesh/mesh.h1
-rw-r--r--mesh/model.c1
-rw-r--r--mesh/node.c48
-rw-r--r--mesh/node.h3
-rw-r--r--mesh/storage.c254
-rw-r--r--mesh/storage.h27
-rw-r--r--mesh/util.c39
-rw-r--r--mesh/util.h1
13 files changed, 254 insertions, 353 deletions
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 d86269131..75015e607 100644
--- a/mesh/mesh-config-json.c
+++ b/mesh/mesh-config-json.c
@@ -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);