2019-07-09 10:16:03

by Jakub Witowski

[permalink] [raw]
Subject: [PATCH BlueZ v4 1/4] mesh: Add ImportLocalNode api documentation

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


2019-07-09 10:16:33

by Jakub Witowski

[permalink] [raw]
Subject: [PATCH BlueZ v4 3/4] mesh: Replace 'json_object' typedef with 'struct json_object'

From: Michał Lowas-Rzechonek <[email protected]>

Also, add a forward declaration for struct json_object in mesh-db, so
that we no longer need to include json-c headers in modules that don't
deal with JSON.
---
mesh/cfgmod-server.c | 2 -
mesh/mesh-db.c | 222 +++++++++++++++++++++----------------------
mesh/mesh-db.h | 74 ++++++++-------
mesh/model.c | 1 -
mesh/node.c | 1 -
mesh/storage.c | 34 +++----
6 files changed, 166 insertions(+), 168 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index a19ddc72e..baf707222 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -24,8 +24,6 @@
#include <sys/time.h>
#include <ell/ell.h>

-#include "json-c/json.h"
-
#include "mesh/mesh-defs.h"
#include "mesh/node.h"
#include "mesh/net.h"
diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index 543b8f0e7..f50c68120 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -36,9 +36,9 @@

#define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095))

-static bool get_int(json_object *jobj, const char *keyword, int *value)
+static bool get_int(struct json_object *jobj, const char *keyword, int *value)
{
- json_object *jvalue;
+ struct json_object *jvalue;

if (!json_object_object_get_ex(jobj, keyword, &jvalue))
return false;
@@ -50,10 +50,10 @@ static bool get_int(json_object *jobj, const char *keyword, int *value)
return true;
}

