All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings
@ 2019-03-08 22:58 Inga Stotland
  2019-03-08 22:58 ` [PATCH BlueZ 1/3] mesh: Add json config functions to save pub/sub updates Inga Stotland
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Inga Stotland @ 2019-03-08 22:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This patch set implements the following:
- Write updates of node model subscriptions to node config file
- Write updates of node model publication settings to node config file
- Correctly restore subscriptions and publications on daemon startup

Inga Stotland (3):
  mesh: Add json config functions to save pub/sub updates
  mesh: Save model subscription updates to config file
  mesh: Store model publication settings in config file

 mesh/cfgmod-server.c | 104 +++++++++++++++-
 mesh/mesh-db.c       | 282 ++++++++++++++++++++++++++++++++++++++++++-
 mesh/mesh-db.h       |  15 ++-
 mesh/model.c         |  22 ++--
 4 files changed, 404 insertions(+), 19 deletions(-)

-- 
2.17.2


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

* [PATCH BlueZ 1/3] mesh: Add json config functions to save pub/sub updates
  2019-03-08 22:58 [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings Inga Stotland
@ 2019-03-08 22:58 ` Inga Stotland
  2019-03-08 22:58 ` [PATCH BlueZ 2/3] mesh: Save model subscription updates to config file Inga Stotland
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Inga Stotland @ 2019-03-08 22:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This adds functions to save updates to model subscriptions and
publication in JSON format.
---
 mesh/mesh-db.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++-
 mesh/mesh-db.h |  13 ++-
 mesh/model.c   |   4 +-
 3 files changed, 292 insertions(+), 5 deletions(-)

diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index 2d518c1aa..01859f524 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -66,6 +66,32 @@ static bool add_key_value(json_object *jobject, const char *desc,
 	return true;
 }
 
+static int get_element_index(json_object *jnode, uint16_t ele_addr)
+{
+	json_object *jvalue, *jelements;
+	uint16_t addr, num_ele;
+	char *str;
+
+	json_object_object_get_ex(jnode, "unicastAddress", &jvalue);
+	if (!jvalue)
+		return -1;
+
+	str = (char *)json_object_get_string(jvalue);
+	if (sscanf(str, "%04hx", &addr) != 1)
+		return -1;
+
+	json_object_object_get_ex(jnode, "elements", &jelements);
+	if (!jelements)
+		return -1;
+
+	num_ele = json_object_array_length(jelements);
+
+	if (ele_addr >= addr + num_ele || ele_addr < addr)
+		return -1;
+
+	return ele_addr - addr;
+}
+
 static json_object *get_element_model(json_object *jnode, int ele_idx,
 						uint32_t mod_id, bool vendor)
 {
@@ -800,10 +826,18 @@ static struct mesh_db_pub *parse_model_publication(json_object *jpub)
 		goto fail;
 	pub->credential = (uint8_t) value;
 
-	if (!get_int(jpub, "retransmit", &value))
+	json_object_object_get_ex(jpub, "retransmit", &jvalue);
+	if (!jvalue)
 		goto fail;
 
-	pub->retransmit = (uint8_t) value;
+	if (!get_int(jvalue, "count", &value))
+		goto fail;
+	pub->count = (uint8_t) value;
+
+	if (!get_int(jvalue, "interval", &value))
+		goto fail;
+	pub->interval = (uint8_t) value;
+
 	return pub;
 
 fail:
@@ -1133,6 +1167,9 @@ bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
 	json_object *jvalue;
 	char *str;
 
+	if (!jnode)
+		return false;
+
 	if (!cb) {
 		l_info("Node read callback is required");
 		return false;
@@ -1185,6 +1222,9 @@ bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
 	json_object *jstring;
 	char buf[5];
 
+	if (!jobj)
+		return false;
+
 	snprintf(buf, 5, "%4.4x", value);
 	jstring = json_object_new_string(buf);
 	if (!jstring)
@@ -1200,6 +1240,9 @@ bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
 	json_object *jstring;
 	char buf[9];
 
+	if (!jobj)
+		return false;
+
 	snprintf(buf, 9, "%8.8x", value);
 	jstring = json_object_new_string(buf);
 	if (!jstring)
@@ -1213,6 +1256,9 @@ bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
 {
 	json_object *jvalue;
 
+	if (!jobj)
+		return false;
+
 	json_object_object_del(jobj, keyword);
 
 	jvalue = json_object_new_int(value);
@@ -1227,6 +1273,9 @@ bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value)
 {
 	json_object *jvalue;
 
+	if (!jobj)
+		return false;
+
 	json_object_object_del(jobj, keyword);
 
 	jvalue = json_object_new_boolean(value);
@@ -1253,6 +1302,9 @@ bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
 {
 	json_object *jstring;
 
+	if (!jobj)
+		return false;
+
 	jstring = json_object_new_string(mode_to_string(value));
 
 	if (!jstring)
@@ -1268,6 +1320,9 @@ bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
 {
 	json_object *jrelay;
 
+	if (!jnode)
+		return false;
+
 	json_object_object_del(jnode, "relay");
 
 	jrelay = json_object_new_object();
@@ -1296,6 +1351,9 @@ bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
 {
 	json_object *jretransmit, *jvalue;
 
+	if (!jobj)
+		return false;
+
 	json_object_object_get_ex(jobj, "retransmit", &jretransmit);
 	if (!jretransmit)
 		return false;
@@ -1320,6 +1378,9 @@ bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
 {
 	json_object *jretransmit;
 
+	if (!jobj)
+		return false;
+
 	json_object_object_del(jobj, "retransmit");
 
 	jretransmit = json_object_new_object();
@@ -1345,6 +1406,9 @@ bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
 {
 	int tmp = update ? 1 : 0;
 
+	if (!jobj)
+		return false;
+
 	if (!mesh_db_write_int(jobj, "IVindex", idx))
 		return false;
 
@@ -1356,7 +1420,8 @@ bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
 
 void mesh_db_remove_property(json_object *jobj, const char *desc)
 {
-	json_object_object_del(jobj, desc);
+	if (jobj)
+		json_object_object_del(jobj, desc);
 }
 
 static void add_model(void *a, void *b)
@@ -1384,6 +1449,9 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
 	const struct l_queue_entry *entry;
 	json_object *jelements;
 
+	if (!jnode)
+		return false;
+
 	/* CID, PID, VID, crpl */
 	if (!mesh_db_write_uint16_hex(jnode, "cid", node->cid))
 		return false;
@@ -1505,6 +1573,9 @@ bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
 {
 	json_object *jarray, *jentry = NULL;
 
+	if (!jobj)
+		return false;
+
 	json_object_object_get_ex(jobj, "netKeys", &jarray);
 
 	if (jarray)
@@ -1524,3 +1595,205 @@ bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
 
 	return true;
 }
+
+bool mesh_db_model_pub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
+					bool vendor, struct mesh_db_pub *pub)
+{
+	json_object *jmodel, *jpub, *jretransmit;
+	bool res;
+	int ele_idx;
+
+	if (!jnode)
+		return false;
+
+	ele_idx = get_element_index(jnode, addr);
+	if (ele_idx < 0)
+		return false;
+
+	jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+	if (!jmodel)
+		return false;
+
+	json_object_object_del(jmodel, "publish");
+
+	jpub = json_object_new_object();
+	if (!jpub)
+		return false;
+
+	if (pub->virt)
+		res = add_key_value(jpub, "address", pub->virt_addr);
+	else
+		res = mesh_db_write_uint16_hex(jpub, "address", pub->addr);
+
+	if (!res)
+		goto fail;
+
+	if (!mesh_db_write_uint16_hex(jpub, "index", pub->idx))
+		goto fail;
+
+	if (!mesh_db_write_int(jpub, "ttl", pub->ttl))
+		goto fail;
+
+	if (!mesh_db_write_int(jpub, "period", pub->period))
+		goto fail;
+
+	if (!mesh_db_write_int(jpub, "credentials", pub->credential ? 1 : 0))
+		goto fail;
+
+	jretransmit = json_object_new_object();
+	if (!jretransmit)
+		goto fail;
+
+	if (!mesh_db_write_int(jretransmit, "count", pub->count))
+		goto fail;
+
+	if (!mesh_db_write_int(jretransmit, "interval", pub->interval))
+		goto fail;
+
+	json_object_object_add(jpub, "retransmit", jretransmit);
+	json_object_object_add(jmodel, "publish", jpub);
+
+	return true;
+fail:
+	json_object_put(jpub);
+	return false;
+}
+
+static bool delete_model_property(json_object *jnode, uint16_t addr,
+			uint32_t mod_id, bool vendor, const char *keyword)
+{
+	json_object *jmodel;
+	int ele_idx;
+
+	ele_idx = get_element_index(jnode, addr);
+	if (ele_idx < 0)
+		return false;
+
+	jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+	if (!jmodel)
+		return false;
+
+	json_object_object_del(jmodel, keyword);
+
+	return true;
+}
+
+bool mesh_db_model_pub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
+								bool vendor)
+{
+	if (!jnode)
+		return false;
+
+	return delete_model_property(jnode, addr, mod_id, vendor, "publish");
+}
+
+bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
+					bool vendor, struct mesh_db_sub *sub)
+{
+	json_object *jmodel, *jstring, *jarray;
+	int ele_idx, len;
+	char buf[33];
+
+	if (!jnode)
+		return false;
+
+	ele_idx = get_element_index(jnode, addr);
+	if (ele_idx < 0)
+		return false;
+
+	jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+	if (!jmodel)
+		return false;
+
+	json_object_object_get_ex(jmodel, "subscribe", &jarray);
+
+	if (!sub->virt) {
+		snprintf(buf, 5, "%4.4x", sub->src.addr);
+		len = 4;
+	} else {
+		hex2str(sub->src.virt_addr, 16, buf, 33);
+		len = 32;
+	}
+
+	if (jarray && jarray_has_string(jarray, buf, len))
+		return true;
+
+	jstring = json_object_new_string(buf);
+	if (!jstring)
+		return false;
+
+	if (!jarray) {
+		jarray = json_object_new_array();
+		if (!jarray) {
+			json_object_put(jstring);
+			return false;
+		}
+		json_object_object_add(jmodel, "subscribe", jarray);
+	}
+
+	json_object_array_add(jarray, jstring);
+
+	return true;
+}
+
+bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr,
+			uint32_t mod_id, bool vendor, struct mesh_db_sub *sub)
+{
+	json_object *jmodel, *jarray, *jarray_new;
+	char buf[33];
+	int len, ele_idx;
+
+	if (!jnode)
+		return false;
+
+	ele_idx = get_element_index(jnode, addr);
+	if (ele_idx < 0)
+		return false;
+
+	jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+	if (!jmodel)
+		return false;
+
+	json_object_object_get_ex(jmodel, "subscribe", &jarray);
+	if (!jarray)
+		return true;
+
+	if (!sub->virt) {
+		snprintf(buf, 5, "%4.4x", sub->src.addr);
+		len = 4;
+	} else {
+		hex2str(sub->src.virt_addr, 16, buf, 33);
+		len = 32;
+	}
+
+	if (!jarray_has_string(jarray, buf, len))
+		return true;
+
+	if (json_object_array_length(jarray) == 1) {
+		json_object_object_del(jmodel, "subscribe");
+		return true;
+	}
+
+	/*
+	 * There is no easy way to delete a value from a json array.
+	 * Create a new copy without specified element and
+	 * then remove old array.
+	 */
+	jarray_new = jarray_string_del(jarray, buf, len);
+	if (!jarray_new)
+		return false;
+
+	json_object_object_del(jmodel, "subscribe");
+	json_object_object_add(jmodel, "subscribe", jarray_new);
+
+	return true;
+}
+
+bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr,
+						uint32_t mod_id, bool vendor)
+{
+	if (!jnode)
+		return false;
+
+	return delete_model_property(jnode, addr, mod_id, vendor, "subscribe");
+}
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index 52ea05528..5dec6cb9f 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -32,7 +32,8 @@ struct mesh_db_pub {
 	uint8_t ttl;
 	uint8_t credential;
 	uint8_t period;
-	uint8_t retransmit;
+	uint8_t count;
+	uint8_t interval;
 	uint8_t virt_addr[16];
 };
 
@@ -129,6 +130,16 @@ bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
 					uint32_t mod_id, uint16_t app_idx);
 bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
 					uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_model_pub_add(json_object *jnode, uint16_t ele_addr,
+			uint32_t mod_id, bool vendor, struct mesh_db_pub *pub);
+bool mesh_db_model_pub_del(json_object *jnode, uint16_t ele_addr,
+						uint32_t mod_id, bool vendor);
+bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
+					bool vendor, struct mesh_db_sub *sub);
+bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
+					bool vendor, struct mesh_db_sub *sub);
+bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr,
+						uint32_t mod_id, bool vendor);
 bool mesh_db_app_key_add(json_object *jnode, uint16_t net_idx, uint16_t app_idx,
 							const uint8_t key[16]);
 bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
diff --git a/mesh/model.c b/mesh/model.c
index 5940f6854..dc525f72f 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -1428,13 +1428,15 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
 		struct mesh_db_pub *pub = db_mod->pub;
 		uint8_t mod_addr[2];
 		uint8_t *pub_addr;
+		uint8_t retransmit = (pub->count << 5) +
+						(pub->interval / 50 - 1);
 
 		/* Add publication */
 		l_put_le16(pub->addr, &mod_addr);
 		pub_addr = pub->virt ? pub->virt_addr : (uint8_t *) &mod_addr;
 
 		if (set_pub(mod, pub_addr, pub->idx, pub->credential, pub->ttl,
-			pub->period, pub->retransmit, pub->virt, NULL) !=
+			pub->period, retransmit, pub->virt, NULL) !=
 							MESH_STATUS_SUCCESS) {
 			mesh_model_free(mod);
 			return NULL;
-- 
2.17.2


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

* [PATCH BlueZ 2/3] mesh: Save model subscription updates to config file
  2019-03-08 22:58 [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings Inga Stotland
  2019-03-08 22:58 ` [PATCH BlueZ 1/3] mesh: Add json config functions to save pub/sub updates Inga Stotland
@ 2019-03-08 22:58 ` Inga Stotland
  2019-03-08 22:58 ` [PATCH BlueZ 3/3] mesh: Store model publication settings in " Inga Stotland
  2019-03-11 22:20 ` [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings Gix, Brian
  3 siblings, 0 replies; 5+ messages in thread
From: Inga Stotland @ 2019-03-08 22:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This adds functionality in Config Server model to save changes in
node configuration file when model subscriptions are added, deleted or
overwritten.
---
 mesh/cfgmod-server.c | 60 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 2 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index 9dc82eef6..df2614529 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -37,6 +37,7 @@
 #include "mesh/appkey.h"
 #include "mesh/model.h"
 #include "mesh/storage.h"
+#include "mesh/mesh-db.h"
 
 #include "mesh/cfgmod.h"
 
@@ -195,7 +196,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 	if (IS_UNASSIGNED(ota) && !b_virt)
 		ttl = period = idx = 0;
 
-	if (status >= 0 && !unreliable)
+	if (!unreliable)
 		send_pub_status(node, src, dst, status, ele_addr, ota,
 				mod_id, idx, cred_flag, ttl, period,
 				retransmit);
@@ -285,6 +286,38 @@ static bool config_sub_get(struct mesh_node *node, uint16_t src, uint16_t dst,
 	return true;
 }
 
+static bool save_config_sub(struct mesh_node *node, uint16_t ele_addr,
+					uint32_t mod_id, bool vendor,
+					const uint8_t *addr, bool virt,
+					uint16_t grp, uint32_t opcode)
+{
+	struct mesh_db_sub db_sub = {
+				.virt = virt,
+				.src.addr = grp
+				};
+
+	if (virt)
+		memcpy(db_sub.src.virt_addr, addr, 16);
+
+	if (opcode == OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE ||
+					opcode == OP_CONFIG_MODEL_SUB_OVERWRITE)
+		mesh_db_model_sub_del_all(node_jconfig_get(node),
+				ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
+									vendor);
+
+	if (opcode != OP_CONFIG_MODEL_SUB_VIRT_DELETE &&
+			opcode != OP_CONFIG_MODEL_SUB_DELETE)
+		return mesh_db_model_sub_add(node_jconfig_get(node),
+					ele_addr,
+					vendor ? mod_id : mod_id & 0x0000ffff,
+					vendor, &db_sub);
+	else
+		return mesh_db_model_sub_del(node_jconfig_get(node),
+					ele_addr,
+					vendor ? mod_id : mod_id & 0x0000ffff,
+					vendor, &db_sub);
+}
+
 static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 					const uint8_t *pkt, uint16_t size,
 					bool virt, uint32_t opcode)
@@ -294,6 +327,7 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 	uint32_t mod_id, func;
 	const uint8_t *addr = NULL;
 	int status = 0;
+	bool vendor = false;
 
 	switch (size) {
 	default:
@@ -314,6 +348,7 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 		} else {
 			mod_id = l_get_le16(pkt + 2) << 16;
 			mod_id |= l_get_le16(pkt + 4);
+			vendor = true;
 		}
 		break;
 	case 8:
@@ -321,6 +356,7 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 			return;
 		mod_id = l_get_le16(pkt + 4) << 16;
 		mod_id |= l_get_le16(pkt + 6);
+		vendor = true;
 		break;
 	case 20:
 		if (!virt)
@@ -351,6 +387,11 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 
 	case OP_CONFIG_MODEL_SUB_DELETE_ALL:
 		status = mesh_model_sub_del_all(node, ele_addr, mod_id);
+
+		if (status == MESH_STATUS_SUCCESS)
+			mesh_db_model_sub_del_all(node_jconfig_get(node),
+				ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
+									vendor);
 		break;
 
 	case OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
@@ -359,6 +400,10 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 	case OP_CONFIG_MODEL_SUB_OVERWRITE:
 		status = mesh_model_sub_ovr(node, ele_addr, mod_id,
 							addr, virt, &grp);
+
+		if (status == MESH_STATUS_SUCCESS)
+			save_config_sub(node, ele_addr, mod_id, vendor, addr,
+							virt, grp, opcode);
 		break;
 	case OP_CONFIG_MODEL_SUB_VIRT_ADD:
 		grp = UNASSIGNED_ADDRESS;
@@ -366,6 +411,12 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 	case OP_CONFIG_MODEL_SUB_ADD:
 		status = mesh_model_sub_add(node, ele_addr, mod_id,
 							addr, virt, &grp);
+
+		if (status == MESH_STATUS_SUCCESS &&
+				!save_config_sub(node, ele_addr, mod_id, vendor,
+						addr, virt, grp, opcode))
+			status = MESH_STATUS_STORAGE_FAIL;
+
 		break;
 	case OP_CONFIG_MODEL_SUB_VIRT_DELETE:
 		grp = UNASSIGNED_ADDRESS;
@@ -373,10 +424,15 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 	case OP_CONFIG_MODEL_SUB_DELETE:
 		status = mesh_model_sub_del(node, ele_addr, mod_id,
 							addr, virt, &grp);
+
+		if (status == MESH_STATUS_SUCCESS)
+			save_config_sub(node, ele_addr, mod_id, vendor, addr,
+							virt, grp, opcode);
+
 		break;
 	}
 
-	if (!unreliable && status >= 0)
+	if (!unreliable)
 		send_sub_status(node, src, dst, status, ele_addr, grp, mod_id);
 
 }
-- 
2.17.2


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

* [PATCH BlueZ 3/3] mesh: Store model publication settings in config file
  2019-03-08 22:58 [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings Inga Stotland
  2019-03-08 22:58 ` [PATCH BlueZ 1/3] mesh: Add json config functions to save pub/sub updates Inga Stotland
  2019-03-08 22:58 ` [PATCH BlueZ 2/3] mesh: Save model subscription updates to config file Inga Stotland
@ 2019-03-08 22:58 ` Inga Stotland
  2019-03-11 22:20 ` [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings Gix, Brian
  3 siblings, 0 replies; 5+ messages in thread
From: Inga Stotland @ 2019-03-08 22:58 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland

This adds functionality to enable storing model publication
parameters in node configuration file.

Also, fix calculations of model publication period.
---
 mesh/cfgmod-server.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 mesh/mesh-db.c       |  2 +-
 mesh/mesh-db.h       |  2 +-
 mesh/model.c         | 18 +++++++++---------
 4 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index df2614529..737aee376 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -125,6 +125,9 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 	uint8_t retransmit;
 	int status;
 	bool cred_flag, b_virt = false;
+	bool vendor = false;
+	struct mesh_model_pub *pub;
+	uint8_t ele_idx;
 
 	switch (size) {
 	default:
@@ -146,6 +149,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 		retransmit = pkt[8];
 		mod_id = l_get_le16(pkt + 9) << 16;
 		mod_id |= l_get_le16(pkt + 11);
+		vendor = true;
 		break;
 
 	case 25:
@@ -166,6 +170,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 		retransmit = pkt[22];
 		mod_id = l_get_le16(pkt + 23) << 16;
 		mod_id |= l_get_le16(pkt + 25);
+		vendor = true;
 		break;
 	}
 	ele_addr = l_get_le16(pkt);
@@ -193,9 +198,46 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
 	l_debug("pub_set: status %d, ea %4.4x, ota: %4.4x, mod: %x, idx: %3.3x",
 					status, ele_addr, ota, mod_id, idx);
 
-	if (IS_UNASSIGNED(ota) && !b_virt)
+	if (IS_UNASSIGNED(ota) && !b_virt) {
 		ttl = period = idx = 0;
 
+		/* Remove model publication from config file */
+		if (status == MESH_STATUS_SUCCESS)
+			mesh_db_model_pub_del(node_jconfig_get(node), ele_addr,
+					vendor ? mod_id : mod_id & 0x0000ffff,
+					vendor);
+		goto done;
+	}
+
+	if (status != MESH_STATUS_SUCCESS)
+		goto done;
+
+	ele_idx = node_get_element_idx(node, ele_addr);
+	pub = mesh_model_pub_get(node, ele_idx, mod_id, &status);
+
+	if (pub) {
+		struct mesh_db_pub db_pub = {
+			.virt = b_virt,
+			.addr = ota,
+			.idx = idx,
+			.ttl = ttl,
+			.credential = pub->credential,
+			.period = period,
+			.count = pub->retransmit >> 5,
+			.interval = ((0x1f & pub->retransmit) + 1) * 50
+		};
+
+		if (b_virt)
+			memcpy(db_pub.virt_addr, pub_addr, 16);
+
+		/* Save model publication to config file */
+		if (!mesh_db_model_pub_add(node_jconfig_get(node), ele_addr,
+					vendor ? mod_id : mod_id & 0x0000ffff,
+					vendor, &db_pub))
+			status = MESH_STATUS_STORAGE_FAIL;
+	}
+
+done:
 	if (!unreliable)
 		send_pub_status(node, src, dst, status, ele_addr, ota,
 				mod_id, idx, cred_flag, ttl, period,
diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index 01859f524..757cfd4c2 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -820,7 +820,7 @@ static struct mesh_db_pub *parse_model_publication(json_object *jpub)
 
 	if (!get_int(jpub, "period", &value))
 		goto fail;
-	pub->period = (uint8_t) value;
+	pub->period = value;
 
 	if (!get_int(jpub, "credentials", &value))
 		goto fail;
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index 5dec6cb9f..b9af1203b 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -27,11 +27,11 @@ struct mesh_db_sub {
 
 struct mesh_db_pub {
 	bool virt;
+	uint32_t period;
 	uint16_t addr;
 	uint16_t idx;
 	uint8_t ttl;
 	uint8_t credential;
-	uint8_t period;
 	uint8_t count;
 	uint8_t interval;
 	uint8_t virt_addr[16];
diff --git a/mesh/model.c b/mesh/model.c
index dc525f72f..80c30edba 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -178,13 +178,13 @@ static struct mesh_model *find_model(struct mesh_node *node, uint16_t addr,
 	return get_model(node, (uint8_t) ele_idx, mod_id, fail);
 }
 
-static uint32_t convert_pub_period_to_ms(uint8_t pub_period)
+static uint32_t pub_period_to_ms(uint8_t pub_period)
 {
 	int n;
 
-	n = (pub_period & 0x3f);
+	n = pub_period >> 2;
 
-	switch (pub_period >> 6) {
+	switch (pub_period & 0x3) {
 	default:
 		return n * 100;
 	case 2:
@@ -488,8 +488,10 @@ static void remove_pub(struct mesh_node *node, struct mesh_model *mod)
 	l_free(mod->pub);
 	mod->pub = NULL;
 
-	/* TODO: remove from storage */
-
+	/*
+	 * TODO: Instead of reporting  period of 0, report publication
+	 * address as unassigned
+	 */
 	if (!mod->cbs)
 		/* External models */
 		config_update_model_pub_period(node, mod->ele_idx, mod->id, 0);
@@ -1017,8 +1019,6 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id,
 	if (result != MESH_STATUS_SUCCESS)
 		return result;
 
-	/* TODO: save to storage */
-
 	/*
 	 * If the publication address is set to unassigned address value,
 	 * remove publication
@@ -1034,7 +1034,7 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id,
 
 	/* External model */
 	config_update_model_pub_period(node, ele_idx, id,
-					convert_pub_period_to_ms(period));
+						pub_period_to_ms(period));
 
 	return MESH_STATUS_SUCCESS;
 }
@@ -1601,7 +1601,7 @@ void model_build_config(void *model, void *msg_builder)
 
 	/* Model periodic publication interval, if present */
 	if (mod->pub) {
-		uint32_t period = convert_pub_period_to_ms(mod->pub->period);
+		uint32_t period = pub_period_to_ms(mod->pub->period);
 		dbus_append_dict_entry_basic(builder, "PublicationPeriod", "u",
 								&period);
 	}
-- 
2.17.2


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

* Re: [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings
  2019-03-08 22:58 [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings Inga Stotland
                   ` (2 preceding siblings ...)
  2019-03-08 22:58 ` [PATCH BlueZ 3/3] mesh: Store model publication settings in " Inga Stotland
@ 2019-03-11 22:20 ` Gix, Brian
  3 siblings, 0 replies; 5+ messages in thread
From: Gix, Brian @ 2019-03-11 22:20 UTC (permalink / raw)
  To: linux-bluetooth, Stotland, Inga; +Cc: luiz.dentz, johan.hedberg

Patch set applied

On Fri, 2019-03-08 at 14:58 -0800, Inga Stotland wrote:
> This patch set implements the following:
> - Write updates of node model subscriptions to node config file
> - Write updates of node model publication settings to node config file
> - Correctly restore subscriptions and publications on daemon startup
> 
> Inga Stotland (3):
>   mesh: Add json config functions to save pub/sub updates
>   mesh: Save model subscription updates to config file
>   mesh: Store model publication settings in config file
> 
>  mesh/cfgmod-server.c | 104 +++++++++++++++-
>  mesh/mesh-db.c       | 282 ++++++++++++++++++++++++++++++++++++++++++-
>  mesh/mesh-db.h       |  15 ++-
>  mesh/model.c         |  22 ++--
>  4 files changed, 404 insertions(+), 19 deletions(-)
> 

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

end of thread, other threads:[~2019-03-11 22:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-08 22:58 [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings Inga Stotland
2019-03-08 22:58 ` [PATCH BlueZ 1/3] mesh: Add json config functions to save pub/sub updates Inga Stotland
2019-03-08 22:58 ` [PATCH BlueZ 2/3] mesh: Save model subscription updates to config file Inga Stotland
2019-03-08 22:58 ` [PATCH BlueZ 3/3] mesh: Store model publication settings in " Inga Stotland
2019-03-11 22:20 ` [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings Gix, Brian

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.