diff mbox series

[BlueZ,v5,14/14] tools/mesh-cfgtest: Support extended device composition

Message ID 20230130235210.94385-15-brian.gix@gmail.com (mailing list archive)
State Accepted
Commit 8787aed7fe0089c079884784131e630ddacc6d26
Headers show
Series Mesh v1.1 additions | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Brian Gix Jan. 30, 2023, 11:52 p.m. UTC
From: Inga Stotland <inga.stotland@intel.com>

This adds support for extended device composition to account for
new fundamental models supported by bluetooth-meshd daemon.
Also, update to include explicit element locations and handle
different ordering of model IDs in the composition data.
---
 tools/mesh-cfgtest.c | 188 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 168 insertions(+), 20 deletions(-)
diff mbox series

Patch

diff --git a/tools/mesh-cfgtest.c b/tools/mesh-cfgtest.c
index 116ab7f16..739d1d972 100644
--- a/tools/mesh-cfgtest.c
+++ b/tools/mesh-cfgtest.c
@@ -38,14 +38,21 @@ 
 #define MAX_CRPL_SIZE	0x7fff
 #define CFG_SRV_MODEL	0x0000
 #define CFG_CLI_MODEL	0x0001
+#define RMT_PROV_SRV_MODEL 0x0004
+#define RMT_PROV_CLI_MODEL 0x0005
+#define PVT_BEACON_SRV_MODEL 0x0008
 #define DEFAULT_IV_INDEX 0x0000
 
-#define IS_CONFIG_MODEL(x) ((x) == CFG_SRV_MODEL || (x) == CFG_CLI_MODEL)
+#define IS_CONFIG_MODEL(x) (((x) == (CFG_SRV_MODEL)) ||		\
+				((x) == (CFG_CLI_MODEL)) ||		\
+				((x) == (RMT_PROV_SRV_MODEL)) ||	\
+				((x) == (RMT_PROV_CLI_MODEL)))
 
 struct meshcfg_el {
 	const char *path;
 	uint8_t index;
-	uint16_t mods[2];
+	uint16_t location;
+	uint16_t mods[4];
 	uint32_t vmods[2];
 };
 
@@ -77,6 +84,11 @@  struct msg_data {
 	uint8_t data[MAX_MSG_LEN];
 };
 
