* [PATCH BlueZ v3 1/3] mesh: Add ImportLocalNode api documentation @ 2019-07-05 15:22 Jakub Witowski 2019-07-05 15:22 ` [PATCH BlueZ v3 2/3] mesh: Added ImportLocalNode call with its API Jakub Witowski 2019-07-05 15:22 ` [PATCH BlueZ v3 3/3] mesh: Separate json type from the node.c file Jakub Witowski 0 siblings, 2 replies; 4+ messages in thread From: Jakub Witowski @ 2019-07-05 15:22 UTC (permalink / raw) To: linux-bluetooth; +Cc: Inga Stotland This updates the mesh-api.txt with new ImportLocalNode() API. --- doc/mesh-api.txt | 104 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 11 deletions(-) diff --git a/doc/mesh-api.txt b/doc/mesh-api.txt index 893a1a6c0..f2ba164a9 100644 --- a/doc/mesh-api.txt +++ b/doc/mesh-api.txt @@ -151,16 +151,36 @@ Methods: org.bluez.mesh.Error.InvalidArguments org.bluez.mesh.Error.AlreadyExists, - uint64 token ImportLocalNode(string json_data) + uint64 token ImportLocalNode(object app_root, array{byte}[16] uuid, + string data_type, array{byte} import_data) This method creates a local mesh node based on node configuration that has been generated outside bluetooth-meshd. - The json_data parameter is a full JSON representation of a node - configuration file. The format must conform to the schema - defined in "Mesh Node Configuration Schema" section. Any - included token will be ignored in favor of a locally generated - token value. + The app_root parameter is a D-Bus object root path of the + application that implements org.bluez.mesh.Application1 + interface, and a org.bluez.mesh.Provisioner1 interface. + + The data_type parameter defines the import_data type. Supported + data_type parameters: + - “json” + + The import_data parameter can be either: + - Simplified representation of node configuration with + provisioning data only + - Full representation of node configuration with both + provisioning and composition data + + sequenceNumber parameter int the import_data is optional. + + The format must conform to the schema defined in + "Mesh Node Configuration Examples" section. Any included token will + be ignored in favor of a locally generated token value. If + import_data contains composition data (determined by the presence of + Elements) it is validated against composition data provided by + the application. Otherwise, new node is created based on + composition data provided by the application using provisioning data + from import_data parameter. The returned token must be preserved by the application in order to authenticate itself to the mesh daemon and attach to @@ -173,8 +193,8 @@ Methods: PossibleErrors: org.bluez.mesh.Error.InvalidArguments, - org.bluez.mesh.Error.AlreadyExists - org.bluez.mesh.Error.NotFound, + org.bluez.mesh.Error.AlreadyExists, + org.bluez.mesh.Error.NotSupported, org.bluez.mesh.Error.Failed Mesh Node Hierarchy @@ -1061,6 +1081,68 @@ Properties: Uniform Resource Identifier points to out-of-band (OOB) information (e.g., a public key) -Mesh Node Configuration Schema -============================== -<TBD> +Mesh Node Configuration Examples +================================ +Example of Json format for ImportLocalNode(): + + Import simplified node operation: + { + "IVindex":0, + "IVupdate":0, + "unicastAddress":"0012", + "deviceKey":"7daa45cd1e9e11a4b86eeef7d01efa11", + "sequenceNumber":15 + "netKeys":[ + { + "index":"0000", + "key":"2ddfef86d67144c394428ea3078f86f9", + "keyRefresh":0 + }], + } + + Import full node operation: + { + "cid":"fee5", + "pid":"0042", + "vid":"0001", + "crpl":"2710", + "relay":{ + "mode":"disabled", + "count":0, + "interval":0 + }, + "lowPower":"unsupported", + "friend":"unsupported", + "proxy":"unsupported", + "beacon":"disabled", + "defaultTTL":255, + "elements":[ + { + "elementIndex":0, + "location":"002a", + "models":[ + { + "modelId":"0008", + "bind":[ + "0000"] + }] + }], + "IVindex":0, + "IVupdate":0, + "unicastAddress":"0010", + "token":"bba7c60afaa85fc1", + "deviceKey":"56325fd145f3d5eee1b82136dc3e1454", + "netKeys":[ + { + "index":"0000", + "key":"2ddfef86d67144c394428ea3078f86f9", + "keyRefresh":0 + }], + "appKeys":[ + { + "index":"0000", + "boundNetKey":"0000", + "key":"43886b02ca4343beaae26dc4b6773ba4" + }], + "sequenceNumber":15 + } -- 2.20.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH BlueZ v3 2/3] mesh: Added ImportLocalNode call with its API 2019-07-05 15:22 [PATCH BlueZ v3 1/3] mesh: Add ImportLocalNode api documentation Jakub Witowski @ 2019-07-05 15:22 ` Jakub Witowski 2019-07-05 15:22 ` [PATCH BlueZ v3 3/3] mesh: Separate json type from the node.c file Jakub Witowski 1 sibling, 0 replies; 4+ messages in thread From: Jakub Witowski @ 2019-07-05 15:22 UTC (permalink / raw) To: linux-bluetooth; +Cc: Inga Stotland This implements ImportLocalNode() method on org.bluez.mesh.Network1 interface. Invoking this method creates a self-provisioned node based on passed JSON definition. Also full functionality of import local node has been implemented --- mesh/mesh.c | 90 +++++++++++++++++-- mesh/node.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++++---- mesh/node.h | 2 + 3 files changed, 317 insertions(+), 22 deletions(-) diff --git a/mesh/mesh.c b/mesh/mesh.c index 26acfd4dc..b3def7817 100644 --- a/mesh/mesh.c +++ b/mesh/mesh.c @@ -22,6 +22,8 @@ #endif #define _GNU_SOURCE +#include <json-c/json.h> +#include <string.h> #include <ell/ell.h> #include "mesh/mesh-io.h" @@ -60,7 +62,7 @@ struct bt_mesh { uint8_t max_filters; }; -struct join_data{ +struct join_data { struct l_dbus_message *msg; struct mesh_agent *agent; const char *sender; @@ -70,6 +72,10 @@ struct join_data{ uint8_t *uuid; }; +static const char * const supported_import_data_types[] = { + "json" +}; + static struct bt_mesh mesh; /* We allow only one outstanding Join request */ @@ -365,8 +371,8 @@ static void node_init_cb(struct mesh_node *node, struct mesh_agent *agent) if (!acceptor_start(num_ele, join_pending->uuid, mesh.algorithms, mesh.prov_timeout, agent, prov_complete_cb, - &mesh)) - { + &mesh)) { + reply = dbus_error(join_pending->msg, MESH_ERROR_FAILED, "Failed to start provisioning acceptor"); goto fail; @@ -383,6 +389,18 @@ fail: free_pending_join_call(true); } +static bool validate_data_type(const char *data_type) +{ + uint8_t len = sizeof(supported_import_data_types) / + sizeof(supported_import_data_types[0]); + + for (uint8_t idx = 0; idx < len; idx++) { + if (strcmp(data_type, supported_import_data_types[idx]) == 0) + return true; + } + return false; +} + static struct l_dbus_message *join_network_call(struct l_dbus *dbus, struct l_dbus_message *msg, void *user_data) @@ -536,7 +554,7 @@ static struct l_dbus_message *leave_call(struct l_dbus *dbus, return l_dbus_message_new_method_return(msg); } -static void create_network_ready_cb(void *user_data, int status, +static void create_node_ready_cb(void *user_data, int status, struct mesh_node *node) { struct l_dbus_message *reply; @@ -593,12 +611,67 @@ static struct l_dbus_message *create_network_call(struct l_dbus *dbus, l_queue_push_tail(pending_queue, pending_msg); - node_create(app_path, sender, uuid, create_network_ready_cb, + node_create(app_path, sender, uuid, create_node_ready_cb, pending_msg); return NULL; } +static struct l_dbus_message *import_local_node_call(struct l_dbus *dbus, + struct l_dbus_message *msg, + void *user_data) +{ + const char *app_path, *sender; + struct l_dbus_message *pending_msg; + struct l_dbus_message_iter iter_uuid, iter_import_data; + const char *data_type, *import_data; + uint8_t *uuid; + uint32_t n; + struct json_object *jnode; + + l_debug("Import local node request"); + + if (!l_dbus_message_get_arguments(msg, "oaysay", &app_path, &iter_uuid, + &data_type, &iter_import_data)) + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL); + + if (!validate_data_type(data_type)) + return dbus_error(msg, MESH_ERROR_NOT_IMPLEMENTED, + "Unsupported data type"); + + if (!l_dbus_message_iter_get_fixed_array(&iter_uuid, &uuid, &n) || + n != 16) + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, "Bad dev UUID"); + + if (node_find_by_uuid(uuid)) + return dbus_error(msg, MESH_ERROR_ALREADY_EXISTS, + "Node already exists"); + + if (!l_dbus_message_iter_get_fixed_array(&iter_import_data, + &import_data, &n)) + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, + "Bad import_data"); + + jnode = json_tokener_parse(import_data); + + sender = l_dbus_message_get_sender(msg); + pending_msg = l_dbus_message_ref(msg); + + if (!pending_queue) + pending_queue = l_queue_new(); + + l_queue_push_tail(pending_queue, pending_msg); + + if (!node_import(app_path, sender, jnode, uuid, create_node_ready_cb, + pending_msg)) { + l_dbus_message_unref(msg); + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, + "Node import failed"); + } + + return NULL; +} + static void setup_network_interface(struct l_dbus_interface *iface) { l_dbus_interface_method(iface, "Join", 0, join_network_call, "", @@ -612,8 +685,15 @@ static void setup_network_interface(struct l_dbus_interface *iface) l_dbus_interface_method(iface, "Leave", 0, leave_call, "", "t", "token"); + l_dbus_interface_method(iface, "CreateNetwork", 0, create_network_call, "t", "oay", "token", "app", "uuid"); + + l_dbus_interface_method(iface, "ImportLocalNode", 0, + import_local_node_call, + "t", "oaysay", "token", + "app", "uuid", "data_type", + "import_data"); } bool mesh_dbus_init(struct l_dbus *dbus) diff --git a/mesh/node.c b/mesh/node.c index 1f781cfe9..00c3270fd 100644 --- a/mesh/node.c +++ b/mesh/node.c @@ -27,6 +27,7 @@ #include <ell/ell.h> #include <json-c/json.h> +#include <stdio.h> #include "mesh/mesh-defs.h" #include "mesh/mesh.h" @@ -57,9 +58,12 @@ #define DEFAULT_CRPL 10 #define DEFAULT_SEQUENCE_NUMBER 0 -#define REQUEST_TYPE_JOIN 0 -#define REQUEST_TYPE_ATTACH 1 -#define REQUEST_TYPE_CREATE 2 +enum request_type { + REQUEST_TYPE_JOIN = 0, + REQUEST_TYPE_ATTACH, + REQUEST_TYPE_CREATE, + REQUEST_TYPE_IMPORT, +}; struct node_element { char *path; @@ -110,7 +114,19 @@ struct managed_obj_request { void *data; void *cb; void *user_data; - uint8_t type; + enum request_type type; +}; + +struct node_import_request { + uint8_t uuid[16]; + uint8_t dev_key[16]; + uint8_t net_key[16]; + uint16_t net_idx; + uint16_t unicast; + uint32_t iv_idx; + bool iv_update; + uint32_t sequence; + void *user_data; }; static struct l_queue *nodes; @@ -870,7 +886,7 @@ element_done: #define MIN_COMPOSITION_LEN 16 bool node_parse_composition(struct mesh_node *node, uint8_t *data, - uint16_t len) + uint16_t len) { struct node_composition *comp; uint16_t features; @@ -965,7 +981,7 @@ bool node_parse_composition(struct mesh_node *node, uint8_t *data, vendor_id = l_get_le16(data); mod_id |= (vendor_id << 16); mod = mesh_model_vendor_new(ele->idx, vendor_id, - mod_id); + mod_id); if (!mod) { element_free(ele); goto fail; @@ -996,7 +1012,6 @@ fail: return false; } - static void attach_io(void *a, void *b) { struct mesh_node *node = a; @@ -1385,17 +1400,86 @@ static bool get_app_properties(struct mesh_node *node, const char *path, return true; } -static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr, - bool ivu, uint32_t iv_idx, uint8_t dev_key[16], - uint16_t net_key_idx, uint8_t net_key[16]) +static bool parse_imported_unicast_addr(json_object *jobj, uint16_t *unicast) { - node->net = mesh_net_new(node); + char *str; - if (!nodes) - nodes = l_queue_new(); + str = (char *)json_object_get_string(jobj); - l_queue_push_tail(nodes, node); + if (sscanf(str, "%04hx", unicast) != 1) + return false; + + return true; +} + +static bool parse_imported_device_key(json_object *jobj, uint8_t key_buf[16]) +{ + char *str; + + if (!key_buf) + return false; + str = (char *)json_object_get_string(jobj); + + if (!str2hex(str, strlen(str), key_buf, 16)) + return false; + + return true; +} + +static void parse_imported_sequence_nr(json_object *jobj, uint32_t *seq) +{ + json_object *jvalue; + + if (json_object_object_get_ex(jobj, "sequenceNumber", &jvalue)) + *seq = (uint32_t) json_object_get_int(jvalue); + else + *seq = DEFAULT_SEQUENCE_NUMBER; +} + +static bool parse_imported_net_key(json_object *jobj, uint8_t key_buf[16], + uint16_t *net_idx) +{ + json_object *jtemp, *jvalue; + char *str; + uint8_t key[16]; + + if (json_object_get_type(jobj) != json_type_array) + return false; + + jtemp = json_object_array_get_idx(jobj, 0); + + if (!json_object_object_get_ex(jtemp, "index", &jvalue)) + return false; + + *net_idx = (uint16_t)json_object_get_int(jvalue); + + if (*net_idx > 4095) + return false; + + if (!json_object_object_get_ex(jtemp, "key", &jvalue)) + return false; + + str = (char *)json_object_get_string(jvalue); + if (!str2hex(str, strlen(str), key, 16)) + return false; + + memcpy(&key_buf[0], &key[0], 16); + + /* Imported node shouldn't contain oldKey or keyRefresh */ + if (json_object_object_get_ex(jtemp, "oldKey", NULL)) + return false; + + if (json_object_object_get_ex(jtemp, "keyRefresh", NULL)) + return false; + + return true; +} + +static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr, + bool ivu, uint32_t iv_idx, uint8_t dev_key[16], + uint16_t net_key_idx, uint8_t net_key[16]) +{ if (!storage_set_iv_index(node->net, iv_idx, ivu)) return false; @@ -1463,14 +1547,13 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data) } if (is_new) { - node = l_new(struct mesh_node, 1); + node = node_new(req->data); 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; const char *interface; @@ -1566,6 +1649,48 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data) cb(node, agent); + } else if (req->type == REQUEST_TYPE_IMPORT) { + + node_ready_func_t cb = req->cb; + struct node_import_request *import_data = req->user_data; + struct keyring_net_key net_key; + + if (!agent) { + l_error("Interface %s not found", + MESH_PROVISION_AGENT_INTERFACE); + goto fail; + } + + node->num_ele = num_ele; + set_defaults(node); + + if (node->seq_number != import_data->sequence) + node->seq_number = import_data->sequence; + + memcpy(node->uuid, import_data->uuid, 16); + + if (!create_node_config(node)) + goto fail; + + if (!add_local_node(node, import_data->unicast, false, + import_data->iv_update, import_data->iv_idx, + import_data->dev_key, import_data->net_idx, + import_data->net_key)) + goto fail; + + memcpy(net_key.old_key, import_data->net_key, 16); + net_key.net_idx = import_data->net_idx; + net_key.phase = KEY_REFRESH_PHASE_NONE; + + if (!keyring_put_remote_dev_key(node, import_data->unicast, + num_ele, import_data->dev_key)) + goto fail; + + if (!keyring_put_net_key(node, PRIMARY_NET_IDX, &net_key)) + goto fail; + + cb(import_data->user_data, MESH_ERROR_NONE, node); + } else { /* Callback for create node request */ node_ready_func_t cb = req->cb; @@ -1614,7 +1739,7 @@ fail: cb(req->user_data, MESH_ERROR_FAILED, node); } else { - /* Handle failed Join and Create requests */ + /* Handle failed Join, Create and Import requests */ if (node) node_remove(node); @@ -1622,6 +1747,14 @@ fail: node_join_ready_func_t cb = req->cb; cb(NULL, NULL); + + } else if (req->type == REQUEST_TYPE_IMPORT) { + struct node_import_request *import_data = + req->user_data; + node_ready_func_t cb = req->cb; + + cb(import_data->user_data, MESH_ERROR_FAILED, NULL); + } else { node_ready_func_t cb = req->cb; @@ -1686,6 +1819,86 @@ void node_join(const char *app_path, const char *sender, const uint8_t *uuid, req, l_free); } +static bool node_import_full(const char *app_path, const char *sender, + void *json_data, const uint8_t *uuid, + node_ready_func_t cb, void *user_data) +{ + return false; +} + +static bool node_import_simplified(const char *app_path, const char *sender, + void *json_data, const uint8_t *uuid, + node_ready_func_t cb, void *user_data) +{ + struct managed_obj_request *req = l_new(struct managed_obj_request, 1); + struct node_import_request *node = l_new(struct node_import_request, 1); + + json_object_object_foreach(json_data, key, val) { + + if (!strcmp(key, "deviceKey")) { + if (!parse_imported_device_key(val, node->dev_key)) { + l_error("Failed to parse imported device key"); + goto fail; + } + + } else if (!strcmp(key, "unicastAddress")) { + if (!parse_imported_unicast_addr(val, &node->unicast)) { + l_error("Failed to parse imported unicast"); + goto fail; + } + + } else if (!strcmp(key, "IVindex")) { + node->iv_idx = (uint32_t) json_object_get_int(val); + + } else if (!strcmp(key, "IVupdate")) { + node->iv_update = (bool) json_object_get_int(val); + + } else if (!strcmp(key, "netKeys")) { + if (!parse_imported_net_key(val, + node->net_key, &node->net_idx)) { + l_error("Failed to parse imported network key"); + goto fail; + } + + } else { + if (strcmp(key, "sequenceNumber")) + goto fail; + } + } + + parse_imported_sequence_nr(json_data, &node->sequence); + node->user_data = user_data; + + memcpy(node->uuid, uuid, 16); + req->data = (void *) uuid; + req->user_data = node; + req->cb = cb; + req->type = REQUEST_TYPE_IMPORT; + + 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 true; + +fail: + json_object_put(json_data); + l_free(node); + return false; +} + +bool node_import(const char *app_path, const char *sender, void *json_data, + const uint8_t *uuid, node_ready_func_t cb, void *user_data) +{ + if (!json_object_object_get_ex(json_data, "elements", NULL)) + return node_import_simplified(app_path, sender, json_data, + uuid, cb, user_data); + else + return node_import_full(app_path, sender, json_data, uuid, + cb, user_data); +} + void node_create(const char *app_path, const char *sender, const uint8_t *uuid, node_ready_func_t cb, void *user_data) { diff --git a/mesh/node.h b/mesh/node.h index 142527b30..9559f9178 100644 --- a/mesh/node.h +++ b/mesh/node.h @@ -91,6 +91,8 @@ void node_build_attach_reply(struct mesh_node *node, struct l_dbus_message *reply); void node_create(const char *app_path, const char *sender, const uint8_t *uuid, node_ready_func_t cb, void *user_data); +bool node_import(const char *app_path, const char *sender, void *jnode, + const uint8_t *uuid, node_ready_func_t cb, void *user_data); 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.20.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH BlueZ v3 3/3] mesh: Separate json type from the node.c file 2019-07-05 15:22 [PATCH BlueZ v3 1/3] mesh: Add ImportLocalNode api documentation Jakub Witowski 2019-07-05 15:22 ` [PATCH BlueZ v3 2/3] mesh: Added ImportLocalNode call with its API Jakub Witowski @ 2019-07-05 15:22 ` Jakub Witowski 2019-07-05 15:41 ` Michał Lowas-Rzechonek 1 sibling, 1 reply; 4+ messages in thread From: Jakub Witowski @ 2019-07-05 15:22 UTC (permalink / raw) To: linux-bluetooth; +Cc: Inga Stotland This creates intermediate layer between imported node data and parser. --- mesh/mesh-db.c | 147 ++++++++++++++++++++++++++++++++++++- mesh/mesh-db.h | 11 +++ mesh/mesh.c | 31 +++++--- mesh/node.c | 193 ++++++++++--------------------------------------- mesh/node.h | 3 +- 5 files changed, 215 insertions(+), 170 deletions(-) diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c index e0a000261..0e8f40470 100644 --- a/mesh/mesh-db.c +++ b/mesh/mesh-db.c @@ -31,7 +31,7 @@ #include "mesh/mesh-defs.h" #include "mesh/util.h" - +#include "mesh/node.h" #include "mesh/mesh-db.h" #define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095)) @@ -253,6 +253,118 @@ static json_object *jarray_key_del(json_object *jarray, int16_t idx) return jarray_new; } +static bool parse_imported_unicast_addr(json_object *jobj, uint16_t *unicast) +{ + char *str = (char *)json_object_get_string(jobj); + + if (sscanf(str, "%04hx", unicast) != 1) + return false; + + return true; +} + +static bool parse_imported_net_key(json_object *jobj, uint8_t key_buf[16], + uint16_t *net_idx) +{ + json_object *jtemp, *jvalue; + char *str; + uint8_t key[16]; + + if (json_object_get_type(jobj) != json_type_array) + return false; + + jtemp = json_object_array_get_idx(jobj, 0); + + if (!json_object_object_get_ex(jtemp, "index", &jvalue)) + return false; + + *net_idx = (uint16_t)json_object_get_int(jvalue); + + if (*net_idx > 4095) + return false; + + if (!json_object_object_get_ex(jtemp, "key", &jvalue)) + return false; + + str = (char *)json_object_get_string(jvalue); + if (!str2hex(str, strlen(str), key, 16)) + return false; + + memcpy(&key_buf[0], &key[0], 16); + + /* Imported node shouldn't contain oldKey or keyRefresh */ + if (json_object_object_get_ex(jtemp, "oldKey", NULL)) + return false; + + if (json_object_object_get_ex(jtemp, "keyRefresh", NULL)) + return false; + + return true; +} + +static uint32_t parse_imported_sequence(json_object *jobj, + uint32_t default_seq_nr) +{ + json_object *jvalue; + + if (json_object_object_get_ex(jobj, "sequenceNumber", &jvalue)) + return (uint32_t) json_object_get_int(jvalue); + else + return default_seq_nr; +} + +static bool json_iter(json_object *jobj, struct mesh_db_import *db_node) +{ + bool dev_key = false, unicast = false; + bool iv_index = false, net_key = false; + + json_object_object_foreach(jobj, key, val) { + + if (!strcmp(key, "deviceKey")) { + + dev_key = true; + if (!mesh_db_read_device_key(jobj, db_node->dev_key)) { + l_error("Failed to parse imported device key"); + return false; + } + + } else if (!strcmp(key, "unicastAddress")) { + + unicast = true; + if (!parse_imported_unicast_addr(val, + &db_node->node->unicast)) { + l_error("Failed to parse imported unicast"); + return false; + } + + } else if (!strcmp(key, "IVindex")) { + + iv_index = true; + if (!mesh_db_read_iv_index(jobj, &db_node->iv_index, + &db_node->iv_update)) { + l_error("Failed to parse iv_index"); + return false; + } + + } else if (!strcmp(key, "netKeys")) { + + net_key = true; + if (!parse_imported_net_key(val, db_node->net_key, + &db_node->net_idx)) { + l_error("Failed to parse imported network key"); + return false; + } + + } else { + if (strcmp(key, "sequenceNumber") && + strcmp(key, "IVupdate")) + return false; + } + } + + return dev_key && unicast && net_key && iv_index; +} + bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update) { int tmp; @@ -1438,7 +1550,8 @@ static void add_model(void *a, void *b) } /* Add unprovisioned node (local) */ -bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) { +bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) +{ struct mesh_db_modes *modes = &node->modes; const struct l_queue_entry *entry; @@ -1783,3 +1896,33 @@ bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr, return delete_model_property(jnode, addr, mod_id, vendor, "subscribe"); } + + + +struct mesh_db_import *mesh_db_parse_import_data(const char *import_data) +{ + json_object *jobj = json_tokener_parse(import_data); + struct mesh_db_import *db_node = l_new(struct mesh_db_import, 1); + + if (!jobj) + goto fail; + + db_node->node = l_new(struct mesh_db_node, 1); + + if (!json_iter(jobj, db_node)) + goto fail; + + db_node->node->seq_number = + parse_imported_sequence(jobj, DEFAULT_SEQUENCE_NUMBER); + + return db_node; +fail: + if (jobj) + json_object_put(jobj); + + if (db_node->node) + l_free(db_node->node); + + l_free(db_node); + return NULL; +} diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h index da5efa12a..a227319ca 100644 --- a/mesh/mesh-db.h +++ b/mesh/mesh-db.h @@ -16,6 +16,7 @@ * Lesser General Public License for more details. * */ +#include <json-c/json.h> struct mesh_db_sub { bool virt; @@ -93,6 +94,15 @@ struct mesh_db_prov { uint8_t priv_key[32]; }; +struct mesh_db_import { + struct mesh_db_node *node; + uint8_t dev_key[16]; + uint8_t net_key[16]; + uint16_t net_idx; + uint32_t iv_index; + bool iv_update; +}; + typedef bool (*mesh_db_net_key_cb)(uint16_t idx, uint8_t key[16], uint8_t new_key[16], int phase, void *user_data); typedef bool (*mesh_db_app_key_cb)(uint16_t idx, uint16_t net_idx, @@ -155,3 +165,4 @@ bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase); bool mesh_db_write_address(json_object *jobj, uint16_t address); 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); +struct mesh_db_import *mesh_db_parse_import_data(const char *import_data); diff --git a/mesh/mesh.c b/mesh/mesh.c index b3def7817..6234121c9 100644 --- a/mesh/mesh.c +++ b/mesh/mesh.c @@ -22,7 +22,6 @@ #endif #define _GNU_SOURCE -#include <json-c/json.h> #include <string.h> #include <ell/ell.h> @@ -36,6 +35,7 @@ #include "mesh/error.h" #include "mesh/agent.h" #include "mesh/mesh.h" +#include "mesh/mesh-db.h" /* * The default values for mesh configuration. Can be @@ -391,10 +391,10 @@ fail: static bool validate_data_type(const char *data_type) { - uint8_t len = sizeof(supported_import_data_types) / - sizeof(supported_import_data_types[0]); + uint8_t idx = 0; + uint8_t len = L_ARRAY_SIZE(supported_import_data_types); - for (uint8_t idx = 0; idx < len; idx++) { + for (idx = 0; idx < len; idx++) { if (strcmp(data_type, supported_import_data_types[idx]) == 0) return true; } @@ -624,10 +624,10 @@ static struct l_dbus_message *import_local_node_call(struct l_dbus *dbus, const char *app_path, *sender; struct l_dbus_message *pending_msg; struct l_dbus_message_iter iter_uuid, iter_import_data; + struct mesh_db_import *p_node; const char *data_type, *import_data; uint8_t *uuid; uint32_t n; - struct json_object *jnode; l_debug("Import local node request"); @@ -652,7 +652,11 @@ static struct l_dbus_message *import_local_node_call(struct l_dbus *dbus, return dbus_error(msg, MESH_ERROR_INVALID_ARGS, "Bad import_data"); - jnode = json_tokener_parse(import_data); + p_node = mesh_db_parse_import_data(import_data); + + if (!p_node) + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, + "Failed to parse import_data"); sender = l_dbus_message_get_sender(msg); pending_msg = l_dbus_message_ref(msg); @@ -662,14 +666,17 @@ static struct l_dbus_message *import_local_node_call(struct l_dbus *dbus, l_queue_push_tail(pending_queue, pending_msg); - if (!node_import(app_path, sender, jnode, uuid, create_node_ready_cb, - pending_msg)) { - l_dbus_message_unref(msg); - return dbus_error(msg, MESH_ERROR_INVALID_ARGS, - "Node import failed"); - } + if (!node_import(app_path, sender, p_node, uuid, create_node_ready_cb, + pending_msg)) + goto fail; return NULL; + +fail: + l_free(p_node); + l_dbus_message_unref(msg); + l_queue_remove(pending_queue, pending_msg); + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, "Node import failed"); } static void setup_network_interface(struct l_dbus_interface *iface) diff --git a/mesh/node.c b/mesh/node.c index 00c3270fd..db04c0c87 100644 --- a/mesh/node.c +++ b/mesh/node.c @@ -26,8 +26,6 @@ #include <sys/time.h> #include <ell/ell.h> -#include <json-c/json.h> -#include <stdio.h> #include "mesh/mesh-defs.h" #include "mesh/mesh.h" @@ -56,7 +54,6 @@ #define DEFAULT_LOCATION 0x0000 #define DEFAULT_CRPL 10 -#define DEFAULT_SEQUENCE_NUMBER 0 enum request_type { REQUEST_TYPE_JOIN = 0, @@ -119,13 +116,7 @@ struct managed_obj_request { struct node_import_request { uint8_t uuid[16]; - uint8_t dev_key[16]; - uint8_t net_key[16]; - uint16_t net_idx; - uint16_t unicast; - uint32_t iv_idx; - bool iv_update; - uint32_t sequence; + struct mesh_db_import *import; void *user_data; }; @@ -885,8 +876,7 @@ element_done: #define MIN_COMPOSITION_LEN 16 -bool node_parse_composition(struct mesh_node *node, uint8_t *data, - uint16_t len) +bool node_parse_composition(struct mesh_node *node, uint8_t *data, uint16_t len) { struct node_composition *comp; uint16_t features; @@ -981,7 +971,7 @@ bool node_parse_composition(struct mesh_node *node, uint8_t *data, vendor_id = l_get_le16(data); mod_id |= (vendor_id << 16); mod = mesh_model_vendor_new(ele->idx, vendor_id, - mod_id); + mod_id); if (!mod) { element_free(ele); goto fail; @@ -1012,6 +1002,7 @@ fail: return false; } + static void attach_io(void *a, void *b) { struct mesh_node *node = a; @@ -1400,82 +1391,6 @@ static bool get_app_properties(struct mesh_node *node, const char *path, return true; } -static bool parse_imported_unicast_addr(json_object *jobj, uint16_t *unicast) -{ - char *str; - - str = (char *)json_object_get_string(jobj); - - if (sscanf(str, "%04hx", unicast) != 1) - return false; - - return true; -} - -static bool parse_imported_device_key(json_object *jobj, uint8_t key_buf[16]) -{ - char *str; - - if (!key_buf) - return false; - - str = (char *)json_object_get_string(jobj); - - if (!str2hex(str, strlen(str), key_buf, 16)) - return false; - - return true; -} - -static void parse_imported_sequence_nr(json_object *jobj, uint32_t *seq) -{ - json_object *jvalue; - - if (json_object_object_get_ex(jobj, "sequenceNumber", &jvalue)) - *seq = (uint32_t) json_object_get_int(jvalue); - else - *seq = DEFAULT_SEQUENCE_NUMBER; -} - -static bool parse_imported_net_key(json_object *jobj, uint8_t key_buf[16], - uint16_t *net_idx) -{ - json_object *jtemp, *jvalue; - char *str; - uint8_t key[16]; - - if (json_object_get_type(jobj) != json_type_array) - return false; - - jtemp = json_object_array_get_idx(jobj, 0); - - if (!json_object_object_get_ex(jtemp, "index", &jvalue)) - return false; - - *net_idx = (uint16_t)json_object_get_int(jvalue); - - if (*net_idx > 4095) - return false; - - if (!json_object_object_get_ex(jtemp, "key", &jvalue)) - return false; - - str = (char *)json_object_get_string(jvalue); - if (!str2hex(str, strlen(str), key, 16)) - return false; - - memcpy(&key_buf[0], &key[0], 16); - - /* Imported node shouldn't contain oldKey or keyRefresh */ - if (json_object_object_get_ex(jtemp, "oldKey", NULL)) - return false; - - if (json_object_object_get_ex(jtemp, "keyRefresh", NULL)) - return false; - - return true; -} - static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr, bool ivu, uint32_t iv_idx, uint8_t dev_key[16], uint16_t net_key_idx, uint8_t net_key[16]) @@ -1652,7 +1567,8 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data) } else if (req->type == REQUEST_TYPE_IMPORT) { node_ready_func_t cb = req->cb; - struct node_import_request *import_data = req->user_data; + struct node_import_request *import_req = req->user_data; + struct mesh_db_import *db_node = import_req->import; struct keyring_net_key net_key; if (!agent) { @@ -1664,32 +1580,32 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data) node->num_ele = num_ele; set_defaults(node); - if (node->seq_number != import_data->sequence) - node->seq_number = import_data->sequence; + if (node->seq_number != db_node->node->seq_number) + node->seq_number = db_node->node->seq_number; - memcpy(node->uuid, import_data->uuid, 16); + memcpy(node->uuid, import_req->uuid, 16); if (!create_node_config(node)) goto fail; - if (!add_local_node(node, import_data->unicast, false, - import_data->iv_update, import_data->iv_idx, - import_data->dev_key, import_data->net_idx, - import_data->net_key)) + if (!add_local_node(node, db_node->node->unicast, false, + db_node->iv_update, db_node->iv_index, + db_node->dev_key, db_node->net_idx, + db_node->net_key)) goto fail; - memcpy(net_key.old_key, import_data->net_key, 16); - net_key.net_idx = import_data->net_idx; + memcpy(net_key.old_key, db_node->net_key, 16); + net_key.net_idx = db_node->net_idx; net_key.phase = KEY_REFRESH_PHASE_NONE; - if (!keyring_put_remote_dev_key(node, import_data->unicast, - num_ele, import_data->dev_key)) + if (!keyring_put_remote_dev_key(node, db_node->node->unicast, + num_ele, db_node->dev_key)) goto fail; if (!keyring_put_net_key(node, PRIMARY_NET_IDX, &net_key)) goto fail; - cb(import_data->user_data, MESH_ERROR_NONE, node); + cb(import_req->user_data, MESH_ERROR_NONE, node); } else { /* Callback for create node request */ @@ -1749,11 +1665,10 @@ fail: cb(NULL, NULL); } else if (req->type == REQUEST_TYPE_IMPORT) { - struct node_import_request *import_data = - req->user_data; + struct node_import_request *import_req = req->user_data; node_ready_func_t cb = req->cb; - cb(import_data->user_data, MESH_ERROR_FAILED, NULL); + cb(import_req->user_data, MESH_ERROR_FAILED, NULL); } else { node_ready_func_t cb = req->cb; @@ -1820,58 +1735,29 @@ void node_join(const char *app_path, const char *sender, const uint8_t *uuid, } static bool node_import_full(const char *app_path, const char *sender, - void *json_data, const uint8_t *uuid, + struct mesh_db_import *db_node, + const uint8_t *uuid, node_ready_func_t cb, void *user_data) { return false; } static bool node_import_simplified(const char *app_path, const char *sender, - void *json_data, const uint8_t *uuid, + struct mesh_db_import *db_node, + const uint8_t *uuid, node_ready_func_t cb, void *user_data) { struct managed_obj_request *req = l_new(struct managed_obj_request, 1); - struct node_import_request *node = l_new(struct node_import_request, 1); - - json_object_object_foreach(json_data, key, val) { - - if (!strcmp(key, "deviceKey")) { - if (!parse_imported_device_key(val, node->dev_key)) { - l_error("Failed to parse imported device key"); - goto fail; - } - - } else if (!strcmp(key, "unicastAddress")) { - if (!parse_imported_unicast_addr(val, &node->unicast)) { - l_error("Failed to parse imported unicast"); - goto fail; - } + struct node_import_request *import_req = + l_new(struct node_import_request, 1); - } else if (!strcmp(key, "IVindex")) { - node->iv_idx = (uint32_t) json_object_get_int(val); - - } else if (!strcmp(key, "IVupdate")) { - node->iv_update = (bool) json_object_get_int(val); - - } else if (!strcmp(key, "netKeys")) { - if (!parse_imported_net_key(val, - node->net_key, &node->net_idx)) { - l_error("Failed to parse imported network key"); - goto fail; - } - - } else { - if (strcmp(key, "sequenceNumber")) - goto fail; - } - } - - parse_imported_sequence_nr(json_data, &node->sequence); - node->user_data = user_data; + l_debug(""); + import_req->user_data = user_data; + import_req->import = db_node; + memcpy(import_req->uuid, uuid, 16); - memcpy(node->uuid, uuid, 16); req->data = (void *) uuid; - req->user_data = node; + req->user_data = import_req; req->cb = cb; req->type = REQUEST_TYPE_IMPORT; @@ -1881,21 +1767,18 @@ static bool node_import_simplified(const char *app_path, const char *sender, get_managed_objects_cb, req, l_free); return true; - -fail: - json_object_put(json_data); - l_free(node); - return false; } -bool node_import(const char *app_path, const char *sender, void *json_data, +bool node_import(const char *app_path, const char *sender, void *import, const uint8_t *uuid, node_ready_func_t cb, void *user_data) { - if (!json_object_object_get_ex(json_data, "elements", NULL)) - return node_import_simplified(app_path, sender, json_data, - uuid, cb, user_data); + struct mesh_db_import *db_node = (struct mesh_db_import *)import; + + if (!db_node->node->elements) + return node_import_simplified(app_path, sender, db_node, uuid, + cb, user_data); else - return node_import_full(app_path, sender, json_data, uuid, + return node_import_full(app_path, sender, db_node, uuid, cb, user_data); } diff --git a/mesh/node.h b/mesh/node.h index 9559f9178..7f1093df7 100644 --- a/mesh/node.h +++ b/mesh/node.h @@ -26,6 +26,7 @@ struct mesh_agent; #define MIN_SEQ_TRIGGER 32 #define MIN_SEQ_CACHE (2*MIN_SEQ_TRIGGER) #define MIN_SEQ_CACHE_TIME (5*60) +#define DEFAULT_SEQUENCE_NUMBER 0 typedef void (*node_ready_func_t) (void *user_data, int status, struct mesh_node *node); @@ -91,7 +92,7 @@ void node_build_attach_reply(struct mesh_node *node, struct l_dbus_message *reply); void node_create(const char *app_path, const char *sender, const uint8_t *uuid, node_ready_func_t cb, void *user_data); -bool node_import(const char *app_path, const char *sender, void *jnode, +bool node_import(const char *app_path, const char *sender, void *import, const uint8_t *uuid, node_ready_func_t cb, void *user_data); void node_id_set(struct mesh_node *node, uint16_t node_id); uint16_t node_id_get(struct mesh_node *node); -- 2.20.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH BlueZ v3 3/3] mesh: Separate json type from the node.c file 2019-07-05 15:22 ` [PATCH BlueZ v3 3/3] mesh: Separate json type from the node.c file Jakub Witowski @ 2019-07-05 15:41 ` Michał Lowas-Rzechonek 0 siblings, 0 replies; 4+ messages in thread From: Michał Lowas-Rzechonek @ 2019-07-05 15:41 UTC (permalink / raw) To: Jakub Witowski; +Cc: linux-bluetooth, Inga Stotland On 07/05, Jakub Witowski wrote: > This creates intermediate layer between imported node data and parser. I don't think it's worth having a separate patch for this, please squash it with 2/3. > --- > mesh/mesh-db.c | 147 ++++++++++++++++++++++++++++++++++++- > mesh/mesh-db.h | 11 +++ > mesh/mesh.c | 31 +++++--- > mesh/node.c | 193 ++++++++++--------------------------------------- > mesh/node.h | 3 +- > 5 files changed, 215 insertions(+), 170 deletions(-) > > diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c > index e0a000261..0e8f40470 100644 > --- a/mesh/mesh-db.c > +++ b/mesh/mesh-db.c > @@ -31,7 +31,7 @@ > > #include "mesh/mesh-defs.h" > #include "mesh/util.h" > - > +#include "mesh/node.h" > #include "mesh/mesh-db.h" > > #define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095)) > @@ -253,6 +253,118 @@ static json_object *jarray_key_del(json_object *jarray, int16_t idx) > return jarray_new; > } > > +static bool parse_imported_unicast_addr(json_object *jobj, uint16_t *unicast) > +{ > + char *str = (char *)json_object_get_string(jobj); > + > + if (sscanf(str, "%04hx", unicast) != 1) > + return false; > + > + return true; > +} > + > +static bool parse_imported_net_key(json_object *jobj, uint8_t key_buf[16], > + uint16_t *net_idx) > +{ > + json_object *jtemp, *jvalue; > + char *str; > + uint8_t key[16]; > + > + if (json_object_get_type(jobj) != json_type_array) > + return false; > + > + jtemp = json_object_array_get_idx(jobj, 0); > + > + if (!json_object_object_get_ex(jtemp, "index", &jvalue)) > + return false; > + > + *net_idx = (uint16_t)json_object_get_int(jvalue); > + > + if (*net_idx > 4095) > + return false; > + > + if (!json_object_object_get_ex(jtemp, "key", &jvalue)) > + return false; > + > + str = (char *)json_object_get_string(jvalue); > + if (!str2hex(str, strlen(str), key, 16)) > + return false; > + > + memcpy(&key_buf[0], &key[0], 16); > + > + /* Imported node shouldn't contain oldKey or keyRefresh */ > + if (json_object_object_get_ex(jtemp, "oldKey", NULL)) > + return false; > + > + if (json_object_object_get_ex(jtemp, "keyRefresh", NULL)) > + return false; > + > + return true; > +} > + > +static uint32_t parse_imported_sequence(json_object *jobj, > + uint32_t default_seq_nr) > +{ > + json_object *jvalue; > + > + if (json_object_object_get_ex(jobj, "sequenceNumber", &jvalue)) > + return (uint32_t) json_object_get_int(jvalue); > + else > + return default_seq_nr; > +} > + > +static bool json_iter(json_object *jobj, struct mesh_db_import *db_node) > +{ > + bool dev_key = false, unicast = false; > + bool iv_index = false, net_key = false; > + > + json_object_object_foreach(jobj, key, val) { > + > + if (!strcmp(key, "deviceKey")) { > + > + dev_key = true; > + if (!mesh_db_read_device_key(jobj, db_node->dev_key)) { > + l_error("Failed to parse imported device key"); > + return false; > + } > + > + } else if (!strcmp(key, "unicastAddress")) { > + > + unicast = true; > + if (!parse_imported_unicast_addr(val, > + &db_node->node->unicast)) { > + l_error("Failed to parse imported unicast"); > + return false; > + } > + > + } else if (!strcmp(key, "IVindex")) { > + > + iv_index = true; > + if (!mesh_db_read_iv_index(jobj, &db_node->iv_index, > + &db_node->iv_update)) { > + l_error("Failed to parse iv_index"); > + return false; > + } > + > + } else if (!strcmp(key, "netKeys")) { > + > + net_key = true; > + if (!parse_imported_net_key(val, db_node->net_key, > + &db_node->net_idx)) { > + l_error("Failed to parse imported network key"); > + return false; > + } > + > + } else { > + if (strcmp(key, "sequenceNumber") && > + strcmp(key, "IVupdate")) > + return false; > + } > + } > + > + return dev_key && unicast && net_key && iv_index; > +} > + > bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update) > { > int tmp; > @@ -1438,7 +1550,8 @@ static void add_model(void *a, void *b) > } > > /* Add unprovisioned node (local) */ > -bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) { > +bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) > +{ > > struct mesh_db_modes *modes = &node->modes; > const struct l_queue_entry *entry; > @@ -1783,3 +1896,33 @@ bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr, > > return delete_model_property(jnode, addr, mod_id, vendor, "subscribe"); > } > + > + > + > +struct mesh_db_import *mesh_db_parse_import_data(const char *import_data) > +{ > + json_object *jobj = json_tokener_parse(import_data); > + struct mesh_db_import *db_node = l_new(struct mesh_db_import, 1); > + > + if (!jobj) > + goto fail; > + > + db_node->node = l_new(struct mesh_db_node, 1); > + > + if (!json_iter(jobj, db_node)) > + goto fail; > + > + db_node->node->seq_number = > + parse_imported_sequence(jobj, DEFAULT_SEQUENCE_NUMBER); > + > + return db_node; > +fail: > + if (jobj) > + json_object_put(jobj); > + > + if (db_node->node) > + l_free(db_node->node); > + > + l_free(db_node); > + return NULL; > +} > diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h > index da5efa12a..a227319ca 100644 > --- a/mesh/mesh-db.h > +++ b/mesh/mesh-db.h > @@ -16,6 +16,7 @@ > * Lesser General Public License for more details. > * > */ > +#include <json-c/json.h> > > struct mesh_db_sub { > bool virt; > @@ -93,6 +94,15 @@ struct mesh_db_prov { > uint8_t priv_key[32]; > }; > > +struct mesh_db_import { > + struct mesh_db_node *node; > + uint8_t dev_key[16]; > + uint8_t net_key[16]; > + uint16_t net_idx; > + uint32_t iv_index; > + bool iv_update; > +}; > + > typedef bool (*mesh_db_net_key_cb)(uint16_t idx, uint8_t key[16], > uint8_t new_key[16], int phase, void *user_data); > typedef bool (*mesh_db_app_key_cb)(uint16_t idx, uint16_t net_idx, > @@ -155,3 +165,4 @@ bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase); > bool mesh_db_write_address(json_object *jobj, uint16_t address); > 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); > +struct mesh_db_import *mesh_db_parse_import_data(const char *import_data); > diff --git a/mesh/mesh.c b/mesh/mesh.c > index b3def7817..6234121c9 100644 > --- a/mesh/mesh.c > +++ b/mesh/mesh.c > @@ -22,7 +22,6 @@ > #endif > > #define _GNU_SOURCE > -#include <json-c/json.h> > #include <string.h> > #include <ell/ell.h> > > @@ -36,6 +35,7 @@ > #include "mesh/error.h" > #include "mesh/agent.h" > #include "mesh/mesh.h" > +#include "mesh/mesh-db.h" > > /* > * The default values for mesh configuration. Can be > @@ -391,10 +391,10 @@ fail: > > static bool validate_data_type(const char *data_type) > { > - uint8_t len = sizeof(supported_import_data_types) / > - sizeof(supported_import_data_types[0]); > + uint8_t idx = 0; > + uint8_t len = L_ARRAY_SIZE(supported_import_data_types); > > - for (uint8_t idx = 0; idx < len; idx++) { > + for (idx = 0; idx < len; idx++) { > if (strcmp(data_type, supported_import_data_types[idx]) == 0) > return true; > } > @@ -624,10 +624,10 @@ static struct l_dbus_message *import_local_node_call(struct l_dbus *dbus, > const char *app_path, *sender; > struct l_dbus_message *pending_msg; > struct l_dbus_message_iter iter_uuid, iter_import_data; > + struct mesh_db_import *p_node; > const char *data_type, *import_data; > uint8_t *uuid; > uint32_t n; > - struct json_object *jnode; > > l_debug("Import local node request"); > > @@ -652,7 +652,11 @@ static struct l_dbus_message *import_local_node_call(struct l_dbus *dbus, > return dbus_error(msg, MESH_ERROR_INVALID_ARGS, > "Bad import_data"); > > - jnode = json_tokener_parse(import_data); > + p_node = mesh_db_parse_import_data(import_data); > + > + if (!p_node) > + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, > + "Failed to parse import_data"); > > sender = l_dbus_message_get_sender(msg); > pending_msg = l_dbus_message_ref(msg); > @@ -662,14 +666,17 @@ static struct l_dbus_message *import_local_node_call(struct l_dbus *dbus, > > l_queue_push_tail(pending_queue, pending_msg); > > - if (!node_import(app_path, sender, jnode, uuid, create_node_ready_cb, > - pending_msg)) { > - l_dbus_message_unref(msg); > - return dbus_error(msg, MESH_ERROR_INVALID_ARGS, > - "Node import failed"); > - } > + if (!node_import(app_path, sender, p_node, uuid, create_node_ready_cb, > + pending_msg)) > + goto fail; > > return NULL; > + > +fail: > + l_free(p_node); > + l_dbus_message_unref(msg); > + l_queue_remove(pending_queue, pending_msg); > + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, "Node import failed"); > } > > static void setup_network_interface(struct l_dbus_interface *iface) > diff --git a/mesh/node.c b/mesh/node.c > index 00c3270fd..db04c0c87 100644 > --- a/mesh/node.c > +++ b/mesh/node.c > @@ -26,8 +26,6 @@ > #include <sys/time.h> > > #include <ell/ell.h> > -#include <json-c/json.h> > -#include <stdio.h> > > #include "mesh/mesh-defs.h" > #include "mesh/mesh.h" > @@ -56,7 +54,6 @@ > #define DEFAULT_LOCATION 0x0000 > > #define DEFAULT_CRPL 10 > -#define DEFAULT_SEQUENCE_NUMBER 0 > > enum request_type { > REQUEST_TYPE_JOIN = 0, > @@ -119,13 +116,7 @@ struct managed_obj_request { > > struct node_import_request { > uint8_t uuid[16]; > - uint8_t dev_key[16]; > - uint8_t net_key[16]; > - uint16_t net_idx; > - uint16_t unicast; > - uint32_t iv_idx; > - bool iv_update; > - uint32_t sequence; > + struct mesh_db_import *import; > void *user_data; > }; > > @@ -885,8 +876,7 @@ element_done: > > #define MIN_COMPOSITION_LEN 16 > > -bool node_parse_composition(struct mesh_node *node, uint8_t *data, > - uint16_t len) > +bool node_parse_composition(struct mesh_node *node, uint8_t *data, uint16_t len) > { > struct node_composition *comp; > uint16_t features; > @@ -981,7 +971,7 @@ bool node_parse_composition(struct mesh_node *node, uint8_t *data, > vendor_id = l_get_le16(data); > mod_id |= (vendor_id << 16); > mod = mesh_model_vendor_new(ele->idx, vendor_id, > - mod_id); > + mod_id); > if (!mod) { > element_free(ele); > goto fail; > @@ -1012,6 +1002,7 @@ fail: > > return false; > } > + > static void attach_io(void *a, void *b) > { > struct mesh_node *node = a; > @@ -1400,82 +1391,6 @@ static bool get_app_properties(struct mesh_node *node, const char *path, > return true; > } > > -static bool parse_imported_unicast_addr(json_object *jobj, uint16_t *unicast) > -{ > - char *str; > - > - str = (char *)json_object_get_string(jobj); > - > - if (sscanf(str, "%04hx", unicast) != 1) > - return false; > - > - return true; > -} > - > -static bool parse_imported_device_key(json_object *jobj, uint8_t key_buf[16]) > -{ > - char *str; > - > - if (!key_buf) > - return false; > - > - str = (char *)json_object_get_string(jobj); > - > - if (!str2hex(str, strlen(str), key_buf, 16)) > - return false; > - > - return true; > -} > - > -static void parse_imported_sequence_nr(json_object *jobj, uint32_t *seq) > -{ > - json_object *jvalue; > - > - if (json_object_object_get_ex(jobj, "sequenceNumber", &jvalue)) > - *seq = (uint32_t) json_object_get_int(jvalue); > - else > - *seq = DEFAULT_SEQUENCE_NUMBER; > -} > - > -static bool parse_imported_net_key(json_object *jobj, uint8_t key_buf[16], > - uint16_t *net_idx) > -{ > - json_object *jtemp, *jvalue; > - char *str; > - uint8_t key[16]; > - > - if (json_object_get_type(jobj) != json_type_array) > - return false; > - > - jtemp = json_object_array_get_idx(jobj, 0); > - > - if (!json_object_object_get_ex(jtemp, "index", &jvalue)) > - return false; > - > - *net_idx = (uint16_t)json_object_get_int(jvalue); > - > - if (*net_idx > 4095) > - return false; > - > - if (!json_object_object_get_ex(jtemp, "key", &jvalue)) > - return false; > - > - str = (char *)json_object_get_string(jvalue); > - if (!str2hex(str, strlen(str), key, 16)) > - return false; > - > - memcpy(&key_buf[0], &key[0], 16); > - > - /* Imported node shouldn't contain oldKey or keyRefresh */ > - if (json_object_object_get_ex(jtemp, "oldKey", NULL)) > - return false; > - > - if (json_object_object_get_ex(jtemp, "keyRefresh", NULL)) > - return false; > - > - return true; > -} > - > static bool add_local_node(struct mesh_node *node, uint16_t unicast, bool kr, > bool ivu, uint32_t iv_idx, uint8_t dev_key[16], > uint16_t net_key_idx, uint8_t net_key[16]) > @@ -1652,7 +1567,8 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data) > } else if (req->type == REQUEST_TYPE_IMPORT) { > > node_ready_func_t cb = req->cb; > - struct node_import_request *import_data = req->user_data; > + struct node_import_request *import_req = req->user_data; > + struct mesh_db_import *db_node = import_req->import; > struct keyring_net_key net_key; > > if (!agent) { > @@ -1664,32 +1580,32 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data) > node->num_ele = num_ele; > set_defaults(node); > > - if (node->seq_number != import_data->sequence) > - node->seq_number = import_data->sequence; > + if (node->seq_number != db_node->node->seq_number) > + node->seq_number = db_node->node->seq_number; > > - memcpy(node->uuid, import_data->uuid, 16); > + memcpy(node->uuid, import_req->uuid, 16); > > if (!create_node_config(node)) > goto fail; > > - if (!add_local_node(node, import_data->unicast, false, > - import_data->iv_update, import_data->iv_idx, > - import_data->dev_key, import_data->net_idx, > - import_data->net_key)) > + if (!add_local_node(node, db_node->node->unicast, false, > + db_node->iv_update, db_node->iv_index, > + db_node->dev_key, db_node->net_idx, > + db_node->net_key)) > goto fail; > > - memcpy(net_key.old_key, import_data->net_key, 16); > - net_key.net_idx = import_data->net_idx; > + memcpy(net_key.old_key, db_node->net_key, 16); > + net_key.net_idx = db_node->net_idx; > net_key.phase = KEY_REFRESH_PHASE_NONE; > > - if (!keyring_put_remote_dev_key(node, import_data->unicast, > - num_ele, import_data->dev_key)) > + if (!keyring_put_remote_dev_key(node, db_node->node->unicast, > + num_ele, db_node->dev_key)) > goto fail; > > if (!keyring_put_net_key(node, PRIMARY_NET_IDX, &net_key)) > goto fail; > > - cb(import_data->user_data, MESH_ERROR_NONE, node); > + cb(import_req->user_data, MESH_ERROR_NONE, node); > > } else { > /* Callback for create node request */ > @@ -1749,11 +1665,10 @@ fail: > cb(NULL, NULL); > > } else if (req->type == REQUEST_TYPE_IMPORT) { > - struct node_import_request *import_data = > - req->user_data; > + struct node_import_request *import_req = req->user_data; > node_ready_func_t cb = req->cb; > > - cb(import_data->user_data, MESH_ERROR_FAILED, NULL); > + cb(import_req->user_data, MESH_ERROR_FAILED, NULL); > > } else { > node_ready_func_t cb = req->cb; > @@ -1820,58 +1735,29 @@ void node_join(const char *app_path, const char *sender, const uint8_t *uuid, > } > > static bool node_import_full(const char *app_path, const char *sender, > - void *json_data, const uint8_t *uuid, > + struct mesh_db_import *db_node, > + const uint8_t *uuid, > node_ready_func_t cb, void *user_data) > { > return false; > } > > static bool node_import_simplified(const char *app_path, const char *sender, > - void *json_data, const uint8_t *uuid, > + struct mesh_db_import *db_node, > + const uint8_t *uuid, > node_ready_func_t cb, void *user_data) > { > struct managed_obj_request *req = l_new(struct managed_obj_request, 1); > - struct node_import_request *node = l_new(struct node_import_request, 1); > - > - json_object_object_foreach(json_data, key, val) { > - > - if (!strcmp(key, "deviceKey")) { > - if (!parse_imported_device_key(val, node->dev_key)) { > - l_error("Failed to parse imported device key"); > - goto fail; > - } > - > - } else if (!strcmp(key, "unicastAddress")) { > - if (!parse_imported_unicast_addr(val, &node->unicast)) { > - l_error("Failed to parse imported unicast"); > - goto fail; > - } > + struct node_import_request *import_req = > + l_new(struct node_import_request, 1); > > - } else if (!strcmp(key, "IVindex")) { > - node->iv_idx = (uint32_t) json_object_get_int(val); > - > - } else if (!strcmp(key, "IVupdate")) { > - node->iv_update = (bool) json_object_get_int(val); > - > - } else if (!strcmp(key, "netKeys")) { > - if (!parse_imported_net_key(val, > - node->net_key, &node->net_idx)) { > - l_error("Failed to parse imported network key"); > - goto fail; > - } > - > - } else { > - if (strcmp(key, "sequenceNumber")) > - goto fail; > - } > - } > - > - parse_imported_sequence_nr(json_data, &node->sequence); > - node->user_data = user_data; > + l_debug(""); > + import_req->user_data = user_data; > + import_req->import = db_node; > + memcpy(import_req->uuid, uuid, 16); > > - memcpy(node->uuid, uuid, 16); > req->data = (void *) uuid; > - req->user_data = node; > + req->user_data = import_req; > req->cb = cb; > req->type = REQUEST_TYPE_IMPORT; > > @@ -1881,21 +1767,18 @@ static bool node_import_simplified(const char *app_path, const char *sender, > get_managed_objects_cb, > req, l_free); > return true; > - > -fail: > - json_object_put(json_data); > - l_free(node); > - return false; > } > > -bool node_import(const char *app_path, const char *sender, void *json_data, > +bool node_import(const char *app_path, const char *sender, void *import, > const uint8_t *uuid, node_ready_func_t cb, void *user_data) > { > - if (!json_object_object_get_ex(json_data, "elements", NULL)) > - return node_import_simplified(app_path, sender, json_data, > - uuid, cb, user_data); > + struct mesh_db_import *db_node = (struct mesh_db_import *)import; > + > + if (!db_node->node->elements) > + return node_import_simplified(app_path, sender, db_node, uuid, > + cb, user_data); > else > - return node_import_full(app_path, sender, json_data, uuid, > + return node_import_full(app_path, sender, db_node, uuid, > cb, user_data); > } > > diff --git a/mesh/node.h b/mesh/node.h > index 9559f9178..7f1093df7 100644 > --- a/mesh/node.h > +++ b/mesh/node.h > @@ -26,6 +26,7 @@ struct mesh_agent; > #define MIN_SEQ_TRIGGER 32 > #define MIN_SEQ_CACHE (2*MIN_SEQ_TRIGGER) > #define MIN_SEQ_CACHE_TIME (5*60) > +#define DEFAULT_SEQUENCE_NUMBER 0 > > typedef void (*node_ready_func_t) (void *user_data, int status, > struct mesh_node *node); > @@ -91,7 +92,7 @@ void node_build_attach_reply(struct mesh_node *node, > struct l_dbus_message *reply); > void node_create(const char *app_path, const char *sender, const uint8_t *uuid, > node_ready_func_t cb, void *user_data); > -bool node_import(const char *app_path, const char *sender, void *jnode, > +bool node_import(const char *app_path, const char *sender, void *import, > const uint8_t *uuid, node_ready_func_t cb, void *user_data); > void node_id_set(struct mesh_node *node, uint16_t node_id); > uint16_t node_id_get(struct mesh_node *node); > -- > 2.20.1 > -- Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com> Silvair http://silvair.com Jasnogórska 44, 31-358 Krakow, POLAND ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-07-05 15:42 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-07-05 15:22 [PATCH BlueZ v3 1/3] mesh: Add ImportLocalNode api documentation Jakub Witowski 2019-07-05 15:22 ` [PATCH BlueZ v3 2/3] mesh: Added ImportLocalNode call with its API Jakub Witowski 2019-07-05 15:22 ` [PATCH BlueZ v3 3/3] mesh: Separate json type from the node.c file Jakub Witowski 2019-07-05 15:41 ` Michał Lowas-Rzechonek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox