All of lore.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, Inga Stotland <inga.stotland@intel.com>
Subject: [PATCH BlueZ 08/20] tools/mesh-cfgclient: Store remote node's model subs
Date: Wed, 22 Sep 2021 20:25:51 -0700	[thread overview]
Message-ID: <20210923032603.50536-9-inga.stotland@intel.com> (raw)
In-Reply-To: <20210923032603.50536-1-inga.stotland@intel.com>

Update remote node's model subscriptions after a successful completion
of "sub-add", "sub-del", "sub-wrt" and "sub-del_all" commands.
---
 tools/mesh/cfgcli.c  |  68 +++++++++++++----
 tools/mesh/mesh-db.c | 178 +++++++++++++++++++++++++++++++++++++++++++
 tools/mesh/mesh-db.h |  17 +++++
 3 files changed, 250 insertions(+), 13 deletions(-)

diff --git a/tools/mesh/cfgcli.c b/tools/mesh/cfgcli.c
index c3241a9b7..71bf2e706 100644
--- a/tools/mesh/cfgcli.c
+++ b/tools/mesh/cfgcli.c
@@ -387,14 +387,21 @@ static void print_appkey_list(uint16_t len, uint8_t *data)
 	}
 }
 
+static bool match_group_addr(const void *a, const void *b)
+{
+	const struct mesh_group *grp = a;
+	uint16_t addr = L_PTR_TO_UINT(b);
+
+	return grp->addr == addr;
+}
+
 static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
 							uint16_t len)
 {
-	uint32_t opcode;
+	uint32_t opcode, mod_id;
 	const struct cfg_cmd *cmd;
-	uint16_t app_idx, net_idx, addr;
-	uint16_t ele_addr;
-	uint32_t mod_id;
+	uint16_t app_idx, net_idx, addr, ele_addr;
+	struct mesh_group *grp;
 	struct model_pub pub;
 	int n;
 	struct pending_req *req;
@@ -664,10 +671,53 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
 		addr = get_le16(data + 3);
 		bt_shell_printf("Element Addr\t%4.4x\n", ele_addr);
 
-		print_mod_id(data + 5, len == 9, "");
+		mod_id = print_mod_id(data + 5, len == 9, "");
 
 		bt_shell_printf("Subscr Addr\t%4.4x\n", addr);
 
+		grp = l_queue_find(groups, match_group_addr,
+							L_UINT_TO_PTR(addr));
+
+		if (data[0] != MESH_STATUS_SUCCESS || !cmd)
+			return true;
+
+		switch (cmd->opcode) {
+		default:
+			return true;
+		case OP_CONFIG_MODEL_SUB_ADD:
+			mesh_db_node_model_add_sub(src, ele_addr, len == 9,
+								mod_id, addr);
+			break;
+		case OP_CONFIG_MODEL_SUB_DELETE:
+			mesh_db_node_model_del_sub(src, ele_addr, len == 9,
+								mod_id, addr);
+			break;
+		case OP_CONFIG_MODEL_SUB_OVERWRITE:
+			mesh_db_node_model_overwrt_sub(src, ele_addr, len == 9,
+								mod_id, addr);
+			break;
+		case OP_CONFIG_MODEL_SUB_DELETE_ALL:
+			mesh_db_node_model_del_sub_all(src, ele_addr, len == 9,
+									mod_id);
+			break;
+		case OP_CONFIG_MODEL_SUB_VIRT_ADD:
+			if (grp)
+				mesh_db_node_model_add_sub_virt(src, ele_addr,
+						len == 9, mod_id, grp->label);
+			break;
+		case OP_CONFIG_MODEL_SUB_VIRT_DELETE:
+			if (grp)
+				mesh_db_node_model_del_sub_virt(src, ele_addr,
+						len == 9, mod_id, grp->label);
+			break;
+		case OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
+			if (grp)
+				mesh_db_node_model_overwrt_sub_virt(src,
+							ele_addr, len == 9,
+							mod_id, grp->label);
+			break;
+		}
+
 		break;
 
 	/* Per Mesh Profile 4.3.2.27 */
@@ -820,14 +870,6 @@ static uint32_t read_input_parameters(int argc, char *argv[])
 	return i;
 }
 
-static bool match_group_addr(const void *a, const void *b)
-{
-	const struct mesh_group *grp = a;
-	uint16_t addr = L_PTR_TO_UINT(b);
-
-	return grp->addr == addr;
-}
-
 static int compare_group_addr(const void *a, const void *b, void *user_data)
 {
 	const struct mesh_group *grp0 = a;
diff --git a/tools/mesh/mesh-db.c b/tools/mesh/mesh-db.c
index da5817acf..1b03e2d90 100644
--- a/tools/mesh/mesh-db.c
+++ b/tools/mesh/mesh-db.c
@@ -814,6 +814,178 @@ bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor,
 						(int) app_idx, "bind", false);
 }
 
+static void jarray_string_del(json_object *jarray, const char *str, size_t len)
+{
+	int i, sz = json_object_array_length(jarray);
+
+	for (i = 0; i < sz; ++i) {
+		json_object *jentry;
+		char *str_entry;
+
+		jentry = json_object_array_get_idx(jarray, i);
+		str_entry = (char *)json_object_get_string(jentry);
+
+		if (str_entry && (strlen(str_entry) == len) &&
+						!strncmp(str, str_entry, len)) {
+			json_object_array_del_idx(jarray, i, 1);
+			return;
+		}
+	}
+}
+
+static bool update_model_string_array(uint16_t unicast, uint16_t ele_addr,
+						bool vendor, uint32_t mod_id,
+						const char *str, uint32_t len,
+						const char *keyword, bool add)
+{
+	json_object *jarray, *jmod, *jstring;
+
+	if (!cfg || !cfg->jcfg)
+		return false;
+
+	jmod = get_model(unicast, ele_addr, mod_id, vendor);
+	if (!jmod)
+		return false;
+
+	if (!json_object_object_get_ex(jmod, keyword, &jarray))
+		return false;
+
+	if (!jarray || json_object_get_type(jarray) != json_type_array)
+		return false;
+
+	jarray_string_del(jarray, str, len);
+
+	if (!add)
+		return true;
+
+	jstring = json_object_new_string(str);
+	if (!jstring)
+		return false;
+
+	json_object_array_add(jarray, jstring);
+
+	return save_config();
+}
+
+bool mesh_db_node_model_add_sub(uint16_t unicast, uint16_t ele, bool vendor,
+						uint32_t mod_id, uint16_t addr)
+{
+	char buf[5];
+
+	snprintf(buf, 5, "%4.4x", addr);
+
+	return update_model_string_array(unicast, ele, vendor, mod_id, buf, 4,
+							"subscribe", true);
+}
+
+bool mesh_db_node_model_del_sub(uint16_t unicast, uint16_t ele, bool vendor,
+						uint32_t mod_id, uint16_t addr)
+{
+	char buf[5];
+
+	snprintf(buf, 5, "%4.4x", addr);
+
+	return update_model_string_array(unicast, ele, vendor, mod_id, buf, 4,
+							"subscribe", false);
+}
+
+bool mesh_db_node_model_add_sub_virt(uint16_t unicast, uint16_t ele,
+						bool vendor, uint32_t mod_id,
+								uint8_t *label)
+{
+	char buf[33];
+
+	hex2str(label, 16, buf, sizeof(buf));
+
+	return update_model_string_array(unicast, ele, vendor, mod_id, buf, 32,
+							"subscribe", true);
+
+}
+
+bool mesh_db_node_model_del_sub_virt(uint16_t unicast, uint16_t ele,
+						bool vendor, uint32_t mod_id,
+								uint8_t *label)
+{
+	char buf[33];
+
+	hex2str(label, 16, buf, sizeof(buf));
+
+	return update_model_string_array(unicast, ele, vendor, mod_id, buf, 32,
+							"subscribe", false);
+}
+
+static json_object *delete_subs(uint16_t unicast, uint16_t ele, bool vendor,
+								uint32_t mod_id)
+{
+	json_object *jarray, *jmod;
+
+	if (!cfg || !cfg->jcfg)
+		return NULL;
+
+	jmod = get_model(unicast, ele, mod_id, vendor);
+	if (!jmod)
+		return NULL;
+
+	json_object_object_del(jmod, "subscribe");
+
+	jarray = json_object_new_array();
+	if (!jarray)
+		return NULL;
+
+	json_object_object_add(jmod, "subscribe", jarray);
+
+	return jarray;
+}
+
+bool mesh_db_node_model_del_sub_all(uint16_t unicast, uint16_t ele, bool vendor,
+								uint32_t mod_id)
+{
+
+	if (!delete_subs(unicast, ele, vendor, mod_id))
+		return false;
+
+	return save_config();
+}
+
+static bool sub_overwrite(uint16_t unicast, uint16_t ele, bool vendor,
+						uint32_t mod_id, char *buf)
+{
+	json_object *jarray, *jstring;
+
+	jarray = delete_subs(unicast, ele, vendor, mod_id);
+	if (!jarray)
+		return false;
+
+	jstring = json_object_new_string(buf);
+	if (!jstring)
+		return false;
+
+	json_object_array_add(jarray, jstring);
+
+	return save_config();
+}
+
+bool mesh_db_node_model_overwrt_sub(uint16_t unicast, uint16_t ele, bool vendor,
+						uint32_t mod_id, uint16_t addr)
+{
+	char buf[5];
+
+	snprintf(buf, 5, "%4.4x", addr);
+
+	return sub_overwrite(unicast, ele, vendor, mod_id, buf);
+}
+
+bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele,
+						bool vendor, uint32_t mod_id,
+								uint8_t *label)
+{
+	char buf[33];
+
+	hex2str(label, 16, buf, sizeof(buf));
+
+	return sub_overwrite(unicast, ele, vendor, mod_id, buf);
+}
+
 static void jarray_key_del(json_object *jarray, int16_t idx)
 {
 	int i, sz = json_object_array_length(jarray);
@@ -1340,6 +1512,9 @@ static json_object *init_model(uint16_t mod_id)
 	jarray = json_object_new_array();
 	json_object_object_add(jmod, "bind", jarray);
 
+	jarray = json_object_new_array();
+	json_object_object_add(jmod, "subscribe", jarray);
+
 	return jmod;
 }
 
