[PATCH BlueZ 4/4] mesh: Unify processing of GetManagedObjects result

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This combines processing of results obtained from GetManagedObjects
request for both Attach() and Join() methods
---
 mesh/mesh-defs.h |   2 +
 mesh/node.c      | 362 +++++++++++++++++++++++------------------------
 2 files changed, 182 insertions(+), 182 deletions(-)

diff --git a/mesh/mesh-defs.h b/mesh/mesh-defs.h
index c30041e4a..131b3502c 100644
--- a/mesh/mesh-defs.h
+++ b/mesh/mesh-defs.h
@@ -75,6 +75,8 @@
 #define VENDOR_ID_MASK		0xffff0000
 
 #define MAX_KEY_IDX		0x0fff
+#define MAX_MODEL_COUNT		0xff
+#define MAX_ELE_COUNT		0xff
 
 #define IS_UNASSIGNED(x)	((x) == UNASSIGNED_ADDRESS)
 #define IS_UNICAST(x)		(((x) > UNASSIGNED_ADDRESS) && \
diff --git a/mesh/node.c b/mesh/node.c
index 0c2fc7262..774d03d45 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -54,6 +54,9 @@
 #define DEFAULT_CRPL 10
 #define DEFAULT_SEQUENCE_NUMBER 0
 
