diff --git a/Makefile.mesh b/Makefile.mesh
index 502ba2a..02b457e 100644
--- a/Makefile.mesh
+++ b/Makefile.mesh
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 033ab41..b256cdd 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
#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 d862691..75015e6 100644
--- a/mesh/mesh-config-json.c
+++ b/mesh/mesh-config-json.c
struct mesh_config {
json_object *jnode;
- char *node_path;
+ char *node_dir_path;
uint8_t uuid[16];
};
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";
json_object_array_add(jarray, jentry);
- return save_config(jnode, cfg->node_path);
+ return save_config(jnode, cfg->node_dir_path);
fail:
if (jentry)
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)
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);
}
/*
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)
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)
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,
json_object_array_add(jarray, jentry);
- return save_config(jnode, cfg->node_path);
+ return save_config(jnode, cfg->node_dir_path);
fail:
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,
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,
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,
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)
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,
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,
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,
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);
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)
}
/* 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;
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;
}
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,
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);
"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,
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,
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,
"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)
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;
}
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;
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;
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;
}
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);
}
}
if (!cfg)
return;
- l_free(cfg->node_path);
+ l_free(cfg->node_dir_path);
json_object_put(cfg->jnode);
l_free(cfg);
}
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);
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;
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 83ba33b..44e3b3a 100644
--- a/mesh/mesh-config.h
+++ b/mesh/mesh-config.h
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 b9e3162..9c6b9a7 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
#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"
/* 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;
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);
return true;
}
+
+const char *mesh_get_storage_dir(void)
+{
+ return storage_dir;
+}
diff --git a/mesh/mesh.h b/mesh/mesh.h
index 78d4d49..e0a3e1b 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
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 ef62a22..785becb 100644
--- a/mesh/model.c
+++ b/mesh/model.c
#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 d90ca2a..56489a8 100644
--- a/mesh/node.c
+++ b/mesh/node.c
#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"
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;
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);
}
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;
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);
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)
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);
{
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);
l_queue_destroy(db_node.elements, l_free);
- return res;
+ return node->cfg != NULL;
}
static void set_defaults(struct mesh_node *node)
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);
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;
{
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 ee62737..e387b4d 100644
--- a/mesh/node.h
+++ b/mesh/node.h
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);
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 6a87662..0000000
--- a/mesh/storage.c
+++ /dev/null
-/*
- *
- * 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 21fd3f5..0000000
--- a/mesh/storage.h
+++ /dev/null
-/*
- *
- * 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 8612322..1455bde 100644
--- a/mesh/util.c
+++ b/mesh/util.c
#endif
#define _GNU_SOURCE
-
+#include <dirent.h>
+#include <ftw.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
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 007ea36..d1e83b5 100644
--- a/mesh/util.h
+++ b/mesh/util.h
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);