public inbox for linux-bluetooth@vger.kernel.org
 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 7/9] mesh: Implement config read/write for mesh json format
Date: Tue,  9 Jul 2019 22:09:57 -0700	[thread overview]
Message-ID: <20190710050959.7321-8-inga.stotland@intel.com> (raw)
In-Reply-To: <20190710050959.7321-1-inga.stotland@intel.com>

This adds implementation of
mesh_config_create_config(), mesh_config_release_config(),
mesh_config_get_config(), mesh_config_get_config_backup(),
mesh_config_restore_backup() and mesh_config_save_config()
for the JSON based node configuration storage.
---
 mesh/mesh-config-json.c | 171 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/mesh/mesh-config-json.c b/mesh/mesh-config-json.c
index 5ca086ad0..3c65b3846 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 <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <ell/ell.h>
 #include <json-c/json.h>
@@ -35,6 +40,10 @@
 
 #define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095))
 
+static const char *cfg_name = "/node.json";
+static const char *bak_name = "/node.json.bak";
+static const char *tmp_name = "/node.json.tmp";
+
 static bool get_int(json_object *jobj, const char *keyword, int *value)
 {
 	json_object *jvalue;
@@ -1827,3 +1836,165 @@ bool mesh_config_model_sub_del_all(void *cfg, uint16_t addr, uint32_t mod_id,
 
 	return delete_model_property(jnode, addr, mod_id, vendor, "subscribe");
 }
+
+static char *create_filename(const char *dir, const char *fname)
+{
+	size_t path_len = strlen(dir) + strlen(fname);
+
+	if (path_len + 1 >= PATH_MAX)
+		return NULL;
+
+	return l_strdup_printf("%s%s", dir, fname);
+}
+
+static void *get_node_config(const char *dir, const char *fname)
+{
+	int fd;
+	char *str = NULL, *fname_full;
+	struct stat st;
+	ssize_t sz;
+	json_object *jconfig = NULL;
+
+	fname_full = create_filename(dir, fname);
+	if (!fname)
+		return NULL;
+
+	l_info("Loading configuration from %s", fname_full);
+
+	fd = open(fname_full, O_RDONLY);
+	if (fd < 0)
+		goto done;
+
+	if (fstat(fd, &st) == -1)
+		goto done;
+
+	str = (char *) l_new(char, st.st_size + 1);
+	if (!str)
+		goto done;
+
+	sz = read(fd, str, st.st_size);
+	if (sz != st.st_size) {
+		l_error("Failed to read configuration file %s", fname_full);
+		goto done;
+	}
+
+	jconfig = json_tokener_parse(str);
+
+done:
+	if (fd >= 0)
+		close(fd);
+
+	l_free(str);
+	l_free(fname_full);
+
+	return jconfig;
+}
+
+void *mesh_config_get_config(const char *dir)
+{
+	if (!dir)
+		return NULL;
+
+	return get_node_config(dir, cfg_name);
+}
+
+void *mesh_config_get_config_backup(const char *dir)
+{
+	if (!dir)
+		return NULL;
+
+	return get_node_config(cfg_name, bak_name);
+}
+
+bool mesh_config_restore_backup(const char *dir)
+{
+	char *fname_cfg = NULL, *fname_bak = NULL;
+	bool res = false;
+
+	fname_cfg = create_filename(dir, cfg_name);
+	fname_bak = create_filename(dir, bak_name);
+
+	if (fname_cfg && fname_bak) {
+		remove(fname_cfg);
+		rename(fname_bak, fname_cfg);
+		res = true;
+	}
+
+	l_free(fname_bak);
+	l_free(fname_cfg);
+
+	return res;
+}
+
+static bool save_config(void *cfg, const char *fname)
+{
+	FILE *outfile;
+	const char *str;
+	bool result = false;
+	json_object *jnode = cfg;
+
+	outfile = fopen(fname, "w");
+
+	if (!outfile)
+		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;
+}
+
+void *mesh_config_create_config(void)
+{
+	return json_object_new_object();
+}
+
+void mesh_config_release_config(void *cfg)
+{
+	json_object *jnode = cfg;
+
+	if (!cfg)
+		return;
+
+	json_object_put(jnode);
+}
+
+bool mesh_config_save_config(const char *dir, void *cfg)
+{
+	char *fname_cfg;
+	char *fname_bak;
+	char *fname_tmp;
+	bool result = false;
+
+	fname_cfg = create_filename(dir, cfg_name);
+	fname_bak = create_filename(dir, bak_name);
+	fname_tmp = create_filename(dir, tmp_name);
+
+	if (!fname_cfg || !fname_bak || !fname_tmp)
+		goto done;
+
+	result = save_config(cfg, fname_tmp);
+
+	if (result) {
+		remove(fname_bak);
+		rename(fname_cfg, fname_bak);
+		rename(fname_tmp, fname_cfg);
+	} else {
+		l_error("Failed to save configuration to %s", fname_tmp);
+	}
+
+	remove(fname_tmp);
+
+done:
+	l_free(fname_cfg);
+	l_free(fname_bak);
+	l_free(fname_tmp);
+
+	return result;
+}
-- 
2.21.0


  parent reply	other threads:[~2019-07-10  5:10 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-10  5:09 [PATCH BlueZ 0/9] mesh: Configuration storage re-org Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 1/9] mesh: Move network config setup from storage.c to node.c Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 2/9] mesh: Rename mesh-db.c to mesh-config-json.c Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 3/9] mesh: Change mesh_db prefix to mesh_config Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 4/9] mesh: Generalize mesh-config APIs Inga Stotland
2019-07-10  7:38   ` Michał Lowas-Rzechonek
2019-07-10 15:01     ` Michał Lowas-Rzechonek
2019-07-10 15:58       ` Stotland, Inga
2019-07-10  5:09 ` [PATCH BlueZ 5/9] mesh: Change variable prefix "jconfig" to "config" Inga Stotland
2019-07-10  8:29   ` Michał Lowas-Rzechonek
2019-07-10  5:09 ` [PATCH BlueZ 6/9] mesh: Define storage format specific read/write routines Inga Stotland
2019-07-10  7:52   ` Michał Lowas-Rzechonek
2019-07-10 16:53     ` Stotland, Inga
2019-07-10 17:00       ` michal.lowas-rzechonek
2019-07-10 17:20     ` Gix, Brian
2019-07-10 19:32       ` Michal Lowas-Rzechonek
2019-07-10  5:09 ` Inga Stotland [this message]
2019-07-10  5:09 ` [PATCH BlueZ 8/9] mesh: Switch to using mesh-config routines for storage Inga Stotland
2019-07-10  5:09 ` [PATCH BlueZ 9/9] mesh: Make storage.c json-c agnostic 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=20190710050959.7321-8-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