-static bool add_u64_value(json_object *jobject, const char *desc,
+static bool add_u64_value(struct json_object *jobject, const char *desc,
const uint8_t u64[8])
{
- json_object *jstring;
+ struct json_object *jstring;
char hexstr[17];

hex2str((uint8_t *) u64, 8, hexstr, 17);
@@ -65,10 +65,10 @@ static bool add_u64_value(json_object *jobject, const char *desc,
return true;
}

-static bool add_key_value(json_object *jobject, const char *desc,
+static bool add_key_value(struct json_object *jobject, const char *desc,
const uint8_t key[16])
{
- json_object *jstring;
+ struct json_object *jstring;
char hexstr[33];

hex2str((uint8_t *) key, 16, hexstr, 33);
@@ -80,9 +80,9 @@ static bool add_key_value(json_object *jobject, const char *desc,
return true;
}

-static int get_element_index(json_object *jnode, uint16_t ele_addr)
+static int get_element_index(struct json_object *jnode, uint16_t ele_addr)
{
- json_object *jvalue, *jelements;
+ struct json_object *jvalue, *jelements;
uint16_t addr, num_ele;
char *str;

@@ -104,10 +104,10 @@ static int get_element_index(json_object *jnode, uint16_t ele_addr)
return ele_addr - addr;
}

-static json_object *get_element_model(json_object *jnode, int ele_idx,
+static struct json_object *get_element_model(struct json_object *jnode, int ele_idx,
uint32_t mod_id, bool vendor)
{
- json_object *jelements, *jelement, *jmodels;
+ struct json_object *jelements, *jelement, *jmodels;
int i, num_mods;
size_t len;
char buf[9];
@@ -140,7 +140,7 @@ static json_object *get_element_model(json_object *jnode, int ele_idx,
}

for (i = 0; i < num_mods; ++i) {
- json_object *jmodel, *jvalue;
+ struct json_object *jmodel, *jvalue;
char *str;

jmodel = json_object_array_get_idx(jmodels, i);
@@ -158,12 +158,12 @@ static json_object *get_element_model(json_object *jnode, int ele_idx,
return NULL;
}

-static bool jarray_has_string(json_object *jarray, char *str, size_t len)
+static bool jarray_has_string(struct json_object *jarray, char *str, size_t len)
{
int i, sz = json_object_array_length(jarray);

for (i = 0; i < sz; ++i) {
- json_object *jentry;
+ struct json_object *jentry;
char *str_entry;

jentry = json_object_array_get_idx(jarray, i);
@@ -178,18 +178,18 @@ static bool jarray_has_string(json_object *jarray, char *str, size_t len)
return false;
}

-static json_object *jarray_string_del(json_object *jarray, char *str,
+static struct json_object *jarray_string_del(struct json_object *jarray, char *str,
size_t len)
{
int i, sz = json_object_array_length(jarray);
- json_object *jarray_new;
+ struct json_object *jarray_new;

jarray_new = json_object_new_array();
if (!jarray_new)
return NULL;

for (i = 0; i < sz; ++i) {
- json_object *jentry;
+ struct json_object *jentry;
char *str_entry;

jentry = json_object_array_get_idx(jarray, i);
@@ -204,12 +204,12 @@ static json_object *jarray_string_del(json_object *jarray, char *str,
return jarray_new;
}

-static json_object *get_key_object(json_object *jarray, uint16_t idx)
+static struct json_object *get_key_object(struct json_object *jarray, uint16_t idx)
{
int i, sz = json_object_array_length(jarray);

for (i = 0; i < sz; ++i) {
- json_object *jentry, *jvalue;
+ struct json_object *jentry, *jvalue;
uint32_t jidx;

jentry = json_object_array_get_idx(jarray, i);
@@ -225,9 +225,9 @@ static json_object *get_key_object(json_object *jarray, uint16_t idx)
return NULL;
}

-static json_object *jarray_key_del(json_object *jarray, int16_t idx)
+static struct json_object *jarray_key_del(struct json_object *jarray, int16_t idx)
{
- json_object *jarray_new;
+ struct json_object *jarray_new;
int i, sz = json_object_array_length(jarray);

jarray_new = json_object_new_array();
@@ -235,7 +235,7 @@ static json_object *jarray_key_del(json_object *jarray, int16_t idx)
return NULL;

for (i = 0; i < sz; ++i) {
- json_object *jentry, *jvalue;
+ struct json_object *jentry, *jvalue;

jentry = json_object_array_get_idx(jarray, i);

@@ -253,10 +253,10 @@ static json_object *jarray_key_del(json_object *jarray, int16_t idx)
return jarray_new;
}

-static bool mesh_db_read_unicast_address(json_object *jobj,
+static bool mesh_db_read_unicast_address(struct json_object *jobj,
uint16_t *unicast)
{
- json_object *jvalue;
+ struct json_object *jvalue;
char *str;

if (!json_object_object_get_ex(jobj, "unicastAddress", &jvalue))
@@ -270,9 +270,9 @@ static bool mesh_db_read_unicast_address(json_object *jobj,
}


-static bool mesh_db_read_seq_number(json_object *jobj, uint32_t *seq_number)
+static bool mesh_db_read_seq_number(struct json_object *jobj, uint32_t *seq_number)
{
- json_object *jvalue;
+ struct json_object *jvalue;

if (!json_object_object_get_ex(jobj, "sequenceNumber", &jvalue))
return false;
@@ -281,7 +281,7 @@ static bool mesh_db_read_seq_number(json_object *jobj, uint32_t *seq_number)
return true;
}

-bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
+bool mesh_db_read_iv_index(struct json_object *jobj, uint32_t *idx, bool *update)
{
int tmp;

@@ -299,9 +299,9 @@ bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
return true;
}

-bool mesh_db_read_token(json_object *jobj, uint8_t token[8])
+bool mesh_db_read_token(struct json_object *jobj, uint8_t token[8])
{
- json_object *jvalue;
+ struct json_object *jvalue;
char *str;

if (!token)
@@ -317,9 +317,9 @@ bool mesh_db_read_token(json_object *jobj, uint8_t token[8])
return true;
}

-bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16])
+bool mesh_db_read_device_key(struct json_object *jobj, uint8_t key_buf[16])
{
- json_object *jvalue;
+ struct json_object *jvalue;
char *str;

if (!key_buf)
@@ -335,10 +335,10 @@ bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16])
return true;
}

-bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
+bool mesh_db_read_app_keys(struct json_object *jobj, mesh_db_app_key_cb cb,
void *user_data)
{
- json_object *jarray;
+ struct json_object *jarray;
int len;
int i;

@@ -354,7 +354,7 @@ bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
len = json_object_array_length(jarray);

for (i = 0; i < len; ++i) {
- json_object *jtemp, *jvalue;
+ struct json_object *jtemp, *jvalue;
int app_idx, net_idx;
bool key_refresh = false;
char *str;
@@ -397,10 +397,10 @@ bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
return true;
}

-bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
+bool mesh_db_read_net_keys(struct json_object *jobj, mesh_db_net_key_cb cb,
void *user_data)
{
- json_object *jarray;
+ struct json_object *jarray;
int len;
int i;

@@ -416,7 +416,7 @@ bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
len = json_object_array_length(jarray);

for (i = 0; i < len; ++i) {
- json_object *jtemp, *jvalue;
+ struct json_object *jtemp, *jvalue;
int idx;
char *str;
bool key_refresh = false;
@@ -460,10 +460,10 @@ bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
return true;
}

-bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
+bool mesh_db_net_key_add(struct json_object *jobj, uint16_t idx,
const uint8_t key[16])
{
- json_object *jarray = NULL, *jentry = NULL, *jstring;
+ struct json_object *jarray = NULL, *jentry = NULL, *jstring;
char buf[5];

json_object_object_get_ex(jobj, "netKeys", &jarray);
@@ -508,10 +508,10 @@ fail:
return false;
}

-bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
+bool mesh_db_net_key_update(struct json_object *jobj, uint16_t idx,
const uint8_t key[16])
{
- json_object *jarray, *jentry, *jstring;
+ struct json_object *jarray, *jentry, *jstring;
const char *str;

if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
@@ -539,9 +539,9 @@ bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
return true;
}

-bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
+bool mesh_db_net_key_del(struct json_object *jobj, uint16_t idx)
{
- json_object *jarray, *jarray_new;
+ struct json_object *jarray, *jarray_new;

if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
return true;
@@ -570,20 +570,20 @@ bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
return true;
}

-bool mesh_db_write_device_key(json_object *jnode, uint8_t *key)
+bool mesh_db_write_device_key(struct json_object *jnode, uint8_t *key)
{
return add_key_value(jnode, "deviceKey", key);
}

-bool mesh_db_write_token(json_object *jnode, uint8_t *token)
+bool mesh_db_write_token(struct json_object *jnode, uint8_t *token)
{
return add_u64_value(jnode, "token", token);
}

-bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
+bool mesh_db_app_key_add(struct json_object *jobj, uint16_t net_idx, uint16_t app_idx,
const uint8_t key[16])
{
- json_object *jarray = NULL, *jentry = NULL, *jstring = NULL;
+ struct json_object *jarray = NULL, *jentry = NULL, *jstring = NULL;
char buf[5];

json_object_object_get_ex(jobj, "appKeys", &jarray);
@@ -633,10 +633,10 @@ fail:
return false;
}

-bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
+bool mesh_db_app_key_update(struct json_object *jobj, uint16_t app_idx,
const uint8_t key[16])
{
- json_object *jarray, *jentry = NULL, *jstring = NULL;
+ struct json_object *jarray, *jentry = NULL, *jstring = NULL;
const char *str;

if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
@@ -658,9 +658,9 @@ bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
return add_key_value(jentry, "key", key);
}

-bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
+bool mesh_db_app_key_del(struct json_object *jobj, uint16_t net_idx, uint16_t idx)
{
- json_object *jarray, *jarray_new;
+ struct json_object *jarray, *jarray_new;

if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
return true;
@@ -689,10 +689,10 @@ bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
return true;
}

-bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
+bool mesh_db_model_binding_add(struct json_object *jnode, uint8_t ele_idx, bool vendor,
uint32_t mod_id, uint16_t app_idx)
{
- json_object *jmodel, *jstring, *jarray = NULL;
+ struct json_object *jmodel, *jstring, *jarray = NULL;
char buf[5];

jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
@@ -723,10 +723,10 @@ bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
return true;
}

-bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
+bool mesh_db_model_binding_del(struct json_object *jnode, uint8_t ele_idx, bool vendor,
uint32_t mod_id, uint16_t app_idx)
{
- json_object *jmodel, *jarray, *jarray_new;
+ struct json_object *jmodel, *jarray, *jarray_new;
char buf[5];

jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
@@ -779,7 +779,7 @@ static void free_element(void *data)
l_free(ele);
}

-static bool parse_bindings(json_object *jbindings, struct mesh_db_model *mod)
+static bool parse_bindings(struct json_object *jbindings, struct mesh_db_model *mod)
{
int cnt;
int i;
@@ -798,7 +798,7 @@ static bool parse_bindings(json_object *jbindings, struct mesh_db_model *mod)

for (i = 0; i < cnt; ++i) {
int idx;
- json_object *jvalue;
+ struct json_object *jvalue;

jvalue = json_object_array_get_idx(jbindings, i);
if (!jvalue)
@@ -814,7 +814,7 @@ static bool parse_bindings(json_object *jbindings, struct mesh_db_model *mod)
return true;
}

-static bool get_key_index(json_object *jobj, const char *keyword,
+static bool get_key_index(struct json_object *jobj, const char *keyword,
uint16_t *index)
{
int idx;
@@ -829,9 +829,9 @@ static bool get_key_index(json_object *jobj, const char *keyword,
return true;
}

-static struct mesh_db_pub *parse_model_publication(json_object *jpub)
+static struct mesh_db_pub *parse_model_publication(struct json_object *jpub)
{
- json_object *jvalue;
+ struct json_object *jvalue;
struct mesh_db_pub *pub;
int len, value;
char *str;
@@ -890,7 +890,7 @@ fail:
return NULL;
}

-static bool parse_model_subscriptions(json_object *jsubs,
+static bool parse_model_subscriptions(struct json_object *jsubs,
struct mesh_db_model *mod)
{
struct mesh_db_sub *subs;
@@ -909,7 +909,7 @@ static bool parse_model_subscriptions(json_object *jsubs,
for (i = 0; i < cnt; ++i) {
char *str;
int len;
- json_object *jvalue;
+ struct json_object *jvalue;

jvalue = json_object_array_get_idx(jsubs, i);
if (!jvalue)
@@ -942,7 +942,7 @@ fail:
return false;
}

-static bool parse_models(json_object *jmodels, struct mesh_db_element *ele)
+static bool parse_models(struct json_object *jmodels, struct mesh_db_element *ele)
{
int i, num_models;

@@ -951,7 +951,7 @@ static bool parse_models(json_object *jmodels, struct mesh_db_element *ele)
return true;

for (i = 0; i < num_models; ++i) {
- json_object *jmodel, *jarray, *jvalue;
+ struct json_object *jmodel, *jarray, *jvalue;
struct mesh_db_model *mod;
uint32_t id;
int len;
@@ -1016,7 +1016,7 @@ fail:
return false;
}

-static bool parse_elements(json_object *jelements, struct mesh_db_node *node)
+static bool parse_elements(struct json_object *jelements, struct mesh_db_node *node)
{
int i, num_ele;

@@ -1031,9 +1031,9 @@ static bool parse_elements(json_object *jelements, struct mesh_db_node *node)
node->elements = l_queue_new();

for (i = 0; i < num_ele; ++i) {
- json_object *jelement;
- json_object *jmodels;
- json_object *jvalue;
+ struct json_object *jelement;
+ struct json_object *jmodels;
+ struct json_object *jvalue;
struct mesh_db_element *ele;
int index;
char *str;
@@ -1075,7 +1075,7 @@ fail:
return false;
}

-static int get_mode(json_object *jvalue)
+static int get_mode(struct json_object *jvalue)
{
const char *str;

@@ -1095,9 +1095,9 @@ static int get_mode(json_object *jvalue)
return 0xffffffff;
}

-static void parse_features(json_object *jconfig, struct mesh_db_node *node)
+static void parse_features(struct json_object *jconfig, struct mesh_db_node *node)
{
- json_object *jvalue, *jrelay;
+ struct json_object *jvalue, *jrelay;
int mode, count;
uint16_t interval;

@@ -1152,9 +1152,9 @@ static void parse_features(json_object *jconfig, struct mesh_db_node *node)
node->modes.relay.interval = interval;
}

-static bool parse_composition(json_object *jcomp, struct mesh_db_node *node)
+static bool parse_composition(struct json_object *jcomp, struct mesh_db_node *node)
{
- json_object *jvalue;
+ struct json_object *jvalue;
char *str;

/* All the fields in node composition are mandatory */
@@ -1189,10 +1189,10 @@ static bool parse_composition(json_object *jcomp, struct mesh_db_node *node)
return true;
}

-bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
+bool mesh_db_read_node(struct json_object *jnode, mesh_db_node_cb cb, void *user_data)
{
struct mesh_db_node node;
- json_object *jvalue;
+ struct json_object *jvalue;

if (!jnode)
return false;
@@ -1233,10 +1233,10 @@ bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
return cb(&node, user_data);
}

-bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
+bool mesh_db_write_uint16_hex(struct json_object *jobj, const char *desc,
uint16_t value)
{
- json_object *jstring;
+ struct json_object *jstring;
char buf[5];

if (!jobj)
@@ -1251,10 +1251,10 @@ bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
return true;
}

-bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
+bool mesh_db_write_uint32_hex(struct json_object *jobj, const char *desc,
uint32_t value)
{
- json_object *jstring;
+ struct json_object *jstring;
char buf[9];

if (!jobj)
@@ -1269,9 +1269,9 @@ bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
return true;
}

-bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
+bool mesh_db_write_int(struct json_object *jobj, const char *keyword, int value)
{
- json_object *jvalue;
+ struct json_object *jvalue;

if (!jobj)
return false;
@@ -1286,9 +1286,9 @@ bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
return true;
}

-bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value)
+bool mesh_db_write_bool(struct json_object *jobj, const char *keyword, bool value)
{
- json_object *jvalue;
+ struct json_object *jvalue;

if (!jobj)
return false;
@@ -1315,9 +1315,9 @@ static const char *mode_to_string(int mode)
}
}

-bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
+bool mesh_db_write_mode(struct json_object *jobj, const char *keyword, int value)
{
- json_object *jstring;
+ struct json_object *jstring;

if (!jobj)
return false;
@@ -1332,10 +1332,10 @@ bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
return true;
}

-bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
+bool mesh_db_write_relay_mode(struct json_object *jnode, uint8_t mode, uint8_t count,
uint16_t interval)
{
- json_object *jrelay;
+ struct json_object *jrelay;

if (!jnode)
return false;
@@ -1363,10 +1363,10 @@ fail:
return false;
}

-bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
+bool mesh_db_read_net_transmit(struct json_object *jobj, uint8_t *cnt,
uint16_t *interval)
{
- json_object *jretransmit, *jvalue;
+ struct json_object *jretransmit, *jvalue;

if (!jobj)
return false;
@@ -1387,10 +1387,10 @@ bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
return true;
}

-bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
+bool mesh_db_write_net_transmit(struct json_object *jobj, uint8_t cnt,
uint16_t interval)
{
- json_object *jretransmit;
+ struct json_object *jretransmit;

if (!jobj)
return false;
@@ -1416,7 +1416,7 @@ fail:

}

-bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
+bool mesh_db_write_iv_index(struct json_object *jobj, uint32_t idx, bool update)
{
int tmp = update ? 1 : 0;

@@ -1432,7 +1432,7 @@ bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
return true;
}

-void mesh_db_remove_property(json_object *jobj, const char *desc)
+void mesh_db_remove_property(struct json_object *jobj, const char *desc)
{
if (jobj)
json_object_object_del(jobj, desc);
@@ -1441,7 +1441,7 @@ void mesh_db_remove_property(json_object *jobj, const char *desc)
static void add_model(void *a, void *b)
{
struct mesh_db_model *mod = a;
- json_object *jmodels = b, *jmodel;
+ struct json_object *jmodels = b, *jmodel;

jmodel = json_object_new_object();
if (!jmodel)
@@ -1457,12 +1457,12 @@ 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(struct json_object *jnode, struct mesh_db_node *node)
{

struct mesh_db_modes *modes = &node->modes;
const struct l_queue_entry *entry;
- json_object *jelements;
+ struct json_object *jelements;

if (!jnode)
return false;
@@ -1516,7 +1516,7 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node)

for (; entry; entry = entry->next) {
struct mesh_db_element *ele = entry->data;
- json_object *jelement, *jmodels;
+ struct json_object *jelement, *jmodels;

jelement = json_object_new_object();

@@ -1548,9 +1548,9 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node)
return true;
}

-static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
+static void finish_key_refresh(struct json_object *jobj, uint16_t net_idx)
{
- json_object *jarray;
+ struct json_object *jarray;
int i, len;

/* Clean up all the bound appkeys */
@@ -1560,7 +1560,7 @@ static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
len = json_object_array_length(jarray);

for (i = 0; i < len; ++i) {
- json_object *jentry;
+ struct json_object *jentry;
uint16_t idx;

jentry = json_object_array_get_idx(jarray, i);
@@ -1579,9 +1579,9 @@ static void finish_key_refresh(json_object *jobj, uint16_t net_idx)

}

-bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
+bool mesh_db_net_key_set_phase(struct json_object *jobj, uint16_t idx, uint8_t phase)
{
- json_object *jarray, *jentry = NULL;
+ struct json_object *jarray, *jentry = NULL;

if (!jobj)
return false;
@@ -1604,10 +1604,10 @@ bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
return true;
}

-bool mesh_db_model_pub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
+bool mesh_db_model_pub_add(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
bool vendor, struct mesh_db_pub *pub)
{
- json_object *jmodel, *jpub, *jretransmit;
+ struct json_object *jmodel, *jpub, *jretransmit;
bool res;
int ele_idx;

@@ -1667,10 +1667,10 @@ fail:
return false;
}

-static bool delete_model_property(json_object *jnode, uint16_t addr,
+static bool delete_model_property(struct json_object *jnode, uint16_t addr,
uint32_t mod_id, bool vendor, const char *keyword)
{
- json_object *jmodel;
+ struct json_object *jmodel;
int ele_idx;

ele_idx = get_element_index(jnode, addr);
@@ -1686,7 +1686,7 @@ static bool delete_model_property(json_object *jnode, uint16_t addr,
return true;
}

-bool mesh_db_model_pub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
+bool mesh_db_model_pub_del(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
bool vendor)
{
if (!jnode)
@@ -1695,10 +1695,10 @@ bool mesh_db_model_pub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
return delete_model_property(jnode, addr, mod_id, vendor, "publish");
}

-bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
+bool mesh_db_model_sub_add(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
bool vendor, struct mesh_db_sub *sub)
{
- json_object *jmodel, *jstring, *jarray = NULL;
+ struct json_object *jmodel, *jstring, *jarray = NULL;
int ele_idx, len;
char buf[33];

@@ -1743,10 +1743,10 @@ bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
return true;
}

-bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr,
+bool mesh_db_model_sub_del(struct json_object *jnode, uint16_t addr,
uint32_t mod_id, bool vendor, struct mesh_db_sub *sub)
{
- json_object *jmodel, *jarray, *jarray_new;
+ struct json_object *jmodel, *jarray, *jarray_new;
char buf[33];
int len, ele_idx;

@@ -1795,7 +1795,7 @@ bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr,
return true;
}

-bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr,
+bool mesh_db_model_sub_del_all(struct json_object *jnode, uint16_t addr,
uint32_t mod_id, bool vendor)
{
if (!jnode)
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index da5efa12a..0c09238ed 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -17,6 +17,8 @@
*
*/

+struct json_object;
+
struct mesh_db_sub {
bool virt;
union {
@@ -99,59 +101,59 @@ typedef bool (*mesh_db_app_key_cb)(uint16_t idx, uint16_t net_idx,
uint8_t key[16], uint8_t new_key[16], void *user_data);
typedef bool (*mesh_db_node_cb)(struct mesh_db_node *node, void *user_data);

-bool mesh_db_read_node(json_object *jobj, mesh_db_node_cb cb, void *user_data);
-bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node);
-bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update);
-bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16]);
-bool mesh_db_read_token(json_object *jobj, uint8_t token[8]);
-bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
+bool mesh_db_read_node(struct json_object *jobj, mesh_db_node_cb cb, void *user_data);
+bool mesh_db_add_node(struct json_object *jnode, struct mesh_db_node *node);
+bool mesh_db_read_iv_index(struct json_object *jobj, uint32_t *idx, bool *update);
+bool mesh_db_read_device_key(struct json_object *jobj, uint8_t key_buf[16]);
+bool mesh_db_read_token(struct json_object *jobj, uint8_t token[8]);
+bool mesh_db_read_net_transmit(struct json_object *jobj, uint8_t *cnt,
uint16_t *interval);
-bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
+bool mesh_db_write_net_transmit(struct json_object *jobj, uint8_t cnt,
uint16_t interval);
-bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
+bool mesh_db_read_net_keys(struct json_object *jobj, mesh_db_net_key_cb cb,
void *user_data);
-bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
+bool mesh_db_read_app_keys(struct json_object *jobj, mesh_db_app_key_cb cb,
void *user_data);
-bool mesh_db_write_device_key(json_object *jobj, uint8_t *key);
-bool mesh_db_write_token(json_object *jobj, uint8_t *token);
-bool mesh_db_write_network_key(json_object *jobj, uint16_t idx, uint8_t *key,
+bool mesh_db_write_device_key(struct json_object *jobj, uint8_t *key);
+bool mesh_db_write_token(struct json_object *jobj, uint8_t *token);
+bool mesh_db_write_network_key(struct json_object *jobj, uint16_t idx, uint8_t *key,
uint8_t *new_key, int phase);
-bool mesh_db_write_app_key(json_object *jobj, uint16_t net_idx,
+bool mesh_db_write_app_key(struct json_object *jobj, uint16_t net_idx,
uint16_t app_idx, uint8_t *key, uint8_t *new_key);
-bool mesh_db_write_int(json_object *jobj, const char *keyword, int value);
-bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
+bool mesh_db_write_int(struct json_object *jobj, const char *keyword, int value);
+bool mesh_db_write_uint16_hex(struct json_object *jobj, const char *desc,
uint16_t value);
-bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
+bool mesh_db_write_uint32_hex(struct json_object *jobj, const char *desc,
uint32_t value);
-bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value);
-bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
+bool mesh_db_write_bool(struct json_object *jobj, const char *keyword, bool value);
+bool mesh_db_write_relay_mode(struct json_object *jnode, uint8_t mode, uint8_t count,
uint16_t interval);
-bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value);
-bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
+bool mesh_db_write_mode(struct json_object *jobj, const char *keyword, int value);
+bool mesh_db_model_binding_add(struct json_object *jnode, uint8_t ele_idx, bool vendor,
uint32_t mod_id, uint16_t app_idx);
-bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
+bool mesh_db_model_binding_del(struct json_object *jnode, uint8_t ele_idx, bool vendor,
uint32_t mod_id, uint16_t app_idx);
-bool mesh_db_model_pub_add(json_object *jnode, uint16_t ele_addr,
+bool mesh_db_model_pub_add(struct json_object *jnode, uint16_t ele_addr,
uint32_t mod_id, bool vendor, struct mesh_db_pub *pub);
-bool mesh_db_model_pub_del(json_object *jnode, uint16_t ele_addr,
+bool mesh_db_model_pub_del(struct json_object *jnode, uint16_t ele_addr,
uint32_t mod_id, bool vendor);
-bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
+bool mesh_db_model_sub_add(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
bool vendor, struct mesh_db_sub *sub);
-bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
+bool mesh_db_model_sub_del(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
bool vendor, struct mesh_db_sub *sub);
-bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr,
+bool mesh_db_model_sub_del_all(struct json_object *jnode, uint16_t addr,
uint32_t mod_id, bool vendor);
-bool mesh_db_app_key_add(json_object *jnode, uint16_t net_idx, uint16_t app_idx,
+bool mesh_db_app_key_add(struct json_object *jnode, uint16_t net_idx, uint16_t app_idx,
const uint8_t key[16]);
-bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
+bool mesh_db_app_key_update(struct json_object *jobj, uint16_t app_idx,
const uint8_t key[16]);
-bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx);
-bool mesh_db_net_key_add(json_object *jobj, uint16_t net_idx,
+bool mesh_db_app_key_del(struct json_object *jobj, uint16_t net_idx, uint16_t idx);
+bool mesh_db_net_key_add(struct json_object *jobj, uint16_t net_idx,
const uint8_t key[16]);
-bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
+bool mesh_db_net_key_update(struct json_object *jobj, uint16_t idx,
const uint8_t key[16]);
-bool mesh_db_net_key_del(json_object *jobj, uint16_t net_idx);
-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);
+bool mesh_db_net_key_del(struct json_object *jobj, uint16_t net_idx);
+bool mesh_db_net_key_set_phase(struct json_object *jobj, uint16_t idx, uint8_t phase);
+bool mesh_db_write_address(struct json_object *jobj, uint16_t address);
+bool mesh_db_write_iv_index(struct json_object *jobj, uint32_t idx, bool update);
+void mesh_db_remove_property(struct json_object *jobj, const char *desc);
diff --git a/mesh/model.c b/mesh/model.c
index e08f95b71..f59d709d5 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -23,7 +23,6 @@

#include <sys/time.h>
#include <ell/ell.h>
-#include <json-c/json.h>

#include "mesh/mesh-defs.h"

diff --git a/mesh/node.c b/mesh/node.c
index 1f781cfe9..8533aaa1e 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -26,7 +26,6 @@
#include <sys/time.h>

#include <ell/ell.h>
-#include <json-c/json.h>

#include "mesh/mesh-defs.h"
#include "mesh/mesh.h"
diff --git a/mesh/storage.c b/mesh/storage.c
index 0f2b77fde..f910bd373 100644
--- a/mesh/storage.c
+++ b/mesh/storage.c
@@ -42,7 +42,7 @@
#include "mesh/storage.h"

struct write_info {
- json_object *jnode;
+ struct json_object *jnode;
const char *node_path;
void *user_data;
mesh_status_func_t cb;
@@ -126,7 +126,7 @@ static bool read_app_keys_cb(uint16_t net_idx, uint16_t app_idx, uint8_t *key,
return appkey_key_init(net, net_idx, app_idx, key, new_key);
}

-static bool parse_node(struct mesh_node *node, json_object *jnode)
+static bool parse_node(struct mesh_node *node, struct json_object *jnode)
{
bool bvalue;
uint32_t iv_index;
@@ -169,7 +169,7 @@ static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
char *str;
struct stat st;
ssize_t sz;
- json_object *jnode = NULL;
+ struct json_object *jnode = NULL;
bool result = false;
struct mesh_node *node;

@@ -222,7 +222,7 @@ done:

bool storage_set_ttl(struct mesh_node *node, uint8_t ttl)
{
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);

if (!mesh_db_write_int(jnode, "defaultTTL", ttl))
return false;
@@ -234,7 +234,7 @@ bool storage_set_ttl(struct mesh_node *node, uint8_t ttl)
bool storage_set_relay(struct mesh_node *node, bool enable,
uint8_t count, uint8_t interval)
{
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);

if (!mesh_db_write_relay_mode(jnode, enable, count, interval))
return false;
@@ -246,7 +246,7 @@ bool storage_set_relay(struct mesh_node *node, bool enable,
bool storage_set_transmit_params(struct mesh_node *node, uint8_t count,
uint8_t interval)
{
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);

if (!mesh_db_write_net_transmit(jnode, count, interval))
return false;
@@ -258,7 +258,7 @@ bool storage_set_transmit_params(struct mesh_node *node, uint8_t count,
bool storage_set_mode(struct mesh_node *node, uint8_t mode,
const char *mode_name)
{
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);

if (!mesh_db_write_mode(jnode, mode_name, mode))
return false;
@@ -270,7 +270,7 @@ bool storage_set_mode(struct mesh_node *node, uint8_t mode,
bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t mod_id,
uint16_t app_idx, bool unbind)
{
- json_object *jnode;
+ struct json_object *jnode;
int ele_idx;
bool stored, is_vendor = (mod_id > 0xffff);

@@ -296,7 +296,7 @@ bool storage_model_bind(struct mesh_node *node, uint16_t addr, uint32_t mod_id,
bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
uint16_t app_idx, const uint8_t key[16], bool update)
{
- json_object *jnode;
+ struct json_object *jnode;
struct mesh_node *node = mesh_net_node_get(net);
bool stored;

@@ -318,7 +318,7 @@ bool storage_app_key_add(struct mesh_net *net, uint16_t net_idx,
bool storage_app_key_del(struct mesh_net *net, uint16_t net_idx,
uint16_t app_idx)
{
- json_object *jnode;
+ struct json_object *jnode;
struct mesh_node *node = mesh_net_node_get(net);

jnode = node_jconfig_get(node);
@@ -336,7 +336,7 @@ bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
const uint8_t key[16], bool update)
{
struct mesh_node *node = mesh_net_node_get(net);
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);
bool stored;

if (!update)
@@ -353,7 +353,7 @@ bool storage_net_key_add(struct mesh_net *net, uint16_t net_idx,
bool storage_net_key_del(struct mesh_net *net, uint16_t net_idx)
{
struct mesh_node *node = mesh_net_node_get(net);
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);

if (!mesh_db_net_key_del(jnode, net_idx))
return false;
@@ -366,7 +366,7 @@ bool storage_set_iv_index(struct mesh_net *net, uint32_t iv_index,
bool update)
{
struct mesh_node *node = mesh_net_node_get(net);
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);

if (!mesh_db_write_iv_index(jnode, iv_index, update))
return false;
@@ -379,7 +379,7 @@ bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
uint8_t phase)
{
struct mesh_node *node = mesh_net_node_get(net);
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);

if (!mesh_db_net_key_set_phase(jnode, net_idx, phase))
return false;
@@ -391,7 +391,7 @@ bool storage_set_key_refresh_phase(struct mesh_net *net, uint16_t net_idx,
bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq)
{
struct mesh_node *node = mesh_net_node_get(net);
- json_object *jnode = node_jconfig_get(node);
+ struct json_object *jnode = node_jconfig_get(node);

if (!mesh_db_write_int(jnode, "sequenceNumber", seq))
return false;
@@ -400,7 +400,7 @@ bool storage_write_sequence_number(struct mesh_net *net, uint32_t seq)
return true;
}

-static bool save_config(json_object *jnode, const char *config_name)
+static bool save_config(struct json_object *jnode, const char *config_name)
{
FILE *outfile;
const char *str;
@@ -566,7 +566,7 @@ bool storage_create_node_config(struct mesh_node *node, void *data)
struct mesh_db_node *db_node = data;
char uuid[33];
char name_buf[PATH_MAX];
- json_object *jnode;
+ struct json_object *jnode;
size_t max_len = strlen(cfg_name) + strlen(bak_ext);

if (!storage_dir)
--
2.20.1

2019-07-09 10:17:46

by Jakub Witowski

[permalink] [raw]
Subject: [PATCH BlueZ v4 4/4] mesh: Added ImportLocalNode call with its API

This implements ImportLocalNode() method on org.bluez.mesh.Network1
interface. Invoking this method creates a self-provisioned node based on
passed JSON definition.
---
mesh/cfgmod-server.c | 2 +-
mesh/mesh-db.c | 162 ++++++++++++++++++++++++++++++++++---------
mesh/mesh-db.h | 62 +++++++++++------
mesh/mesh-defs.h | 1 +
mesh/mesh.c | 91 +++++++++++++++++++++++-
mesh/model.c | 5 +-
mesh/node.c | 128 ++++++++++++++++++++++++++++------
mesh/node.h | 6 ++
8 files changed, 377 insertions(+), 80 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index baf707222..eae53e076 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -1214,7 +1214,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst,
gettimeofday(&time_now, NULL);
time_now.tv_sec -= hb->sub_start;

- if (time_now.tv_sec >= (long int) hb->sub_period)
+ if (time_now.tv_sec >= (long) hb->sub_period)
time_now.tv_sec = 0;
else
time_now.tv_sec = hb->sub_period - time_now.tv_sec;
diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index f50c68120..1c2b1d019 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -31,6 +31,7 @@

#include "mesh/mesh-defs.h"
#include "mesh/util.h"
+#include "mesh/net.h"

#include "mesh/mesh-db.h"

@@ -104,8 +105,8 @@ static int get_element_index(struct json_object *jnode, uint16_t ele_addr)
return ele_addr - addr;
}

-static struct json_object *get_element_model(struct json_object *jnode, int ele_idx,
- uint32_t mod_id, bool vendor)
+static struct json_object *get_element_model(struct json_object *jnode,
+ int ele_idx, uint32_t mod_id, bool vendor)
{
struct json_object *jelements, *jelement, *jmodels;
int i, num_mods;
@@ -178,8 +179,8 @@ static bool jarray_has_string(struct json_object *jarray, char *str, size_t len)
return false;
}

-static struct json_object *jarray_string_del(struct json_object *jarray, char *str,
- size_t len)
+static struct json_object *jarray_string_del(struct json_object *jarray,
+ char *str, size_t len)
{
int i, sz = json_object_array_length(jarray);
struct json_object *jarray_new;
@@ -204,7 +205,8 @@ static struct json_object *jarray_string_del(struct json_object *jarray, char *s
return jarray_new;
}

-static struct json_object *get_key_object(struct json_object *jarray, uint16_t idx)
+static struct json_object *get_key_object(struct json_object *jarray,
+ uint16_t idx)
{
int i, sz = json_object_array_length(jarray);

@@ -225,7 +227,8 @@ static struct json_object *get_key_object(struct json_object *jarray, uint16_t i
return NULL;
}

-static struct json_object *jarray_key_del(struct json_object *jarray, int16_t idx)
+static struct json_object *jarray_key_del(struct json_object *jarray,
+ int16_t idx)
{
struct json_object *jarray_new;
int i, sz = json_object_array_length(jarray);
@@ -270,7 +273,8 @@ static bool mesh_db_read_unicast_address(struct json_object *jobj,
}


-static bool mesh_db_read_seq_number(struct json_object *jobj, uint32_t *seq_number)
+static bool mesh_db_read_seq_number(struct json_object *jobj,
+ uint32_t *seq_number)
{
struct json_object *jvalue;

@@ -281,7 +285,8 @@ static bool mesh_db_read_seq_number(struct json_object *jobj, uint32_t *seq_numb
return true;
}

-bool mesh_db_read_iv_index(struct json_object *jobj, uint32_t *idx, bool *update)
+bool mesh_db_read_iv_index(struct json_object *jobj, uint32_t *idx,
+ bool *update)
{
int tmp;

@@ -580,8 +585,8 @@ bool mesh_db_write_token(struct json_object *jnode, uint8_t *token)
return add_u64_value(jnode, "token", token);
}

-bool mesh_db_app_key_add(struct json_object *jobj, uint16_t net_idx, uint16_t app_idx,
- const uint8_t key[16])
+bool mesh_db_app_key_add(struct json_object *jobj, uint16_t net_idx,
+ uint16_t app_idx, const uint8_t key[16])
{
struct json_object *jarray = NULL, *jentry = NULL, *jstring = NULL;
char buf[5];
@@ -658,7 +663,8 @@ bool mesh_db_app_key_update(struct json_object *jobj, uint16_t app_idx,
return add_key_value(jentry, "key", key);
}

-bool mesh_db_app_key_del(struct json_object *jobj, uint16_t net_idx, uint16_t idx)
+bool mesh_db_app_key_del(struct json_object *jobj, uint16_t net_idx,
+ uint16_t idx)
{
struct json_object *jarray, *jarray_new;

@@ -689,8 +695,8 @@ bool mesh_db_app_key_del(struct json_object *jobj, uint16_t net_idx, uint16_t id
return true;
}

-bool mesh_db_model_binding_add(struct json_object *jnode, uint8_t ele_idx, bool vendor,
- uint32_t mod_id, uint16_t app_idx)
+bool mesh_db_model_binding_add(struct json_object *jnode, uint8_t ele_idx,
+ bool vendor, uint32_t mod_id, uint16_t app_idx)
{
struct json_object *jmodel, *jstring, *jarray = NULL;
char buf[5];
@@ -723,8 +729,8 @@ bool mesh_db_model_binding_add(struct json_object *jnode, uint8_t ele_idx, bool
return true;
}

-bool mesh_db_model_binding_del(struct json_object *jnode, uint8_t ele_idx, bool vendor,
- uint32_t mod_id, uint16_t app_idx)
+bool mesh_db_model_binding_del(struct json_object *jnode, uint8_t ele_idx,
+ bool vendor, uint32_t mod_id, uint16_t app_idx)
{
struct json_object *jmodel, *jarray, *jarray_new;
char buf[5];
@@ -779,7 +785,8 @@ static void free_element(void *data)
l_free(ele);
}

-static bool parse_bindings(struct json_object *jbindings, struct mesh_db_model *mod)
+static bool parse_bindings(struct json_object *jbindings,
+ struct mesh_db_model *mod)
{
int cnt;
int i;
@@ -942,7 +949,8 @@ fail:
return false;
}

-static bool parse_models(struct json_object *jmodels, struct mesh_db_element *ele)
+static bool parse_models(struct json_object *jmodels,
+ struct mesh_db_element *ele)
{
int i, num_models;

@@ -1016,7 +1024,8 @@ fail:
return false;
}

-static bool parse_elements(struct json_object *jelements, struct mesh_db_node *node)
+static bool parse_elements(struct json_object *jelements,
+ struct mesh_db_node *node)
{
int i, num_ele;

@@ -1095,7 +1104,8 @@ static int get_mode(struct json_object *jvalue)
return 0xffffffff;
}

-static void parse_features(struct json_object *jconfig, struct mesh_db_node *node)
+static void parse_features(struct json_object *jconfig,
+ struct mesh_db_node *node)
{
struct json_object *jvalue, *jrelay;
int mode, count;
@@ -1152,7 +1162,8 @@ static void parse_features(struct json_object *jconfig, struct mesh_db_node *nod
node->modes.relay.interval = interval;
}

-static bool parse_composition(struct json_object *jcomp, struct mesh_db_node *node)
+static bool parse_composition(struct json_object *jcomp,
+ struct mesh_db_node *node)
{
struct json_object *jvalue;
char *str;
@@ -1189,7 +1200,8 @@ static bool parse_composition(struct json_object *jcomp, struct mesh_db_node *no
return true;
}

-bool mesh_db_read_node(struct json_object *jnode, mesh_db_node_cb cb, void *user_data)
+bool mesh_db_read_node(struct json_object *jnode, mesh_db_node_cb cb,
+ void *user_data)
{
struct mesh_db_node node;
struct json_object *jvalue;
@@ -1286,7 +1298,8 @@ bool mesh_db_write_int(struct json_object *jobj, const char *keyword, int value)
return true;
}

-bool mesh_db_write_bool(struct json_object *jobj, const char *keyword, bool value)
+bool mesh_db_write_bool(struct json_object *jobj, const char *keyword,
+ bool value)
{
struct json_object *jvalue;

@@ -1315,7 +1328,8 @@ static const char *mode_to_string(int mode)
}
}

-bool mesh_db_write_mode(struct json_object *jobj, const char *keyword, int value)
+bool mesh_db_write_mode(struct json_object *jobj, const char *keyword,
+ int value)
{
struct json_object *jstring;

@@ -1332,8 +1346,8 @@ bool mesh_db_write_mode(struct json_object *jobj, const char *keyword, int value
return true;
}

-bool mesh_db_write_relay_mode(struct json_object *jnode, uint8_t mode, uint8_t count,
- uint16_t interval)
+bool mesh_db_write_relay_mode(struct json_object *jnode, uint8_t mode,
+ uint8_t count, uint16_t interval)
{
struct json_object *jrelay;

@@ -1579,7 +1593,8 @@ static void finish_key_refresh(struct json_object *jobj, uint16_t net_idx)

}

-bool mesh_db_net_key_set_phase(struct json_object *jobj, uint16_t idx, uint8_t phase)
+bool mesh_db_net_key_set_phase(struct json_object *jobj, uint16_t idx,
+ uint8_t phase)
{
struct json_object *jarray, *jentry = NULL;

@@ -1604,8 +1619,8 @@ bool mesh_db_net_key_set_phase(struct json_object *jobj, uint16_t idx, uint8_t p
return true;
}

-bool mesh_db_model_pub_add(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
- bool vendor, struct mesh_db_pub *pub)
+bool mesh_db_model_pub_add(struct json_object *jnode, uint16_t addr,
+ uint32_t mod_id, bool vendor, struct mesh_db_pub *pub)
{
struct json_object *jmodel, *jpub, *jretransmit;
bool res;
@@ -1686,8 +1701,8 @@ static bool delete_model_property(struct json_object *jnode, uint16_t addr,
return true;
}

-bool mesh_db_model_pub_del(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
- bool vendor)
+bool mesh_db_model_pub_del(struct json_object *jnode, uint16_t addr,
+ uint32_t mod_id, bool vendor)
{
if (!jnode)
return false;
@@ -1695,8 +1710,8 @@ bool mesh_db_model_pub_del(struct json_object *jnode, uint16_t addr, uint32_t mo
return delete_model_property(jnode, addr, mod_id, vendor, "publish");
}

-bool mesh_db_model_sub_add(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
- bool vendor, struct mesh_db_sub *sub)
+bool mesh_db_model_sub_add(struct json_object *jnode, uint16_t addr,
+ uint32_t mod_id, bool vendor, struct mesh_db_sub *sub)
{
struct json_object *jmodel, *jstring, *jarray = NULL;
int ele_idx, len;
@@ -1803,3 +1818,86 @@ bool mesh_db_model_sub_del_all(struct json_object *jnode, uint16_t addr,

return delete_model_property(jnode, addr, mod_id, vendor, "subscribe");
}
+
+
+static bool import_net_key_cb(uint16_t idx, uint8_t *key, uint8_t *new_key,
+ int phase, void *user_data)
+{
+ struct mesh_db_import *import = user_data;
+
+ if (import->net_idx != UNUSED_KEY_IDX)
+ return false;
+
+ if (new_key || phase != KEY_REFRESH_PHASE_NONE)
+ return false;
+
+ import->net_idx = idx;
+ memcpy(import->net_key, key, sizeof(import->net_key));
+
+ return true;
+}
+
+struct mesh_db_import *mesh_db_import_new(const char *import_data)
+{
+ json_object *jobj = json_tokener_parse(import_data);
+ struct mesh_db_import *import = NULL;
+
+ if (!jobj || json_object_get_type(jobj) != json_type_object)
+ goto fail;
+
+ import = l_new(struct mesh_db_import, 1);
+ import->node = l_new(struct mesh_db_node, 1);
+ import->net_idx = UNUSED_KEY_IDX;
+
+ if (!mesh_db_read_device_key(jobj, import->dev_key)) {
+ l_error("Failed to parse imported device key");
+ goto fail;
+ }
+
+ json_object_object_del(jobj, "deviceKey");
+
+ if (!mesh_db_read_unicast_address(jobj, &import->node->unicast)) {
+ l_error("Failed to parse imported unicast");
+ goto fail;
+ }
+
+ json_object_object_del(jobj, "unicastAddress");
+
+ if (!mesh_db_read_iv_index(jobj, &import->iv_index,
+ &import->iv_update)) {
+ l_error("Failed to parse iv_index");
+ goto fail;
+ }
+
+ json_object_object_del(jobj, "IVindex");
+ json_object_object_del(jobj, "IVupdate");
+
+ if (!mesh_db_read_net_keys(jobj, import_net_key_cb, import)) {
+ l_error("Failed to parse imported network key");
+ goto fail;
+ }
+
+ json_object_object_del(jobj, "netKeys");
+
+ if (!mesh_db_read_seq_number(jobj, &import->node->seq_number))
+ import->node->seq_number = DEFAULT_SEQUENCE_NUMBER;
+
+ json_object_object_del(jobj, "sequenceNumber");
+
+ if (json_object_object_length(jobj) != 0) {
+ l_error("Unexpected keys in import data");
+ goto fail;
+ }
+
+ return import;
+fail:
+ if (jobj)
+ json_object_put(jobj);
+
+ if (import) {
+ l_free(import->node);
+ l_free(import);
+ }
+
+ return NULL;
+}
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index 0c09238ed..187f75459 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -95,15 +95,26 @@ 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,
uint8_t key[16], uint8_t new_key[16], void *user_data);
typedef bool (*mesh_db_node_cb)(struct mesh_db_node *node, void *user_data);

-bool mesh_db_read_node(struct json_object *jobj, mesh_db_node_cb cb, void *user_data);
+bool mesh_db_read_node(struct json_object *jobj, mesh_db_node_cb cb,
+ void *user_data);
bool mesh_db_add_node(struct json_object *jnode, struct mesh_db_node *node);
-bool mesh_db_read_iv_index(struct json_object *jobj, uint32_t *idx, bool *update);
+bool mesh_db_read_iv_index(struct json_object *jobj, uint32_t *idx,
+ bool *update);
bool mesh_db_read_device_key(struct json_object *jobj, uint8_t key_buf[16]);
bool mesh_db_read_token(struct json_object *jobj, uint8_t token[8]);
bool mesh_db_read_net_transmit(struct json_object *jobj, uint8_t *cnt,
@@ -116,44 +127,51 @@ bool mesh_db_read_app_keys(struct json_object *jobj, mesh_db_app_key_cb cb,
void *user_data);
bool mesh_db_write_device_key(struct json_object *jobj, uint8_t *key);
bool mesh_db_write_token(struct json_object *jobj, uint8_t *token);
-bool mesh_db_write_network_key(struct json_object *jobj, uint16_t idx, uint8_t *key,
- uint8_t *new_key, int phase);
+bool mesh_db_write_network_key(struct json_object *jobj, uint16_t idx,
+ uint8_t *key, uint8_t *new_key, int phase);
bool mesh_db_write_app_key(struct json_object *jobj, uint16_t net_idx,
uint16_t app_idx, uint8_t *key, uint8_t *new_key);
-bool mesh_db_write_int(struct json_object *jobj, const char *keyword, int value);
+bool mesh_db_write_int(struct json_object *jobj, const char *keyword,
+ int value);
bool mesh_db_write_uint16_hex(struct json_object *jobj, const char *desc,
uint16_t value);
bool mesh_db_write_uint32_hex(struct json_object *jobj, const char *desc,
uint32_t value);
-bool mesh_db_write_bool(struct json_object *jobj, const char *keyword, bool value);
-bool mesh_db_write_relay_mode(struct json_object *jnode, uint8_t mode, uint8_t count,
- uint16_t interval);
-bool mesh_db_write_mode(struct json_object *jobj, const char *keyword, int value);
-bool mesh_db_model_binding_add(struct json_object *jnode, uint8_t ele_idx, bool vendor,
- uint32_t mod_id, uint16_t app_idx);
-bool mesh_db_model_binding_del(struct json_object *jnode, uint8_t ele_idx, bool vendor,
- uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_write_bool(struct json_object *jobj, const char *keyword,
+ bool value);
+bool mesh_db_write_relay_mode(struct json_object *jnode, uint8_t mode,
+ uint8_t count, uint16_t interval);
+bool mesh_db_write_mode(struct json_object *jobj, const char *keyword,
+ int value);
+bool mesh_db_model_binding_add(struct json_object *jnode, uint8_t ele_idx,
+ bool vendor, uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_model_binding_del(struct json_object *jnode, uint8_t ele_idx,
+ bool vendor, uint32_t mod_id, uint16_t app_idx);
bool mesh_db_model_pub_add(struct json_object *jnode, uint16_t ele_addr,
uint32_t mod_id, bool vendor, struct mesh_db_pub *pub);
bool mesh_db_model_pub_del(struct json_object *jnode, uint16_t ele_addr,
uint32_t mod_id, bool vendor);
-bool mesh_db_model_sub_add(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
- bool vendor, struct mesh_db_sub *sub);
-bool mesh_db_model_sub_del(struct json_object *jnode, uint16_t addr, uint32_t mod_id,
- bool vendor, struct mesh_db_sub *sub);
+bool mesh_db_model_sub_add(struct json_object *jnode, uint16_t addr,
+ uint32_t mod_id, bool vendor, struct mesh_db_sub *sub);
+bool mesh_db_model_sub_del(struct json_object *jnode, uint16_t addr,
+ uint32_t mod_id, bool vendor, struct mesh_db_sub *sub);
bool mesh_db_model_sub_del_all(struct json_object *jnode, uint16_t addr,
uint32_t mod_id, bool vendor);
-bool mesh_db_app_key_add(struct json_object *jnode, uint16_t net_idx, uint16_t app_idx,
- const uint8_t key[16]);
+bool mesh_db_app_key_add(struct json_object *jnode, uint16_t net_idx,
+ uint16_t app_idx, const uint8_t key[16]);
bool mesh_db_app_key_update(struct json_object *jobj, uint16_t app_idx,
const uint8_t key[16]);
-bool mesh_db_app_key_del(struct json_object *jobj, uint16_t net_idx, uint16_t idx);
+bool mesh_db_app_key_del(struct json_object *jobj, uint16_t net_idx,
+ uint16_t idx);
bool mesh_db_net_key_add(struct json_object *jobj, uint16_t net_idx,
const uint8_t key[16]);
bool mesh_db_net_key_update(struct json_object *jobj, uint16_t idx,
const uint8_t key[16]);
bool mesh_db_net_key_del(struct json_object *jobj, uint16_t net_idx);
-bool mesh_db_net_key_set_phase(struct json_object *jobj, uint16_t idx, uint8_t phase);
+bool mesh_db_net_key_set_phase(struct json_object *jobj, uint16_t idx,
+ uint8_t phase);
bool mesh_db_write_address(struct json_object *jobj, uint16_t address);
-bool mesh_db_write_iv_index(struct json_object *jobj, uint32_t idx, bool update);
+bool mesh_db_write_iv_index(struct json_object *jobj, uint32_t idx,
+ bool update);
void mesh_db_remove_property(struct json_object *jobj, const char *desc);
+struct mesh_db_import *mesh_db_import_new(const char *import_data);
diff --git a/mesh/mesh-defs.h b/mesh/mesh-defs.h
index 1a199f156..d6ef22362 100644
--- a/mesh/mesh-defs.h
+++ b/mesh/mesh-defs.h
@@ -37,6 +37,7 @@
#define KEY_REFRESH_PHASE_THREE 0x03

#define DEFAULT_TTL 0xff
+#define DEFAULT_SEQUENCE_NUMBER 0

/* Supported algorithms for provisioning */
#define ALG_FIPS_256_ECC 0x0001
diff --git a/mesh/mesh.c b/mesh/mesh.c
index 98e6d87b2..f6280e12d 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -22,6 +22,7 @@
#endif

#define _GNU_SOURCE
+#include <string.h>
#include <ell/ell.h>

#include "mesh/mesh-io.h"
@@ -34,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
@@ -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 */
@@ -383,6 +389,18 @@ fail:
free_pending_join_call(true);
}

+static bool validate_data_type(const char *data_type)
+{
+ uint8_t idx = 0;
+ uint8_t len = L_ARRAY_SIZE(supported_import_data_types);
+
+ for (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,74 @@ 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;
+ struct mesh_db_import *import;
+ const char *data_type, *import_data;
+ uint8_t *uuid;
+ uint32_t n;
+
+ 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");
+
+ import = mesh_db_import_new(import_data);
+
+ if (!import)
+ 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);
+
+ if (!pending_queue)
+ pending_queue = l_queue_new();
+
+ l_queue_push_tail(pending_queue, pending_msg);
+
+ if (!node_import(app_path, sender, import, uuid, create_node_ready_cb,
+ pending_msg))
+ goto fail;
+
+ return NULL;
+
+fail:
+ l_free(import);
+ 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)
{
l_dbus_interface_method(iface, "Join", 0, join_network_call, "",
@@ -612,8 +692,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/model.c b/mesh/model.c
index f59d709d5..c320a7594 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -227,6 +227,7 @@ static struct l_dbus_message *create_config_update_msg(struct mesh_node *node,

if ((id & VENDOR_ID_MASK) != VENDOR_ID_MASK) {
uint16_t vendor = id >> 16;
+
dbus_append_dict_entry_basic(*builder, "Vendor", "q", &vendor);
}

@@ -267,7 +268,7 @@ static void append_dict_uint16_array(struct l_dbus_message_builder *builder,
for (entry = l_queue_get_entries(q); entry; entry = entry->next) {
uint16_t value = (uint16_t) L_PTR_TO_UINT(entry->data);

- l_dbus_message_builder_append_basic(builder,'q', &value);
+ l_dbus_message_builder_append_basic(builder, 'q', &value);
}

l_dbus_message_builder_leave_array(builder);
@@ -1579,6 +1580,7 @@ void model_build_config(void *model, void *msg_builder)
/* For vendor models, add vendor id */
if ((mod->id & VENDOR_ID_MASK) != VENDOR_ID_MASK) {
uint16_t vendor = mod->id >> 16;
+
dbus_append_dict_entry_basic(builder, "Vendor", "q", &vendor);
}

@@ -1589,6 +1591,7 @@ void model_build_config(void *model, void *msg_builder)
/* Model periodic publication interval, if present */
if (mod->pub) {
uint32_t period = pub_period_to_ms(mod->pub->period);
+
dbus_append_dict_entry_basic(builder, "PublicationPeriod", "u",
&period);
}
diff --git a/mesh/node.c b/mesh/node.c
index 8533aaa1e..646e23a32 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -54,11 +54,13 @@
#define DEFAULT_LOCATION 0x0000

#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;
@@ -108,8 +110,16 @@ struct mesh_node {
struct managed_obj_request {
void *data;
void *cb;
- void *user_data;
- uint8_t type;
+ union {
+ struct l_dbus_message *pending_msg;
+ struct node_import_request *import_req;
+ };
+ enum request_type type;
+};
+
+struct node_import_request {
+ struct mesh_db_import *import;
+ struct l_dbus_message *pending_msg;
};

static struct l_queue *nodes;
@@ -1388,13 +1398,6 @@ 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])
{
- node->net = mesh_net_new(node);
-
- if (!nodes)
- nodes = l_queue_new();
-
- l_queue_push_tail(nodes, node);
-
if (!storage_set_iv_index(node->net, iv_idx, ivu))
return false;

@@ -1462,14 +1465,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;
@@ -1543,7 +1545,7 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data)

node->disc_watch = l_dbus_add_disconnect_watch(bus,
node->owner, app_disc_cb, node, NULL);
- cb(req->user_data, MESH_ERROR_NONE, node);
+ cb(req->pending_msg, MESH_ERROR_NONE, node);
} else
goto fail;

@@ -1565,6 +1567,49 @@ 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_req = req->import_req;
+ struct mesh_db_import *import = import_req->import;
+ 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->node->seq_number)
+ node->seq_number = import->node->seq_number;
+
+ memcpy(node->uuid, req->data, 16);
+
+ if (!create_node_config(node))
+ goto fail;
+
+ if (!add_local_node(node, import->node->unicast, false,
+ import->iv_update, import->iv_index,
+ import->dev_key, import->net_idx,
+ import->net_key))
+ goto fail;
+
+ memcpy(net_key.old_key, import->net_key, 16);
+ net_key.net_idx = import->net_idx;
+ net_key.phase = KEY_REFRESH_PHASE_NONE;
+
+ if (!keyring_put_remote_dev_key(node, import->node->unicast,
+ num_ele, import->dev_key))
+ goto fail;
+
+ if (!keyring_put_net_key(node, PRIMARY_NET_IDX, &net_key))
+ goto fail;
+
+ cb(import_req->pending_msg, MESH_ERROR_NONE, node);
+
} else {
/* Callback for create node request */
node_ready_func_t cb = req->cb;
@@ -1597,7 +1642,7 @@ static void get_managed_objects_cb(struct l_dbus_message *msg, void *user_data)
if (!keyring_put_net_key(node, PRIMARY_NET_IDX, &net_key))
goto fail;

- cb(req->user_data, MESH_ERROR_NONE, node);
+ cb(req->pending_msg, MESH_ERROR_NONE, node);
}

return;
@@ -1611,9 +1656,9 @@ fail:

free_node_dbus_resources(node);

- cb(req->user_data, MESH_ERROR_FAILED, node);
+ cb(req->pending_msg, MESH_ERROR_FAILED, node);
} else {
- /* Handle failed Join and Create requests */
+ /* Handle failed Join, Create and Import requests */
if (node)
node_remove(node);

@@ -1621,10 +1666,16 @@ fail:
node_join_ready_func_t cb = req->cb;

cb(NULL, NULL);
+ } else if (req->type == REQUEST_TYPE_IMPORT) {
+ node_ready_func_t cb = req->cb;
+
+ cb(req->import_req->pending_msg, MESH_ERROR_FAILED,
+ NULL);
+
} else {
node_ready_func_t cb = req->cb;

- cb(req->user_data, MESH_ERROR_FAILED, NULL);
+ cb(req->pending_msg, MESH_ERROR_FAILED, NULL);
}
}
}
@@ -1652,7 +1703,7 @@ int node_attach(const char *app_path, const char *sender, uint64_t token,
req = l_new(struct managed_obj_request, 1);
req->data = node;
req->cb = cb;
- req->user_data = user_data;
+ req->pending_msg = user_data;
req->type = REQUEST_TYPE_ATTACH;

l_dbus_method_call(dbus_get_bus(), sender, app_path,
@@ -1685,6 +1736,39 @@ void node_join(const char *app_path, const char *sender, const uint8_t *uuid,
req, l_free);
}

+bool node_import(const char *app_path, const char *sender,
+ struct mesh_db_import *import,
+ const uint8_t *uuid, node_ready_func_t cb,
+ void *user_data)
+{
+ struct managed_obj_request *req;
+ struct node_import_request *import_req;
+
+ l_debug("");
+
+ /* TODO: implement full import */
+ if (import->node->elements)
+ return false;
+
+ req = l_new(struct managed_obj_request, 1);
+ import_req = l_new(struct node_import_request, 1);
+
+ import_req->pending_msg = user_data;
+ import_req->import = import;
+
+ req->data = (void *) uuid;
+ req->import_req = import_req;
+ 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;
+}
+
void node_create(const char *app_path, const char *sender, const uint8_t *uuid,
node_ready_func_t cb, void *user_data)
{
@@ -1695,7 +1779,7 @@ void node_create(const char *app_path, const char *sender, const uint8_t *uuid,
req = l_new(struct managed_obj_request, 1);
req->data = (void *) uuid;
req->cb = cb;
- req->user_data = user_data;
+ req->pending_msg = user_data;
req->type = REQUEST_TYPE_CREATE;

l_dbus_method_call(dbus_get_bus(), sender, app_path,
diff --git a/mesh/node.h b/mesh/node.h
index 142527b30..c87e2c683 100644
--- a/mesh/node.h
+++ b/mesh/node.h
@@ -33,6 +33,8 @@ typedef void (*node_ready_func_t) (void *user_data, int status,
typedef void (*node_join_ready_func_t) (struct mesh_node *node,
struct mesh_agent *agent);

+struct mesh_db_import;
+
struct mesh_node *node_new(const uint8_t uuid[16]);
void node_remove(struct mesh_node *node);
void node_join(const char *app_path, const char *sender, const uint8_t *uuid,
@@ -91,6 +93,10 @@ 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,
+ struct mesh_db_import *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);
bool node_dbus_init(struct l_dbus *bus);
--
2.20.1

2019-07-10 07:39:35

by Stotland, Inga

[permalink] [raw]
Subject: Re: [PATCH BlueZ v4 1/4] mesh: Add ImportLocalNode api documentation

Hi Jakub,

On Tue, 2019-07-09 at 12:15 +0200, Jakub Witowski wrote:
> 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 application that implements org.bluez.mesh.Application1 interface"
I don't think that supporting Provisioner1 interface is a requirement?

> +
> + The data_type parameter defines the import_data type.
> Supported
> + data_type parameters:

"The following values are supported:"

> + - “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 description of import_data parameter needs to be re-written.
The above description is too skewed towards JSON format and imo is more
detiled than needed.

we definitely need to mention that the interpretation of the
import_data parameter depends on the value of data_type. Then we can
say that "for the case when data_type has value "json", the import_data
contains a string that describes node configuration in JSOn notation,
following the <TBD> schema. See the examples at the end of this
documents."



> 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>


Line break
> +Mesh Node Configuration Examples
> +================================
> +Example of Json format for ImportLocalNode():


Minimum required configuration:
> + {
> + "IVindex":0,
> + "IVupdate":0,
> + "unicastAddress":"0012",
> + "deviceKey":"7daa45cd1e9e11a4b86eeef7d01efa11",
> + "netKeys":[
"sequenceNumber":15
No sequence number

> + {
> + "index":"0000",
> + "key":"2ddfef86d67144c394428ea3078f86f9",
> + "keyRefresh":0
> + }]
> + }
> +
> + Import full node operation:
> + {
> + "cid":"fee5",
> + "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",

No token
> + "deviceKey":"56325fd145f3d5eee1b82136dc3e1454",
> + "netKeys":[
> + {
> + "index":"0000",
> + "key":"2ddfef86d67144c394428ea3078f86f9",
> + "keyRefresh":0
> + }],
> + "appKeys":[
> + {
> + "index":"0000",
> + "boundNetKey":"0000",
> + "key":"43886b02ca4343beaae26dc4b6773ba4"
> + }],
> + "sequenceNumber":15

no sequence number
> + }


Actually, I don't like the full configuration exmple. It's not realy
"full". Better to provide a schema. We'll get to the schema in time.


Attachments:
smime.p7s (3.19 kB)