* [PATCH BlueZ 1/4] mesh: Remove Node interface if node owner disconnects
2019-04-29 19:45 [PATCH BlueZ 0/4] Cleanup of org.bluez.mesh.Network1 interface Inga Stotland
@ 2019-04-29 19:45 ` Inga Stotland
2019-04-29 19:45 ` [PATCH BlueZ 2/4] mesh: Clean up processing of Attach() method Inga Stotland
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Inga Stotland @ 2019-04-29 19:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland
This unregisters Node interface associated with a specific node
application when this application disconnects from D-Bus.
---
mesh/node.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/mesh/node.c b/mesh/node.c
index 157991dad..a6c9332bc 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -233,7 +233,7 @@ static void free_node_resources(void *data)
if (node->path)
l_dbus_object_remove_interface(dbus_get_bus(), node->path,
- MESH_NODE_INTERFACE);
+ MESH_NODE_INTERFACE);
l_free(node->path);
l_free(node);
@@ -1020,8 +1020,12 @@ static void app_disc_cb(struct l_dbus *bus, void *user_data)
l_free(node->owner);
node->owner = NULL;
- l_free(node->app_path);
- node->app_path = NULL;
+ if (node->path) {
+ l_dbus_object_remove_interface(dbus_get_bus(), node->path,
+ MESH_NODE_INTERFACE);
+ l_free(node->app_path);
+ node->app_path = NULL;
+ }
}
static bool validate_element_properties(struct mesh_node *node,
--
2.17.2
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH BlueZ 2/4] mesh: Clean up processing of Attach() method
2019-04-29 19:45 [PATCH BlueZ 0/4] Cleanup of org.bluez.mesh.Network1 interface Inga Stotland
2019-04-29 19:45 ` [PATCH BlueZ 1/4] mesh: Remove Node interface if node owner disconnects Inga Stotland
@ 2019-04-29 19:45 ` Inga Stotland
2019-04-29 19:45 ` [PATCH BlueZ 3/4] mesh: Consolidate processing of mesh element properties Inga Stotland
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Inga Stotland @ 2019-04-29 19:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland
This changes the prototype for the callback function of
Attach() method call: remove unused node_path argument and make the
callback more generalized and re-usable for other method calls.
---
mesh/mesh.c | 69 ++++++++++++++++++++---------------------------------
mesh/node.c | 19 +++++++--------
mesh/node.h | 9 +++----
3 files changed, 39 insertions(+), 58 deletions(-)
diff --git a/mesh/mesh.c b/mesh/mesh.c
index e7eef0473..a084f9200 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -76,12 +76,6 @@ struct join_data{
uint8_t *uuid;
};
-struct attach_data {
- uint64_t token;
- struct l_dbus_message *msg;
- const char *app;
-};
-
static struct bt_mesh mesh;
static struct l_queue *controllers;
static struct mgmt *mgmt_mesh;
@@ -90,8 +84,8 @@ static bool initialized;
/* We allow only one outstanding Join request */
static struct join_data *join_pending;
-/* Pending Attach requests */
-static struct l_queue *attach_queue;
+/* Pending method requests */
+static struct l_queue *pending_queue;
static bool simple_match(const void *a, const void *b)
{
@@ -341,14 +335,13 @@ bool mesh_init(uint16_t index, const char *config_dir)
return true;
}
-static void attach_exit(void *data)
+static void pending_request_exit(void *data)
{
struct l_dbus_message *reply;
- struct attach_data *pending = data;
+ struct l_dbus_message *msg = data;
- reply = dbus_error(pending->msg, MESH_ERROR_FAILED, "Failed. Exiting");
+ reply = dbus_error(msg, MESH_ERROR_FAILED, "Failed. Exiting");
l_dbus_send(dbus_get_bus(), reply);
- l_free(pending);
}
static void free_pending_join_call(bool failed)
@@ -388,7 +381,7 @@ void mesh_cleanup(void)
free_pending_join_call(true);
}
- l_queue_destroy(attach_queue, attach_exit);
+ l_queue_destroy(pending_queue, pending_request_exit);
node_cleanup_all();
mesh_model_cleanup();
@@ -628,38 +621,29 @@ done:
return reply;
}
-static bool match_attach_request(const void *a, const void *b)
-{
- const struct attach_data *pending = a;
- const uint64_t *token = b;
-
- return *token == pending->token;
-}
-
-static void attach_ready_cb(int status, char *node_path, uint64_t token)
+static void attach_ready_cb(void *user_data, int status, struct mesh_node *node)
{
struct l_dbus_message *reply;
- struct attach_data *pending;
+ struct l_dbus_message *pending_msg;
- pending = l_queue_find(attach_queue, match_attach_request, &token);
- if (!pending)
+ pending_msg = l_queue_find(pending_queue, simple_match, user_data);
+ if (!pending_msg)
return;
if (status != MESH_ERROR_NONE) {
const char *desc = (status == MESH_ERROR_NOT_FOUND) ?
"Node match not found" : "Attach failed";
- reply = dbus_error(pending->msg, status, desc);
+ reply = dbus_error(pending_msg, status, desc);
goto done;
}
- reply = l_dbus_message_new_method_return(pending->msg);
+ reply = l_dbus_message_new_method_return(pending_msg);
- node_build_attach_reply(reply, token);
+ node_build_attach_reply(node, reply);
done:
l_dbus_send(dbus_get_bus(), reply);
- l_queue_remove(attach_queue, pending);
- l_free(pending);
+ l_queue_remove(pending_queue, pending_msg);
}
static struct l_dbus_message *attach_call(struct l_dbus *dbus,
@@ -668,7 +652,8 @@ static struct l_dbus_message *attach_call(struct l_dbus *dbus,
{
uint64_t token;
const char *app_path, *sender;
- struct attach_data *pending;
+ struct l_dbus_message *pending_msg;
+ int status;
l_debug("Attach");
@@ -677,22 +662,20 @@ static struct l_dbus_message *attach_call(struct l_dbus *dbus,
sender = l_dbus_message_get_sender(msg);
- if (node_attach(app_path, sender, token, attach_ready_cb) !=
- MESH_ERROR_NONE)
- return dbus_error(msg, MESH_ERROR_NOT_FOUND,
- "Matching node not found");
+ pending_msg = l_dbus_message_ref(msg);
+ if (!pending_queue)
+ pending_queue = l_queue_new();
- pending = l_new(struct attach_data, 1);
+ l_queue_push_tail(pending_queue, pending_msg);
- pending->token = token;
- pending->msg = l_dbus_message_ref(msg);
+ status = node_attach(app_path, sender, token, attach_ready_cb,
+ pending_msg);
+ if (status == MESH_ERROR_NONE)
+ return NULL;
- if (!attach_queue)
- attach_queue = l_queue_new();
+ l_queue_remove(pending_queue, pending_msg);
- l_queue_push_tail(attach_queue, pending);
-
- return NULL;
+ return dbus_error(msg, status, NULL);
}
static struct l_dbus_message *leave_call(struct l_dbus *dbus,
diff --git a/mesh/node.c b/mesh/node.c
index a6c9332bc..a9eb41e87 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -101,8 +101,9 @@ struct mesh_node {
};
struct attach_obj_request {
- node_attach_ready_func_t cb;
+ node_ready_func_t cb;
struct mesh_node *node;
+ void *user_data;
};
struct join_obj_request {
@@ -1077,7 +1078,6 @@ static void get_managed_objects_attach_cb(struct l_dbus_message *msg,
struct attach_obj_request *req = user_data;
struct mesh_node *node = req->node;
const char *path;
- uint64_t token = l_get_be64(node->token);
uint8_t num_ele;
if (l_dbus_message_is_error(msg)) {
@@ -1124,12 +1124,12 @@ static void get_managed_objects_attach_cb(struct l_dbus_message *msg,
node->disc_watch = l_dbus_add_disconnect_watch(bus, node->owner,
app_disc_cb, node, NULL);
- req->cb(MESH_ERROR_NONE, node->path, token);
+ req->cb(req->user_data, MESH_ERROR_NONE, node);
return;
}
fail:
- req->cb(MESH_ERROR_FAILED, NULL, token);
+ req->cb(req->user_data, MESH_ERROR_FAILED, NULL);
l_queue_foreach(node->elements, free_element_path, NULL);
l_free(node->app_path);
@@ -1141,7 +1141,7 @@ fail:
/* Establish relationship between application and mesh node */
int node_attach(const char *app_path, const char *sender, uint64_t token,
- node_attach_ready_func_t cb)
+ node_ready_func_t cb, void *user_data)
{
struct attach_obj_request *req;
struct mesh_node *node;
@@ -1162,6 +1162,7 @@ int node_attach(const char *app_path, const char *sender, uint64_t token,
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,
@@ -1531,15 +1532,11 @@ static void build_element_config(void *a, void *b)
l_dbus_message_builder_leave_struct(builder);
}
-void node_build_attach_reply(struct l_dbus_message *reply, uint64_t token)
+void node_build_attach_reply(struct mesh_node *node,
+ struct l_dbus_message *reply)
{
- struct mesh_node *node;
struct l_dbus_message_builder *builder;
- node = l_queue_find(nodes, match_token, &token);
- if (!node)
- return;
-
builder = l_dbus_message_builder_new(reply);
/* Node object path */
diff --git a/mesh/node.h b/mesh/node.h
index ebc82ffb8..20b60099e 100644
--- a/mesh/node.h
+++ b/mesh/node.h
@@ -27,8 +27,8 @@ struct mesh_agent;
#define MIN_SEQ_CACHE (2*MIN_SEQ_TRIGGER)
#define MIN_SEQ_CACHE_TIME (5*60)
-typedef void (*node_attach_ready_func_t) (int status, char *node_path,
- uint64_t token);
+typedef void (*node_ready_func_t) (void *user_data, int status,
+ struct mesh_node *node);
typedef void (*node_join_ready_func_t) (struct mesh_node *node,
struct mesh_agent *agent);
@@ -86,8 +86,9 @@ bool node_add_pending_local(struct mesh_node *node, void *info,
struct mesh_io *io);
void node_attach_io(struct mesh_io *io);
int node_attach(const char *app_path, const char *sender, uint64_t token,
- node_attach_ready_func_t cb);
-void node_build_attach_reply(struct l_dbus_message *reply, uint64_t token);
+ node_ready_func_t cb, void *user_data);
+void node_build_attach_reply(struct mesh_node *node,
+ struct l_dbus_message *reply);
void node_id_set(struct mesh_node *node, uint16_t node_id);
uint16_t node_id_get(struct mesh_node *node);
bool node_dbus_init(struct l_dbus *bus);
--
2.17.2
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH BlueZ 3/4] mesh: Consolidate processing of mesh element properties
2019-04-29 19:45 [PATCH BlueZ 0/4] Cleanup of org.bluez.mesh.Network1 interface Inga Stotland
2019-04-29 19:45 ` [PATCH BlueZ 1/4] mesh: Remove Node interface if node owner disconnects Inga Stotland
2019-04-29 19:45 ` [PATCH BlueZ 2/4] mesh: Clean up processing of Attach() method Inga Stotland
@ 2019-04-29 19:45 ` Inga Stotland
2019-04-29 19:45 ` [PATCH BlueZ 4/4] mesh: Unify processing of GetManagedObjects result Inga Stotland
2019-05-02 16:01 ` [PATCH BlueZ 0/4] Cleanup of org.bluez.mesh.Network1 interface Gix, Brian
4 siblings, 0 replies; 6+ messages in thread
From: Inga Stotland @ 2019-04-29 19:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland
Consolidate functions to parse and process properties of mesh
element objects. Also, add validation of element composition
when processing Attach() method.
---
mesh/node.c | 269 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 167 insertions(+), 102 deletions(-)
diff --git a/mesh/node.c b/mesh/node.c
index a9eb41e87..0c2fc7262 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -147,6 +147,14 @@ static bool match_element_idx(const void *a, const void *b)
return (element->idx == index);
}
+static bool match_model_id(const void *a, const void *b)
+{
+ const struct mesh_model *mod = a;
+ uint32_t mod_id = L_PTR_TO_UINT(b);
+
+ return mod_id == mesh_model_get_model_id(mod);
+}
+
static bool match_element_path(const void *a, const void *b)
{
const struct node_element *element = a;
@@ -1029,20 +1037,115 @@ static void app_disc_cb(struct l_dbus *bus, void *user_data)
}
}
-static bool validate_element_properties(struct mesh_node *node,
- const char *path,
- struct l_dbus_message_iter *properties)
+
+static bool validate_model_property(struct node_element *ele,
+ struct l_dbus_message_iter *property,
+ uint8_t *num_models, bool vendor)
+{
+ struct l_dbus_message_iter ids;
+ uint16_t mod_id, vendor_id;
+ uint8_t count;
+ const char *signature = !vendor ? "aq" : "a(qq)";
+
+ if (!l_dbus_message_iter_get_variant(property, signature, &ids)) {
+ /* Allow empty elements */
+ if (l_queue_length(ele->models) == 0) {
+ *num_models = 0;
+ return true;
+ } else
+ return false;
+ }
+
+ count = 0;
+ if (!vendor) {
+ /* Bluetooth SIG defined models */
+ while (l_dbus_message_iter_next_entry(&ids, &mod_id)) {
+ struct mesh_model *mod;
+ uint32_t m = mod_id;
+
+ /* Skip internally implemented models */
+ if (m == CONFIG_SRV_MODEL)
+ continue;
+
+ mod = l_queue_find(ele->models, match_model_id,
+ L_UINT_TO_PTR(VENDOR_ID_MASK | mod_id));
+ if (!mod)
+ return false;
+ count++;
+ }
+ } else {
+ /* Vendor defined models */
+ 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)
+ return false;
+ count++;
+ }
+ }
+
+ *num_models = count;
+ return true;
+}
+
+static void get_models_from_properties(struct node_element *ele,
+ struct l_dbus_message_iter *property,
+ bool vendor)
+{
+ struct l_dbus_message_iter ids;
+ uint16_t mod_id, vendor_id;
+ const char *signature = !vendor ? "aq" : "a(qq)";
+
+ if (!ele->models)
+ ele->models = l_queue_new();
+
+ if (!l_dbus_message_iter_get_variant(property, signature, &ids))
+ return;
+
+ /* Bluetooth SIG defined models */
+ if (!vendor) {
+ while (l_dbus_message_iter_next_entry(&ids, &mod_id)) {
+ struct mesh_model *mod;
+ uint32_t m = mod_id;
+
+ /* Skip internally implemented models */
+ if (m == CONFIG_SRV_MODEL)
+ continue;
+
+ mod = mesh_model_new(ele->idx, mod_id);
+ l_queue_push_tail(ele->models, mod);
+ }
+ return;
+ }
+
+ /* Vendor defined models */
+ while (l_dbus_message_iter_next_entry(&ids, &vendor_id, &mod_id)) {
+ struct mesh_model *mod;
+
+ mod = mesh_model_vendor_new(ele->idx, vendor_id, mod_id);
+ l_queue_push_tail(ele->models, mod);
+ }
+}
+
+static bool get_element_properties(struct mesh_node *node, const char *path,
+ struct l_dbus_message_iter *properties,
+ bool create_new)
{
- uint8_t ele_idx;
struct node_element *ele;
const char *key;
- struct l_dbus_message_iter variant;
+ struct l_dbus_message_iter var;
bool have_index = false;
+ uint8_t idx, mod_cnt, vendor_cnt;
l_debug("path %s", path);
- while (l_dbus_message_iter_next_entry(properties, &key, &variant)) {
+ while (l_dbus_message_iter_next_entry(properties, &key, &var)) {
if (!strcmp(key, "Index")) {
+ if (!l_dbus_message_iter_get_variant(&var, "y", &idx))
+ return false;
have_index = true;
break;
}
@@ -1053,20 +1156,66 @@ static bool validate_element_properties(struct mesh_node *node,
return false;
}
- if (!l_dbus_message_iter_get_variant(&variant, "y", &ele_idx))
- return false;
+ if (!create_new) {
+ /* Validate composition: check the element index */
+ ele = l_queue_find(node->elements, match_element_idx,
+ L_UINT_TO_PTR(idx));
+ if (!ele) {
+ l_debug("Element with index %u not found", idx);
+ return false;
+ }
+ } else {
+ ele = l_new(struct node_element, 1);
+ ele->location = DEFAULT_LOCATION;
+ ele->idx = idx;
+ }
- ele = l_queue_find(node->elements, match_element_idx,
- L_UINT_TO_PTR(ele_idx));
+ mod_cnt = 0;
+ vendor_cnt = 0;
- if (!ele) {
- l_debug("Element with index %u not found", ele_idx);
- return false;
+ while (l_dbus_message_iter_next_entry(properties, &key, &var)) {
+ if (!strcmp(key, "Location")) {
+ uint8_t loc;
+
+ l_dbus_message_iter_get_variant(&var, "q", &loc);
+
+ /* Validate composition: location match */
+ if (!create_new && (ele->location != loc))
+ return false;
+
+ ele->location = loc;
+
+ } else if (!strcmp(key, "Models")) {
+
+ if (create_new)
+ get_models_from_properties(ele, &var, false);
+ else if (!validate_model_property(ele, &var, &mod_cnt,
+ false))
+ return false;
+
+ } else if (!strcmp(key, "VendorModels")) {
+
+ if (create_new)
+ get_models_from_properties(ele, &var, true);
+ else if (!validate_model_property(ele, &var,
+ &vendor_cnt, true))
+ return false;
+ }
}
- /* TODO: validate models */
+ if (create_new) {
+ l_queue_push_tail(node->elements, ele);
+ } else {
+ /* Account for internal Configuration Server model */
+ if (idx == 0)
+ mod_cnt += 1;
- ele->path = l_strdup(path);
+ /* Validate composition: number of models must match */
+ if (l_queue_length(ele->models) != (mod_cnt + vendor_cnt))
+ return false;
+
+ ele->path = l_strdup(path);
+ }
return true;
}
@@ -1101,8 +1250,8 @@ static void get_managed_objects_attach_cb(struct l_dbus_message *msg,
if (strcmp(MESH_ELEMENT_INTERFACE, interface))
continue;
- if (!validate_element_properties(node, path,
- &properties))
+ if (!get_element_properties(node, path, &properties,
+ false))
goto fail;
num_ele++;
@@ -1173,90 +1322,6 @@ int node_attach(const char *app_path, const char *sender, uint64_t token,
}
-static void add_model_from_properties(struct node_element *ele,
- struct l_dbus_message_iter *property)
-{
- struct l_dbus_message_iter ids;
- uint16_t model_id;
- int i = 0;
-
- if (!ele->models)
- ele->models = l_queue_new();
-
- if (!l_dbus_message_iter_get_variant(property, "aq", &ids))
- return;
-
- while (l_dbus_message_iter_next_entry(&ids, &model_id)) {
- struct mesh_model *mod;
- l_debug("model_id %4.4x", model_id);
- mod = mesh_model_new(ele->idx, model_id);
- l_queue_push_tail(ele->models, mod);
- i++;
- if (i > 3)
- break;
- }
-}
-
-static void add_vendor_model_from_properties(struct node_element *ele,
- struct l_dbus_message_iter *property)
-{
- struct l_dbus_message_iter ids;
- uint16_t v;
- uint16_t m;
-
- if (!ele->models)
- ele->models = l_queue_new();
-
- if (!l_dbus_message_iter_get_variant(property, "a(qq)", &ids))
- return;
-
- while (l_dbus_message_iter_next_entry(&ids, &v, &m)) {
- struct mesh_model *mod;
-
- mod = mesh_model_vendor_new(ele->idx, v, m);
- l_queue_push_tail(ele->models, mod);
- }
-}
-
-static bool get_element_properties(struct mesh_node *node, const char *path,
- struct l_dbus_message_iter *properties)
-{
- struct node_element *ele;
- const char *key;
- struct l_dbus_message_iter variant;
- bool have_index = false;
-
- l_debug("path %s", path);
-
- ele = l_new(struct node_element, 1);
- ele->location = DEFAULT_LOCATION;
-
- while (l_dbus_message_iter_next_entry(properties, &key, &variant)) {
- if (!strcmp(key, "Index")) {
- if (!l_dbus_message_iter_get_variant(&variant, "y",
- &ele->idx))
- return false;
- have_index = true;
- } else if (!strcmp(key, "Location")) {
- l_dbus_message_iter_get_variant(&variant, "q",
- &ele->location);
- } else if (!strcmp(key, "Models")) {
- add_model_from_properties(ele, &variant);
- } else if (!strcmp(key, "VendorModels")) {
- add_vendor_model_from_properties(ele, &variant);
- }
- }
-
- if (!have_index) {
- l_debug("Mandatory property \"Index\" not found");
- return false;
- }
-
- l_queue_push_tail(node->elements, ele);
-
- return true;
-}
-
static bool get_app_properties(struct mesh_node *node, const char *path,
struct l_dbus_message_iter *properties)
{
@@ -1418,7 +1483,7 @@ static void get_managed_objects_join_cb(struct l_dbus_message *msg,
if (!strcmp(MESH_ELEMENT_INTERFACE, interface)) {
res = get_element_properties(node, path,
- &properties);
+ &properties, true);
if (!res)
goto fail;
--
2.17.2
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH BlueZ 4/4] mesh: Unify processing of GetManagedObjects result
2019-04-29 19:45 [PATCH BlueZ 0/4] Cleanup of org.bluez.mesh.Network1 interface Inga Stotland
` (2 preceding siblings ...)
2019-04-29 19:45 ` [PATCH BlueZ 3/4] mesh: Consolidate processing of mesh element properties Inga Stotland
@ 2019-04-29 19:45 ` Inga Stotland
2019-05-02 16:01 ` [PATCH BlueZ 0/4] Cleanup of org.bluez.mesh.Network1 interface Gix, Brian
4 siblings, 0 replies; 6+ messages in thread
From: Inga Stotland @ 2019-04-29 19:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: brian.gix, johan.hedberg, luiz.dentz, Inga Stotland
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
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH BlueZ 0/4] Cleanup of org.bluez.mesh.Network1 interface
2019-04-29 19:45 [PATCH BlueZ 0/4] Cleanup of org.bluez.mesh.Network1 interface Inga Stotland
` (3 preceding siblings ...)
2019-04-29 19:45 ` [PATCH BlueZ 4/4] mesh: Unify processing of GetManagedObjects result Inga Stotland
@ 2019-05-02 16:01 ` Gix, Brian
4 siblings, 0 replies; 6+ messages in thread
From: Gix, Brian @ 2019-05-02 16:01 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org, Stotland, Inga
Cc: luiz.dentz@gmail.com, johan.hedberg@gmail.com
Patch-set applied
On Mon, 2019-04-29 at 12:45 -0700, Inga Stotland wrote:
> This set of patches tightens the existing implementation of Join() and
> Attach() methods. Some redundacies are removed, common code is combined and
> validation of node composition is added for Attach method.
>
> Inga Stotland (4):
> mesh: Remove Node interface if node owner disconnects
> mesh: Clean up processing of Attach() method
> mesh: Consolidate processing of mesh element properties
> mesh: Unify processing of GetManagedObjects result
>
> mesh/mesh-defs.h | 2 +
> mesh/mesh.c | 69 +++---
> mesh/node.c | 558 ++++++++++++++++++++++++++---------------------
> mesh/node.h | 9 +-
> 4 files changed, 344 insertions(+), 294 deletions(-)
>
^ permalink raw reply [flat|nested] 6+ messages in thread