+struct exp_rsp {
+	uint8_t test_id;
+	void *rsp;
+};
+
 struct key_data {
 	uint16_t idx;
 	bool update;
@@ -140,7 +152,9 @@  static struct meshcfg_app client_app = {
 		{
 			.path = cli_ele_path_00,
 			.index = PRIMARY_ELE_IDX,
-			.mods = {CFG_SRV_MODEL, CFG_CLI_MODEL},
+			.location = 0x0001,
+			.mods = {CFG_SRV_MODEL, CFG_CLI_MODEL,
+				 RMT_PROV_SRV_MODEL, PVT_BEACON_SRV_MODEL},
 			.vmods = {0xffffffff, 0xffffffff}
 		}
 	}
@@ -158,13 +172,16 @@  static struct meshcfg_app server_app = {
 		{
 			.path = srv_ele_path_00,
 			.index = PRIMARY_ELE_IDX,
-			.mods = {CFG_SRV_MODEL, 0xffff},
+			.location = 0x0001,
+			.mods = {CFG_SRV_MODEL, RMT_PROV_SRV_MODEL,
+						PVT_BEACON_SRV_MODEL, 0xffff},
 			.vmods = {0xffffffff, 0xffffffff}
 		},
 		{
 			.path = srv_ele_path_01,
 			.index = PRIMARY_ELE_IDX + 1,
-			.mods = {0x1000, 0xffff},
+			.location = 0x0002,
+			.mods = {0x1000, 0xffff, 0xffff, 0xffff},
 			.vmods = {0x5F10001, 0xffffffff}
 		}
 	}
@@ -262,6 +279,11 @@  static struct msg_data test_add_appkey_rsp = {
 	.data = {0x80, 0x03, 0x00, 0x01, 0x20, 0x00}
 };
 
+static struct exp_rsp test_add_appkey_expected = {
+	.test_id = 1,
+	.rsp = &test_add_appkey_rsp,
+};
+
 static struct key_data test_add_appkey_req = {
 	.idx = 0x002,
 	.update = false
@@ -285,6 +307,11 @@  static struct msg_data test_set_ttl_rsp = {
 	.data = { 0x80, 0x0E, 0x7}
 };
 
+static struct exp_rsp test_set_ttl_expected = {
+	.test_id = 2,
+	.rsp = &test_set_ttl_rsp
+};
+
 static struct msg_data test_set_ttl_req = {
 	.len = 3,
 	.data = { 0x80, 0x0D, 0x7}
@@ -295,27 +322,42 @@  static struct msg_data test_bind_rsp = {
 	.data = { 0x80, 0x3E, 0x00, 0xCE, 0x0B, 0x01, 0x00, 0x00, 0x10},
 };
 
+static struct exp_rsp test_bind_expected = {
+	.test_id = 3,
+	.rsp = &test_bind_rsp
+};
+
 static struct msg_data test_bind_req = {
 	.len = 8,
 	.data = { 0x80, 0x3D, 0xCE, 0x0B, 0x01, 0x00, 0x00, 0x10}
 };
 
-
 static struct msg_data test_bind_inv_mod_rsp = {
 	.len = 9,
 	.data = { 0x80, 0x3E, 0x02, 0xCE, 0x0B, 0x01, 0x00, 0x00, 0x11},
 };
 
+static struct exp_rsp test_bind_inv_mod_expected = {
+	.test_id = 4,
+	.rsp = &test_bind_inv_mod_rsp
+};
+
 static struct msg_data test_bind_inv_mod_req = {
 	.len = 8,
 	.data = { 0x80, 0x3D, 0xCE, 0x0B, 0x01, 0x00, 0x00, 0x11}
 };
 
 static struct msg_data test_dev_comp_rsp = {
-	.len = 28,
-	.data = { 0x02, 0x00, 0xf1, 0x05, 0x02, 0x00, 0x01, 0x00, 0xff, 0x7f,
-			0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x01, 0x01, 0x00, 0x10, 0xf1, 0x05, 0x01, 0x00}
+	.len = 32,
+	.data = { 0x02, 0x00, 0xf1, 0x05, 0x02, 0x00, 0x01, 0x00,
+		0xff, 0x7f, 0x05, 0x00,
+		0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
+		0x02, 0x00, 0x01, 0x01, 0x00, 0x10, 0xf1, 0x05, 0x01, 0x00}
+};
+
+static struct exp_rsp test_dev_comp_expected = {
+	.test_id = 5,
+	.rsp = &test_dev_comp_rsp
 };
 
 static struct msg_data test_dev_comp_req = {
@@ -955,11 +997,101 @@  static bool ele_idx_getter(struct l_dbus *dbus,
 	return true;
 }
 
+static bool location_getter(struct l_dbus *dbus,
+				struct l_dbus_message *message,
+				struct l_dbus_message_builder *builder,
+				void *user_data)
+{
+	struct meshcfg_el *ele = user_data;
+
+	l_dbus_message_builder_append_basic(builder, 'q', &ele->location);
+
+	return true;
+}
+
+static bool find_model(uint8_t *buf, uint32_t len, uint8_t *mod, uint8_t sz)
+{
+	bool found = false;
+
+	while (len >= sz) {
+		if (!memcmp(buf, mod, sz)) {
+			/* Disallow duplicates */
+			if (found)
+				return false;
+
+			found = true;
+		}
+
+		buf += sz;
+		len -= sz;
+	}
+
+	return found;
+}
+
+static bool check_device_composition(struct msg_data *rsp, uint32_t len,
+								uint8_t *data)
+{
+	uint32_t cnt;
+
+	if (len != rsp->len)
+		return false;
+
+	if (!memcmp(data, rsp->data, len))
+		return true;
+
+	/* Allow for a different ordering of model IDs */
+
+	/* First, check that the fixed length data matches */
+	if (memcmp(data, rsp->data, 12))
+		return false;
+
+	cnt = 12;
+	data += 12;
+
+	while (cnt < len) {
+		uint8_t s, v, i;
+
+		if ((len - cnt) < 4)
+			return false;
+
+		/* Check element index, location and model count */
+		if (memcmp(data, rsp->data + cnt, 4))
+			return false;
+
+		s = data[2];
+		v = data[3];
+
+		if ((cnt + s * 2 + v * 4) > len)
+			return false;
+
+		data += 4;
+		cnt += 4;
+
+		for (i = 0; i < s; i++) {
+			if (!find_model(&rsp->data[cnt], s * 2, data, 2))
+				return false;
+			data += 2;
+		}
+
+		cnt += s * 2;
+
+		for (i = 0; i < v; i++) {
+			if (!find_model(&rsp->data[cnt], v * 4, data, 4))
+				return false;
+			data += 4;
+		}
+
+		cnt += v * 4;
+	}
+
+	return true;
+}
+
 static struct l_dbus_message *dev_msg_recv_call(struct l_dbus *dbus,
 						struct l_dbus_message *msg,
 						void *user_data)
 {
-	struct msg_data *rsp;
 	struct l_dbus_message_iter iter;
 	uint16_t src, idx;
 	uint8_t *data;
@@ -983,7 +1115,7 @@  static struct l_dbus_message *dev_msg_recv_call(struct l_dbus *dbus,
 		uint32_t i;
 
 		for (i = 0; i < n; i++)
-			printf("%x ", data[i]);
+			printf("%02x ", data[i]);
 		printf("\n");
 	}
 
@@ -999,9 +1131,24 @@  static struct l_dbus_message *dev_msg_recv_call(struct l_dbus *dbus,
 			l_tester_pre_setup_failed(tester);
 		}
 	} else {
-		rsp = l_tester_get_data(tester);
+		struct exp_rsp *exp = l_tester_get_data(tester);
+		bool res = false;
+
+		if (exp && exp->rsp) {
+			if (exp->test_id == 5)
+				/* Check device composition */
+				res = check_device_composition(exp->rsp, n,
+									data);
+			else {
+				struct msg_data *rsp = exp->rsp;
+
+				if (n == rsp->len &&
+						!memcmp(data, rsp->data, n))
+					res = true;
+			}
+		}
 
-		if (rsp && rsp->len == n && !memcmp(data, rsp->data, n))
+		if (res)
 			l_idle_oneshot(test_success, NULL, NULL);
 		else
 			l_idle_oneshot(test_fail, NULL, NULL);
@@ -1019,7 +1166,8 @@  static void setup_ele_iface(struct l_dbus_interface *iface)
 							vmod_getter, NULL);
 	l_dbus_interface_property(iface, "Models", 0, "a(qa{sv})", mod_getter,
 									NULL);
-
+	l_dbus_interface_property(iface, "Location", 0, "q", location_getter,
+									NULL);
 	/* Methods */
 	l_dbus_interface_method(iface, "DevKeyMessageReceived", 0,
 				dev_msg_recv_call, "", "qbqay", "source",
@@ -1411,23 +1559,23 @@  int main(int argc, char *argv[])
 
 	l_tester_add_full(tester, "Config AppKey Add: Success",
 			&test_add_appkey, init_test, create_appkey, add_appkey,
-				NULL, NULL, 2, &test_add_appkey_rsp, NULL);
+				NULL, NULL, 2, &test_add_appkey_expected, NULL);
 
 	tester_add_with_response("Config Default TTL Set: Success",
 					&test_set_ttl_req, send_cfg_msg,
-							&test_set_ttl_rsp);
+						&test_set_ttl_expected);
 
 	tester_add_with_response("Config Get Device Composition: Success",
 					&test_dev_comp_req, send_cfg_msg,
-							&test_dev_comp_rsp);
+						&test_dev_comp_expected);
 
 	tester_add_with_response("Config Bind: Success",
 					&test_bind_req, send_cfg_msg,
-							&test_bind_rsp);
+						&test_bind_expected);
 
 	tester_add_with_response("Config Bind: Error Invalid Model",
 					&test_bind_inv_mod_req, send_cfg_msg,
-							&test_bind_inv_mod_rsp);
+						&test_bind_inv_mod_expected);
 
 	l_tester_start(tester, done_callback);