@@ -1357,6 +1532,9 @@ static json_object *init_vendor_model(uint32_t mod_id)
 	jarray = json_object_new_array();
 	json_object_object_add(jmod, "bind", jarray);
 
+	jarray = json_object_new_array();
+	json_object_object_add(jmod, "subscribe", jarray);
+
 	return jmod;
 }
 
diff --git a/tools/mesh/mesh-db.h b/tools/mesh/mesh-db.h
index c3ee81457..384376cbd 100644
--- a/tools/mesh/mesh-db.h
+++ b/tools/mesh/mesh-db.h
@@ -48,6 +48,23 @@ bool mesh_db_node_model_bind(uint16_t unicast, uint16_t ele_addr, bool vendor,
 					uint32_t mod_id, uint16_t app_idx);
 bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor,
 					uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_node_model_add_sub(uint16_t unicast, uint16_t ele, bool vendor,
+						uint32_t mod_id, uint16_t addr);
+bool mesh_db_node_model_del_sub(uint16_t unicast, uint16_t ele, bool vendor,
+						uint32_t mod_id, uint16_t addr);
+bool mesh_db_node_model_overwrt_sub(uint16_t unicast, uint16_t ele, bool vendor,
+						uint32_t mod_id, uint16_t addr);
+bool mesh_db_node_model_add_sub_virt(uint16_t unicast, uint16_t ele,
+						bool vendor, uint32_t mod_id,
+								uint8_t *label);
+bool mesh_db_node_model_del_sub_virt(uint16_t unicast, uint16_t ele,
+						bool vendor, uint32_t mod_id,
+								uint8_t *label);
+bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele,
+						bool vendor, uint32_t mod_id,
+								uint8_t *label);
+bool mesh_db_node_model_del_sub_all(uint16_t unicast, uint16_t ele, bool vendor,
+							uint32_t mod_id);
 struct l_queue *mesh_db_load_groups(void);
 bool mesh_db_add_group(struct mesh_group *grp);
 bool mesh_db_add_rejected_addr(uint16_t unicast, uint32_t iv_index);
-- 
2.31.1


  parent reply	other threads:[~2021-09-23  3:27 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-23  3:25 [PATCH BlueZ 00/20] Mesh Configuration Database Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 01/20] tools/mesh-cfgclient: Save provisioner info Inga Stotland
2021-09-23  4:00   ` Mesh Configuration Database bluez.test.bot
2021-09-23  4:14     ` Tedd Ho-Jeong An
2021-09-23 16:52   ` bluez.test.bot
2021-09-23  3:25 ` [PATCH BlueZ 02/20] tools/mesh-cfgclient: Add timestamp to config database Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 03/20] tools/mesh-cfgclient: Update stored NetKey and AppKey Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 04/20] tools/mesh-cfgclient: Keep track of updated keys Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 05/20] tools/mesh: Add new info to stored remote nodes Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 06/20] tools/mesh-cfgclient: Overwrite config values when adding new ones Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 07/20] tools/mesh-cfgclient: Store remote node's model bindings Inga Stotland
2021-09-23  3:25 ` Inga Stotland [this message]
2021-09-23  3:25 ` [PATCH BlueZ 09/20] tools/mesh-cfgclient: Disallow model commands w/o composition Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 10/20] tools/mesh-cfgclient: Store remote's model publication info Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 11/20] tools/mesh-cfgclient: Check the result of config save Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 12/20] tools/mesh-cfgclient: Rename mesh-db APIs for consistency Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 13/20] tools/mesh-cfgclient: Save remote node feature setting Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 14/20] tools/mesh-cfgclient: Store remote's heartbeat sub/pub Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 15/20] tools/mesh-cfgclient: Add group parent address for DB compliance Inga Stotland
2021-09-23  3:25 ` [PATCH BlueZ 16/20] doc/mesh-api: Add ExportKeys call Inga Stotland
2021-09-23  3:26 ` [PATCH BlueZ 17/20] mesh: Implement ExportKeys() method Inga Stotland
2021-09-23  3:26 ` [PATCH BlueZ 18/20] tools/mesh-cfgclient: Store UUIDs in standard format Inga Stotland
2021-09-23  3:26 ` [PATCH BlueZ 19/20] tools/mesh-cfgclient: Excluded addresses property Inga Stotland
2021-09-23  3:26 ` [PATCH BlueZ 20/20] tools/mesh-cfgclient: Export configuration database Inga Stotland
2021-09-27 20:27 ` [PATCH BlueZ 00/20] Mesh Configuration Database Gix, Brian

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=20210923032603.50536-9-inga.stotland@intel.com \
    --to=inga.stotland@intel.com \
    --cc=brian.gix@intel.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /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 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.