+#define REQUEST_TYPE_JOIN 0
+#define REQUEST_TYPE_ATTACH 1
+
 struct node_element {
 	char *path;
 	struct l_queue *models;
@@ -100,15 +103,11 @@ struct mesh_node {
 	uint8_t beacon;
 };
 
-struct attach_obj_request {
-	node_ready_func_t cb;
-	struct mesh_node *node;
+struct managed_obj_request {
+	void *data;
+	void *cb;
 	void *user_data;
-};
-
-struct join_obj_request {
-	node_join_ready_func_t cb;
-	const uint8_t *uuid;
+	uint8_t type;
 };
 
 static struct l_queue *nodes;
@@ -1003,6 +1002,7 @@ void node_attach_io(struct mesh_io *io)
 	l_queue_foreach(nodes, attach_io, io);
 }
 
+/* Register node object with D-Bus */
 static bool register_node_object(struct mesh_node *node)
 {
 	node->path = l_malloc(strlen(MESH_NODE_PATH_PREFIX) + 5);
@@ -1078,7 +1078,6 @@ static bool validate_model_property(struct node_element *ele,
 		while (l_dbus_message_iter_next_entry(&ids, &vendor_id,
 								&mod_id)) {
 			struct mesh_model *mod;
-
 			mod = l_queue_find(ele->models, match_model_id,
 				L_UINT_TO_PTR((vendor_id << 16) | mod_id));
 			if (!mod)
@@ -1132,7 +1131,7 @@ static void get_models_from_properties(struct node_element *ele,
 
 static bool get_element_properties(struct mesh_node *node, const char *path,
 					struct l_dbus_message_iter *properties,
-								bool create_new)
+								bool is_new)
 {
 	struct node_element *ele;
 	const char *key;
@@ -1156,7 +1155,7 @@ static bool get_element_properties(struct mesh_node *node, const char *path,
 		return false;
 	}
 
-	if (!create_new) {
+	if (!is_new) {
 		/* Validate composition: check the element index */
 		ele = l_queue_find(node->elements, match_element_idx,
 							L_UINT_TO_PTR(idx));
@@ -1180,14 +1179,14 @@ static bool get_element_properties(struct mesh_node *node, const char *path,
 			l_dbus_message_iter_get_variant(&var, "q", &loc);
 
 			/* Validate composition: location match */
-			if (!create_new && (ele->location != loc))
+			if (!is_new && (ele->location != loc))
 				return false;
 
 			ele->location = loc;
 
 		} else if (!strcmp(key, "Models")) {
 
-			if (create_new)
+			if (is_new)
 				get_models_from_properties(ele, &var, false);
 			else if (!validate_model_property(ele, &var, &mod_cnt,
 									false))
@@ -1195,15 +1194,16 @@ static bool get_element_properties(struct mesh_node *node, const char *path,
 
 		} else if (!strcmp(key, "VendorModels")) {
 
-			if (create_new)
+			if (is_new)
 				get_models_from_properties(ele, &var, true);
 			else if (!validate_model_property(ele, &var,
 							&vendor_cnt, true))
 				return false;
+
 		}
 	}
 
-	if (create_new) {
+	if (is_new) {
 		l_queue_push_tail(node->elements, ele);
 	} else {
 		/* Account for internal Configuration Server model */
@@ -1220,139 +1220,6 @@ static bool get_element_properties(struct mesh_node *node, const char *path,
 	return true;
 }
 
-static void get_managed_objects_attach_cb(struct l_dbus_message *msg,
-								void *user_data)
-{
-	struct l_dbus_message_iter objects, interfaces;
-	struct attach_obj_request *req = user_data;
-	struct mesh_node *node = req->node;
-	const char *path;
-	uint8_t num_ele;
-
-	if (l_dbus_message_is_error(msg)) {
-		l_error("Failed to get app's dbus objects");
-		goto fail;
-	}
-
-	if (!l_dbus_message_get_arguments(msg, "a{oa{sa{sv}}}", &objects)) {
-		l_error("Failed to parse app's dbus objects");
-		goto fail;
-	}
-
-	num_ele = 0;
-
-	while (l_dbus_message_iter_next_entry(&objects, &path, &interfaces)) {
-		struct l_dbus_message_iter properties;
-		const char *interface;
-
-		while (l_dbus_message_iter_next_entry(&interfaces, &interface,
-								&properties)) {
-			if (strcmp(MESH_ELEMENT_INTERFACE, interface))
-				continue;
-
-			if (!get_element_properties(node, path, &properties,
-									false))
-				goto fail;
-
-			num_ele++;
-		}
-	}
-
-	/*
-	 * Check that the number of element objects matches the expected number
-	 * of elements on the node
-	 */
-	if (num_ele != node->num_ele)
-		goto fail;
-
-	/* Register node object with D-Bus */
-	register_node_object(node);
-
-	if (node->path) {
-		struct l_dbus *bus = dbus_get_bus();
-
-		node->disc_watch = l_dbus_add_disconnect_watch(bus, node->owner,
-						app_disc_cb, node, NULL);
-		req->cb(req->user_data, MESH_ERROR_NONE, node);
-
-		return;
-	}
-fail:
-	req->cb(req->user_data, MESH_ERROR_FAILED, NULL);
-
-	l_queue_foreach(node->elements, free_element_path, NULL);
-	l_free(node->app_path);
-	node->app_path = NULL;
-
-	l_free(node->owner);
-	node->owner = NULL;
-}
-
-/* Establish relationship between application and mesh node */
-int node_attach(const char *app_path, const char *sender, uint64_t token,
-				node_ready_func_t cb, void *user_data)
-{
-	struct attach_obj_request *req;
-	struct mesh_node *node;
-
-	node = l_queue_find(nodes, match_token, (void *) &token);
-	if (!node)
-		return MESH_ERROR_NOT_FOUND;
-
-	/* Check if the node is already in use */
-	if (node->owner) {
-		l_warn("The node is already in use");
-		return MESH_ERROR_ALREADY_EXISTS;
-	}
-
-	node->app_path = l_strdup(app_path);
-	node->owner = l_strdup(sender);
-
-	req = l_new(struct attach_obj_request, 1);
-	req->node = node;
-	req->cb = cb;
-	req->user_data = user_data;
-
-	l_dbus_method_call(dbus_get_bus(), sender, app_path,
-					L_DBUS_INTERFACE_OBJECT_MANAGER,
-					"GetManagedObjects", NULL,
-					get_managed_objects_attach_cb,
-					req, l_free);
-	return MESH_ERROR_NONE;
-
-}
-
-static bool get_app_properties(struct mesh_node *node, const char *path,
-					struct l_dbus_message_iter *properties)
-{
-	const char *key;
-	struct l_dbus_message_iter variant;
-
-	l_debug("path %s", path);
-
-	if (!node->comp)
-		node->comp = l_new(struct node_composition, 1);
-
-	while (l_dbus_message_iter_next_entry(properties, &key, &variant)) {
-
-		if (!strcmp(key, "CompanyID")) {
-			if (!l_dbus_message_iter_get_variant(&variant, "q",
-							&node->comp->cid))
-				return false;
-		} else if (!strcmp(key, "ProductID")) {
-			if (!l_dbus_message_iter_get_variant(&variant, "q",
-							&node->comp->pid))
-				return false;
-		} else if (!strcmp(key, "VersionID")) {
-			if (!l_dbus_message_iter_get_variant(&variant, "q",
-							&node->comp->vid))
-				return false;
-		}
-	}
-
-	return true;
-}
-
 static void convert_node_to_storage(struct mesh_node *node,
 						struct mesh_db_node *db_node)
 {
@@ -1451,14 +1318,66 @@ static void set_defaults(struct mesh_node *node)
 	add_internal_model(node, CONFIG_SRV_MODEL, PRIMARY_ELE_IDX);
 }
 
-static void get_managed_objects_join_cb(struct l_dbus_message *msg,
-								void *user_data)
+static bool get_app_properties(struct mesh_node *node, const char *path,
+					struct l_dbus_message_iter *properties,
+								bool is_new)
+{
+	const char *key;
+	struct l_dbus_message_iter variant;
+	uint16_t value;
+
+	l_debug("path %s", path);
+
+	if (is_new)
+		node->comp = l_new(struct node_composition, 1);
+
+	while (l_dbus_message_iter_next_entry(properties, &key, &variant)) {
+
+		if (!strcmp(key, "CompanyID")) {
+			if (!l_dbus_message_iter_get_variant(&variant, "q",
+									&value))
+				return false;
+
+			if (!is_new && node->comp->cid != value)
+				return false;
+
+			node->comp->cid = value;
+
+		} else if (!strcmp(key, "ProductID")) {
+			if (!l_dbus_message_iter_get_variant(&variant, "q",
+									&value))
+				return false;
+
+			if (!is_new && node->comp->pid != value)
+				return false;
+
+			node->comp->pid = value;
+
+		} else if (!strcmp(key, "VersionID")) {
+			if (!l_dbus_message_iter_get_variant(&variant, "q",
+									&value))
+				return false;
+
+			if (!is_new && node->comp->vid != value)
+				return false;
+
+			node->comp->vid = value;
+		}
+	}
+
+	return true;
+}
+
+static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data)
 {
 	struct l_dbus_message_iter objects, interfaces;
-	struct join_obj_request *req = user_data;
+	struct managed_obj_request *req = user_data;
 	const char *path;
 	struct mesh_node *node = NULL;
 	void *agent = NULL;
+	bool have_app = false;
+	bool is_new;
+	uint8_t num_ele;
 
 	if (l_dbus_message_is_error(msg)) {
 		l_error("Failed to get app's dbus objects");
@@ -1470,8 +1389,16 @@ static void get_managed_objects_join_cb(struct l_dbus_message *msg,
 		goto fail;
 	}
 
-	node = l_new(struct mesh_node, 1);
-	node->elements = l_queue_new();
+	is_new = (req->type != REQUEST_TYPE_ATTACH);
+
+	if (is_new) {
+		node = l_new(struct mesh_node, 1);
+		node->elements = l_queue_new();
+	} else {
+		node = req->data;
+	}
+
+	num_ele = 0;
 
 	while (l_dbus_message_iter_next_entry(&objects, &path, &interfaces)) {
 		struct l_dbus_message_iter properties;
@@ -1482,26 +1409,27 @@ static void get_managed_objects_join_cb(struct l_dbus_message *msg,
 			bool res;
 
 			if (!strcmp(MESH_ELEMENT_INTERFACE, interface)) {
+
+				if (num_ele == MAX_ELE_COUNT)
+					goto fail;
+
 				res = get_element_properties(node, path,
-							&properties, true);
+							&properties, is_new);
 				if (!res)
 					goto fail;
 
-				node->num_ele++;
-				continue;
-
-			}
+				num_ele++;
 
-			if (!strcmp(MESH_APPLICATION_INTERFACE, interface)) {
+			} else if (!strcmp(MESH_APPLICATION_INTERFACE,
+								interface)) {
 				res = get_app_properties(node, path,
-								&properties);
+							&properties, is_new);
 				if (!res)
 					goto fail;
 
-				continue;
-			}
+				have_app = true;
 
-			if (!strcmp(MESH_PROVISION_AGENT_INTERFACE,
+			} else if (!strcmp(MESH_PROVISION_AGENT_INTERFACE,
 								interface)) {
 				const char *sender;
 
@@ -1514,18 +1442,12 @@ static void get_managed_objects_join_cb(struct l_dbus_message *msg,
 		}
 	}
 
-	if (!node->comp){
+	if (!have_app) {
 		l_error("Interface %s not found", MESH_APPLICATION_INTERFACE);
 		goto fail;
 	}
 
-	if (!agent) {
-		l_error("Interface %s not found",
-						MESH_PROVISION_AGENT_INTERFACE);
-		goto fail;
-	}
-
-	if (!node->num_ele) {
+	if (num_ele == 0) {
 		l_error("Interface %s not found", MESH_ELEMENT_INTERFACE);
 		goto fail;
 	}
@@ -1537,41 +1459,117 @@ static void get_managed_objects_join_cb(struct l_dbus_message *msg,
 		goto fail;
 	}
 
-	set_defaults(node);
-	memcpy(node->dev_uuid, req->uuid, 16);
+	if (req->type == REQUEST_TYPE_JOIN) {
+		node_join_ready_func_t cb = req->cb;
 
-	if (!create_node_config(node))
-		goto fail;
+		if (!agent) {
+			l_error("Interface %s not found",
+						MESH_PROVISION_AGENT_INTERFACE);
+			goto fail;
+		}
+		node->num_ele = num_ele;
+		set_defaults(node);
+		memcpy(node->dev_uuid, req->data, 16);
+
+		if (!create_node_config(node))
+			goto fail;
+
+		cb(node, agent);
+	} else {
+		node_ready_func_t cb = req->cb;
+
+		if (num_ele != node->num_ele)
+			goto fail;
+
+		if (register_node_object(node)) {
+			struct l_dbus *bus = dbus_get_bus();
 
-	req->cb(node, agent);
+			node->disc_watch = l_dbus_add_disconnect_watch(bus,
+					node->owner, app_disc_cb, node, NULL);
+			cb(req->user_data, MESH_ERROR_NONE, node);
+		} else
+			goto fail;
+	}
 
 	return;
 fail:
 	if (agent)
 		mesh_agent_remove(agent);
 
-	if (node)
+	if (is_new && node)
 		free_node_resources(node);
 
-	req->cb(NULL, NULL);
+	if (req->type == REQUEST_TYPE_JOIN) {
+		node_join_ready_func_t cb = req->cb;
+
+		cb(NULL, NULL);
+
+	} else {
+		node_ready_func_t cb = req->cb;
+
+		l_queue_foreach(node->elements, free_element_path, NULL);
+		l_free(node->app_path);
+		node->app_path = NULL;
+
+		l_free(node->owner);
+		node->owner = NULL;
+		cb(req->user_data, MESH_ERROR_FAILED, node);
+	}
+}
+
+/* Establish relationship between application and mesh node */
+int node_attach(const char *app_path, const char *sender, uint64_t token,
+					node_ready_func_t cb, void *user_data)
+{
+	struct managed_obj_request *req;
+	struct mesh_node *node;
+
+	node = l_queue_find(nodes, match_token, (void *) &token);
+	if (!node)
+		return MESH_ERROR_NOT_FOUND;
+
+	/* Check if the node is already in use */
+	if (node->owner) {
+		l_warn("The node is already in use");
+		return MESH_ERROR_ALREADY_EXISTS;
+	}
+
+	node->app_path = l_strdup(app_path);
+	node->owner = l_strdup(sender);
+
+	req = l_new(struct managed_obj_request, 1);
+	req->data = node;
+	req->cb = cb;
+	req->user_data = user_data;
+	req->type = REQUEST_TYPE_ATTACH;
+
+	l_dbus_method_call(dbus_get_bus(), sender, app_path,
+					L_DBUS_INTERFACE_OBJECT_MANAGER,
+					"GetManagedObjects", NULL,
+					get_managed_objects_cb,
+					req, l_free);
+	return MESH_ERROR_NONE;
+
 }
 
+
 /* Create a temporary pre-provisioned node */
 void node_join(const char *app_path, const char *sender, const uint8_t *uuid,
 						node_join_ready_func_t cb)
 {
-	struct join_obj_request *req;
+	struct managed_obj_request *req;
 
 	l_debug("");
 
-	req = l_new(struct join_obj_request, 1);
-	req->uuid = uuid;
+	req = l_new(struct managed_obj_request, 1);
+	req->data = (void *) uuid;
 	req->cb = cb;
+	req->type = REQUEST_TYPE_JOIN;
 
 	l_dbus_method_call(dbus_get_bus(), sender, app_path,
 					L_DBUS_INTERFACE_OBJECT_MANAGER,
 					"GetManagedObjects", NULL,
-					get_managed_objects_join_cb,
+					get_managed_objects_cb,
 					req, l_free);
 }
 
-- 
2.17.2




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux