2019-03-08 22:58:24

by Stotland, Inga

[permalink] [raw]
Subject: [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings

This patch set implements the following:
- Write updates of node model subscriptions to node config file
- Write updates of node model publication settings to node config file
- Correctly restore subscriptions and publications on daemon startup

Inga Stotland (3):
mesh: Add json config functions to save pub/sub updates
mesh: Save model subscription updates to config file
mesh: Store model publication settings in config file

mesh/cfgmod-server.c | 104 +++++++++++++++-
mesh/mesh-db.c | 282 ++++++++++++++++++++++++++++++++++++++++++-
mesh/mesh-db.h | 15 ++-
mesh/model.c | 22 ++--
4 files changed, 404 insertions(+), 19 deletions(-)

--
2.17.2



2019-03-08 22:58:27

by Stotland, Inga

[permalink] [raw]
Subject: [PATCH BlueZ 2/3] mesh: Save model subscription updates to config file

This adds functionality in Config Server model to save changes in
node configuration file when model subscriptions are added, deleted or
overwritten.
---
mesh/cfgmod-server.c | 60 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 58 insertions(+), 2 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index 9dc82eef6..df2614529 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -37,6 +37,7 @@
#include "mesh/appkey.h"
#include "mesh/model.h"
#include "mesh/storage.h"
+#include "mesh/mesh-db.h"

#include "mesh/cfgmod.h"

@@ -195,7 +196,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
if (IS_UNASSIGNED(ota) && !b_virt)
ttl = period = idx = 0;

- if (status >= 0 && !unreliable)
+ if (!unreliable)
send_pub_status(node, src, dst, status, ele_addr, ota,
mod_id, idx, cred_flag, ttl, period,
retransmit);
@@ -285,6 +286,38 @@ static bool config_sub_get(struct mesh_node *node, uint16_t src, uint16_t dst,
return true;
}

+static bool save_config_sub(struct mesh_node *node, uint16_t ele_addr,
+ uint32_t mod_id, bool vendor,
+ const uint8_t *addr, bool virt,
+ uint16_t grp, uint32_t opcode)
+{
+ struct mesh_db_sub db_sub = {
+ .virt = virt,
+ .src.addr = grp
+ };
+
+ if (virt)
+ memcpy(db_sub.src.virt_addr, addr, 16);
+
+ if (opcode == OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE ||
+ opcode == OP_CONFIG_MODEL_SUB_OVERWRITE)
+ mesh_db_model_sub_del_all(node_jconfig_get(node),
+ ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
+ vendor);
+
+ if (opcode != OP_CONFIG_MODEL_SUB_VIRT_DELETE &&
+ opcode != OP_CONFIG_MODEL_SUB_DELETE)
+ return mesh_db_model_sub_add(node_jconfig_get(node),
+ ele_addr,
+ vendor ? mod_id : mod_id & 0x0000ffff,
+ vendor, &db_sub);
+ else
+ return mesh_db_model_sub_del(node_jconfig_get(node),
+ ele_addr,
+ vendor ? mod_id : mod_id & 0x0000ffff,
+ vendor, &db_sub);
+}
+
static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
const uint8_t *pkt, uint16_t size,
bool virt, uint32_t opcode)
@@ -294,6 +327,7 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
uint32_t mod_id, func;
const uint8_t *addr = NULL;
int status = 0;
+ bool vendor = false;

switch (size) {
default:
@@ -314,6 +348,7 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
} else {
mod_id = l_get_le16(pkt + 2) << 16;
mod_id |= l_get_le16(pkt + 4);
+ vendor = true;
}
break;
case 8:
@@ -321,6 +356,7 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
return;
mod_id = l_get_le16(pkt + 4) << 16;
mod_id |= l_get_le16(pkt + 6);
+ vendor = true;
break;
case 20:
if (!virt)
@@ -351,6 +387,11 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,

case OP_CONFIG_MODEL_SUB_DELETE_ALL:
status = mesh_model_sub_del_all(node, ele_addr, mod_id);
+
+ if (status == MESH_STATUS_SUCCESS)
+ mesh_db_model_sub_del_all(node_jconfig_get(node),
+ ele_addr, vendor ? mod_id : mod_id & 0x0000ffff,
+ vendor);
break;

case OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
@@ -359,6 +400,10 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
case OP_CONFIG_MODEL_SUB_OVERWRITE:
status = mesh_model_sub_ovr(node, ele_addr, mod_id,
addr, virt, &grp);
+
+ if (status == MESH_STATUS_SUCCESS)
+ save_config_sub(node, ele_addr, mod_id, vendor, addr,
+ virt, grp, opcode);
break;
case OP_CONFIG_MODEL_SUB_VIRT_ADD:
grp = UNASSIGNED_ADDRESS;
@@ -366,6 +411,12 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
case OP_CONFIG_MODEL_SUB_ADD:
status = mesh_model_sub_add(node, ele_addr, mod_id,
addr, virt, &grp);
+
+ if (status == MESH_STATUS_SUCCESS &&
+ !save_config_sub(node, ele_addr, mod_id, vendor,
+ addr, virt, grp, opcode))
+ status = MESH_STATUS_STORAGE_FAIL;
+
break;
case OP_CONFIG_MODEL_SUB_VIRT_DELETE:
grp = UNASSIGNED_ADDRESS;
@@ -373,10 +424,15 @@ static void config_sub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
case OP_CONFIG_MODEL_SUB_DELETE:
status = mesh_model_sub_del(node, ele_addr, mod_id,
addr, virt, &grp);
+
+ if (status == MESH_STATUS_SUCCESS)
+ save_config_sub(node, ele_addr, mod_id, vendor, addr,
+ virt, grp, opcode);
+
break;
}

- if (!unreliable && status >= 0)
+ if (!unreliable)
send_sub_status(node, src, dst, status, ele_addr, grp, mod_id);

}
--
2.17.2


2019-03-08 22:58:28

by Stotland, Inga

[permalink] [raw]
Subject: [PATCH BlueZ 1/3] mesh: Add json config functions to save pub/sub updates

This adds functions to save updates to model subscriptions and
publication in JSON format.
---
mesh/mesh-db.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++-
mesh/mesh-db.h | 13 ++-
mesh/model.c | 4 +-
3 files changed, 292 insertions(+), 5 deletions(-)

diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index 2d518c1aa..01859f524 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -66,6 +66,32 @@ 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)
+{
+ json_object *jvalue, *jelements;
+ uint16_t addr, num_ele;
+ char *str;
+
+ json_object_object_get_ex(jnode, "unicastAddress", &jvalue);
+ if (!jvalue)
+ return -1;
+
+ str = (char *)json_object_get_string(jvalue);
+ if (sscanf(str, "%04hx", &addr) != 1)
+ return -1;
+
+ json_object_object_get_ex(jnode, "elements", &jelements);
+ if (!jelements)
+ return -1;
+
+ num_ele = json_object_array_length(jelements);
+
+ if (ele_addr >= addr + num_ele || ele_addr < addr)
+ return -1;
+
+ return ele_addr - addr;
+}
+
static json_object *get_element_model(json_object *jnode, int ele_idx,
uint32_t mod_id, bool vendor)
{
@@ -800,10 +826,18 @@ static struct mesh_db_pub *parse_model_publication(json_object *jpub)
goto fail;
pub->credential = (uint8_t) value;

- if (!get_int(jpub, "retransmit", &value))
+ json_object_object_get_ex(jpub, "retransmit", &jvalue);
+ if (!jvalue)
goto fail;

- pub->retransmit = (uint8_t) value;
+ if (!get_int(jvalue, "count", &value))
+ goto fail;
+ pub->count = (uint8_t) value;
+
+ if (!get_int(jvalue, "interval", &value))
+ goto fail;
+ pub->interval = (uint8_t) value;
+
return pub;

fail:
@@ -1133,6 +1167,9 @@ bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
json_object *jvalue;
char *str;

+ if (!jnode)
+ return false;
+
if (!cb) {
l_info("Node read callback is required");
return false;
@@ -1185,6 +1222,9 @@ bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
json_object *jstring;
char buf[5];

+ if (!jobj)
+ return false;
+
snprintf(buf, 5, "%4.4x", value);
jstring = json_object_new_string(buf);
if (!jstring)
@@ -1200,6 +1240,9 @@ bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
json_object *jstring;
char buf[9];

+ if (!jobj)
+ return false;
+
snprintf(buf, 9, "%8.8x", value);
jstring = json_object_new_string(buf);
if (!jstring)
@@ -1213,6 +1256,9 @@ bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
{
json_object *jvalue;

+ if (!jobj)
+ return false;
+
json_object_object_del(jobj, keyword);

jvalue = json_object_new_int(value);
@@ -1227,6 +1273,9 @@ bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value)
{
json_object *jvalue;

+ if (!jobj)
+ return false;
+
json_object_object_del(jobj, keyword);

jvalue = json_object_new_boolean(value);
@@ -1253,6 +1302,9 @@ bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
{
json_object *jstring;

+ if (!jobj)
+ return false;
+
jstring = json_object_new_string(mode_to_string(value));

if (!jstring)
@@ -1268,6 +1320,9 @@ bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
{
json_object *jrelay;

+ if (!jnode)
+ return false;
+
json_object_object_del(jnode, "relay");

jrelay = json_object_new_object();
@@ -1296,6 +1351,9 @@ bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
{
json_object *jretransmit, *jvalue;

+ if (!jobj)
+ return false;
+
json_object_object_get_ex(jobj, "retransmit", &jretransmit);
if (!jretransmit)
return false;
@@ -1320,6 +1378,9 @@ bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
{
json_object *jretransmit;

+ if (!jobj)
+ return false;
+
json_object_object_del(jobj, "retransmit");

jretransmit = json_object_new_object();
@@ -1345,6 +1406,9 @@ bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
{
int tmp = update ? 1 : 0;

+ if (!jobj)
+ return false;
+
if (!mesh_db_write_int(jobj, "IVindex", idx))
return false;

@@ -1356,7 +1420,8 @@ 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)
{
- json_object_object_del(jobj, desc);
+ if (jobj)
+ json_object_object_del(jobj, desc);
}

static void add_model(void *a, void *b)
@@ -1384,6 +1449,9 @@ bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
const struct l_queue_entry *entry;
json_object *jelements;

+ if (!jnode)
+ return false;
+
/* CID, PID, VID, crpl */
if (!mesh_db_write_uint16_hex(jnode, "cid", node->cid))
return false;
@@ -1505,6 +1573,9 @@ bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
{
json_object *jarray, *jentry = NULL;

+ if (!jobj)
+ return false;
+
json_object_object_get_ex(jobj, "netKeys", &jarray);

if (jarray)
@@ -1524,3 +1595,205 @@ 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 vendor, struct mesh_db_pub *pub)
+{
+ json_object *jmodel, *jpub, *jretransmit;
+ bool res;
+ int ele_idx;
+
+ if (!jnode)
+ return false;
+
+ ele_idx = get_element_index(jnode, addr);
+ if (ele_idx < 0)
+ return false;
+
+ jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+ if (!jmodel)
+ return false;
+
+ json_object_object_del(jmodel, "publish");
+
+ jpub = json_object_new_object();
+ if (!jpub)
+ return false;
+
+ if (pub->virt)
+ res = add_key_value(jpub, "address", pub->virt_addr);
+ else
+ res = mesh_db_write_uint16_hex(jpub, "address", pub->addr);
+
+ if (!res)
+ goto fail;
+
+ if (!mesh_db_write_uint16_hex(jpub, "index", pub->idx))
+ goto fail;
+
+ if (!mesh_db_write_int(jpub, "ttl", pub->ttl))
+ goto fail;
+
+ if (!mesh_db_write_int(jpub, "period", pub->period))
+ goto fail;
+
+ if (!mesh_db_write_int(jpub, "credentials", pub->credential ? 1 : 0))
+ goto fail;
+
+ jretransmit = json_object_new_object();
+ if (!jretransmit)
+ goto fail;
+
+ if (!mesh_db_write_int(jretransmit, "count", pub->count))
+ goto fail;
+
+ if (!mesh_db_write_int(jretransmit, "interval", pub->interval))
+ goto fail;
+
+ json_object_object_add(jpub, "retransmit", jretransmit);
+ json_object_object_add(jmodel, "publish", jpub);
+
+ return true;
+fail:
+ json_object_put(jpub);
+ return false;
+}
+
+static bool delete_model_property(json_object *jnode, uint16_t addr,
+ uint32_t mod_id, bool vendor, const char *keyword)
+{
+ json_object *jmodel;
+ int ele_idx;
+
+ ele_idx = get_element_index(jnode, addr);
+ if (ele_idx < 0)
+ return false;
+
+ jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+ if (!jmodel)
+ return false;
+
+ json_object_object_del(jmodel, keyword);
+
+ return true;
+}
+
+bool mesh_db_model_pub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
+ bool vendor)
+{
+ if (!jnode)
+ return false;
+
+ 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 vendor, struct mesh_db_sub *sub)
+{
+ json_object *jmodel, *jstring, *jarray;
+ int ele_idx, len;
+ char buf[33];
+
+ if (!jnode)
+ return false;
+
+ ele_idx = get_element_index(jnode, addr);
+ if (ele_idx < 0)
+ return false;
+
+ jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+ if (!jmodel)
+ return false;
+
+ json_object_object_get_ex(jmodel, "subscribe", &jarray);
+
+ if (!sub->virt) {
+ snprintf(buf, 5, "%4.4x", sub->src.addr);
+ len = 4;
+ } else {
+ hex2str(sub->src.virt_addr, 16, buf, 33);
+ len = 32;
+ }
+
+ if (jarray && jarray_has_string(jarray, buf, len))
+ return true;
+
+ jstring = json_object_new_string(buf);
+ if (!jstring)
+ return false;
+
+ if (!jarray) {
+ jarray = json_object_new_array();
+ if (!jarray) {
+ json_object_put(jstring);
+ return false;
+ }
+ json_object_object_add(jmodel, "subscribe", jarray);
+ }
+
+ json_object_array_add(jarray, jstring);
+
+ return true;
+}
+
+bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr,
+ uint32_t mod_id, bool vendor, struct mesh_db_sub *sub)
+{
+ json_object *jmodel, *jarray, *jarray_new;
+ char buf[33];
+ int len, ele_idx;
+
+ if (!jnode)
+ return false;
+
+ ele_idx = get_element_index(jnode, addr);
+ if (ele_idx < 0)
+ return false;
+
+ jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
+ if (!jmodel)
+ return false;
+
+ json_object_object_get_ex(jmodel, "subscribe", &jarray);
+ if (!jarray)
+ return true;
+
+ if (!sub->virt) {
+ snprintf(buf, 5, "%4.4x", sub->src.addr);
+ len = 4;
+ } else {
+ hex2str(sub->src.virt_addr, 16, buf, 33);
+ len = 32;
+ }
+
+ if (!jarray_has_string(jarray, buf, len))
+ return true;
+
+ if (json_object_array_length(jarray) == 1) {
+ json_object_object_del(jmodel, "subscribe");
+ return true;
+ }
+
+ /*
+ * There is no easy way to delete a value from a json array.
+ * Create a new copy without specified element and
+ * then remove old array.
+ */
+ jarray_new = jarray_string_del(jarray, buf, len);
+ if (!jarray_new)
+ return false;
+
+ json_object_object_del(jmodel, "subscribe");
+ json_object_object_add(jmodel, "subscribe", jarray_new);
+
+ return true;
+}
+
+bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr,
+ uint32_t mod_id, bool vendor)
+{
+ if (!jnode)
+ return false;
+
+ return delete_model_property(jnode, addr, mod_id, vendor, "subscribe");
+}
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index 52ea05528..5dec6cb9f 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -32,7 +32,8 @@ struct mesh_db_pub {
uint8_t ttl;
uint8_t credential;
uint8_t period;
- uint8_t retransmit;
+ uint8_t count;
+ uint8_t interval;
uint8_t virt_addr[16];
};

@@ -129,6 +130,16 @@ bool mesh_db_model_binding_add(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,
uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_model_pub_add(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,
+ uint32_t mod_id, bool vendor);
+bool mesh_db_model_sub_add(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 vendor, struct mesh_db_sub *sub);
+bool mesh_db_model_sub_del_all(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,
const uint8_t key[16]);
bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
diff --git a/mesh/model.c b/mesh/model.c
index 5940f6854..dc525f72f 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -1428,13 +1428,15 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx,
struct mesh_db_pub *pub = db_mod->pub;
uint8_t mod_addr[2];
uint8_t *pub_addr;
+ uint8_t retransmit = (pub->count << 5) +
+ (pub->interval / 50 - 1);

/* Add publication */
l_put_le16(pub->addr, &mod_addr);
pub_addr = pub->virt ? pub->virt_addr : (uint8_t *) &mod_addr;

if (set_pub(mod, pub_addr, pub->idx, pub->credential, pub->ttl,
- pub->period, pub->retransmit, pub->virt, NULL) !=
+ pub->period, retransmit, pub->virt, NULL) !=
MESH_STATUS_SUCCESS) {
mesh_model_free(mod);
return NULL;
--
2.17.2


2019-03-08 22:58:29

by Stotland, Inga

[permalink] [raw]
Subject: [PATCH BlueZ 3/3] mesh: Store model publication settings in config file

This adds functionality to enable storing model publication
parameters in node configuration file.

Also, fix calculations of model publication period.
---
mesh/cfgmod-server.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
mesh/mesh-db.c | 2 +-
mesh/mesh-db.h | 2 +-
mesh/model.c | 18 +++++++++---------
4 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c
index df2614529..737aee376 100644
--- a/mesh/cfgmod-server.c
+++ b/mesh/cfgmod-server.c
@@ -125,6 +125,9 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
uint8_t retransmit;
int status;
bool cred_flag, b_virt = false;
+ bool vendor = false;
+ struct mesh_model_pub *pub;
+ uint8_t ele_idx;

switch (size) {
default:
@@ -146,6 +149,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
retransmit = pkt[8];
mod_id = l_get_le16(pkt + 9) << 16;
mod_id |= l_get_le16(pkt + 11);
+ vendor = true;
break;

case 25:
@@ -166,6 +170,7 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
retransmit = pkt[22];
mod_id = l_get_le16(pkt + 23) << 16;
mod_id |= l_get_le16(pkt + 25);
+ vendor = true;
break;
}
ele_addr = l_get_le16(pkt);
@@ -193,9 +198,46 @@ static bool config_pub_set(struct mesh_node *node, uint16_t src, uint16_t dst,
l_debug("pub_set: status %d, ea %4.4x, ota: %4.4x, mod: %x, idx: %3.3x",
status, ele_addr, ota, mod_id, idx);

- if (IS_UNASSIGNED(ota) && !b_virt)
+ if (IS_UNASSIGNED(ota) && !b_virt) {
ttl = period = idx = 0;

+ /* Remove model publication from config file */
+ if (status == MESH_STATUS_SUCCESS)
+ mesh_db_model_pub_del(node_jconfig_get(node), ele_addr,
+ vendor ? mod_id : mod_id & 0x0000ffff,
+ vendor);
+ goto done;
+ }
+
+ if (status != MESH_STATUS_SUCCESS)
+ goto done;
+
+ ele_idx = node_get_element_idx(node, ele_addr);
+ pub = mesh_model_pub_get(node, ele_idx, mod_id, &status);
+
+ if (pub) {
+ struct mesh_db_pub db_pub = {
+ .virt = b_virt,
+ .addr = ota,
+ .idx = idx,
+ .ttl = ttl,
+ .credential = pub->credential,
+ .period = period,
+ .count = pub->retransmit >> 5,
+ .interval = ((0x1f & pub->retransmit) + 1) * 50
+ };
+
+ if (b_virt)
+ memcpy(db_pub.virt_addr, pub_addr, 16);
+
+ /* Save model publication to config file */
+ if (!mesh_db_model_pub_add(node_jconfig_get(node), ele_addr,
+ vendor ? mod_id : mod_id & 0x0000ffff,
+ vendor, &db_pub))
+ status = MESH_STATUS_STORAGE_FAIL;
+ }
+
+done:
if (!unreliable)
send_pub_status(node, src, dst, status, ele_addr, ota,
mod_id, idx, cred_flag, ttl, period,
diff --git a/mesh/mesh-db.c b/mesh/mesh-db.c
index 01859f524..757cfd4c2 100644
--- a/mesh/mesh-db.c
+++ b/mesh/mesh-db.c
@@ -820,7 +820,7 @@ static struct mesh_db_pub *parse_model_publication(json_object *jpub)

if (!get_int(jpub, "period", &value))
goto fail;
- pub->period = (uint8_t) value;
+ pub->period = value;

if (!get_int(jpub, "credentials", &value))
goto fail;
diff --git a/mesh/mesh-db.h b/mesh/mesh-db.h
index 5dec6cb9f..b9af1203b 100644
--- a/mesh/mesh-db.h
+++ b/mesh/mesh-db.h
@@ -27,11 +27,11 @@ struct mesh_db_sub {

struct mesh_db_pub {
bool virt;
+ uint32_t period;
uint16_t addr;
uint16_t idx;
uint8_t ttl;
uint8_t credential;
- uint8_t period;
uint8_t count;
uint8_t interval;
uint8_t virt_addr[16];
diff --git a/mesh/model.c b/mesh/model.c
index dc525f72f..80c30edba 100644
--- a/mesh/model.c
+++ b/mesh/model.c
@@ -178,13 +178,13 @@ static struct mesh_model *find_model(struct mesh_node *node, uint16_t addr,
return get_model(node, (uint8_t) ele_idx, mod_id, fail);
}

-static uint32_t convert_pub_period_to_ms(uint8_t pub_period)
+static uint32_t pub_period_to_ms(uint8_t pub_period)
{
int n;

- n = (pub_period & 0x3f);
+ n = pub_period >> 2;

- switch (pub_period >> 6) {
+ switch (pub_period & 0x3) {
default:
return n * 100;
case 2:
@@ -488,8 +488,10 @@ static void remove_pub(struct mesh_node *node, struct mesh_model *mod)
l_free(mod->pub);
mod->pub = NULL;

- /* TODO: remove from storage */
-
+ /*
+ * TODO: Instead of reporting period of 0, report publication
+ * address as unassigned
+ */
if (!mod->cbs)
/* External models */
config_update_model_pub_period(node, mod->ele_idx, mod->id, 0);
@@ -1017,8 +1019,6 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id,
if (result != MESH_STATUS_SUCCESS)
return result;

- /* TODO: save to storage */
-
/*
* If the publication address is set to unassigned address value,
* remove publication
@@ -1034,7 +1034,7 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id,

/* External model */
config_update_model_pub_period(node, ele_idx, id,
- convert_pub_period_to_ms(period));
+ pub_period_to_ms(period));

return MESH_STATUS_SUCCESS;
}
@@ -1601,7 +1601,7 @@ void model_build_config(void *model, void *msg_builder)

/* Model periodic publication interval, if present */
if (mod->pub) {
- uint32_t period = convert_pub_period_to_ms(mod->pub->period);
+ uint32_t period = pub_period_to_ms(mod->pub->period);
dbus_append_dict_entry_basic(builder, "PublicationPeriod", "u",
&period);
}
--
2.17.2


2019-03-11 22:20:16

by Gix, Brian

[permalink] [raw]
Subject: Re: [PATCH BlueZ 0/3] Save and restore mesh models pub/sub settings

Patch set applied

On Fri, 2019-03-08 at 14:58 -0800, Inga Stotland wrote:
> This patch set implements the following:
> - Write updates of node model subscriptions to node config file
> - Write updates of node model publication settings to node config file
> - Correctly restore subscriptions and publications on daemon startup
>
> Inga Stotland (3):
> mesh: Add json config functions to save pub/sub updates
> mesh: Save model subscription updates to config file
> mesh: Store model publication settings in config file
>
> mesh/cfgmod-server.c | 104 +++++++++++++++-
> mesh/mesh-db.c | 282 ++++++++++++++++++++++++++++++++++++++++++-
> mesh/mesh-db.h | 15 ++-
> mesh/model.c | 22 ++--
> 4 files changed, 404 insertions(+), 19 deletions(-)
>