linux-bluetooth.vger.kernel.org archive mirror
 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 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).