@@ -60,11 +60,6 @@ struct pending_req {
uint16_t addr;
};
-struct mesh_group {
- uint16_t addr;
- uint8_t label[16];
-};
-
static struct l_queue *requests;
static struct l_queue *groups;
@@ -816,6 +811,8 @@ static struct mesh_group *add_group(uint16_t addr)
grp->addr = addr;
l_queue_insert(groups, grp, compare_group_addr, NULL);
+ mesh_db_add_group(grp);
+
return grp;
}
@@ -1683,6 +1680,7 @@ retry:
if (!tmp) {
l_queue_insert(groups, grp, compare_group_addr, NULL);
print_group(grp, NULL);
+ mesh_db_add_group(grp);
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
@@ -1819,6 +1817,11 @@ static struct model_info cli_info = {
.vendor_id = VENDOR_ID_INVALID
};
+void cfgcli_restore_groups(struct l_queue *saved_groups)
+{
+ groups = saved_groups;
+}
+
struct model_info *cfgcli_init(key_send_func_t key_send, void *user_data)
{
if (!key_send)
@@ -1827,8 +1830,6 @@ struct model_info *cfgcli_init(key_send_func_t key_send, void *user_data)
send_key_msg = key_send;
key_data = user_data;
requests = l_queue_new();
- groups = l_queue_new();
-
bt_shell_add_submenu(&cfg_menu);
return &cli_info;
@@ -18,8 +18,14 @@
*
*/
+struct mesh_group {
+ uint16_t addr;
+ uint8_t label[16];
+};
+
typedef bool (*key_send_func_t) (void *user_data, uint16_t dst,
uint16_t idx, bool is_appkey, bool update);
struct model_info *cfgcli_init(key_send_func_t key_func, void *user_data);
+void cfgcli_restore_groups(struct l_queue *groups);
void cfgcli_cleanup(void);
@@ -41,6 +41,7 @@
#include "tools/mesh/keys.h"
#include "tools/mesh/remote.h"
+#include "tools/mesh/cfgcli.h"
#include "tools/mesh/mesh-db.h"
#define KEY_IDX_INVALID NET_IDX_INVALID
@@ -254,6 +255,81 @@ static uint16_t node_parse_key(json_object *jarray, int i)
return idx;
}
+static int compare_group_addr(const void *a, const void *b, void *user_data)
+{
+ const struct mesh_group *grp0 = a;
+ const struct mesh_group *grp1 = b;
+
+ if (grp0->addr < grp1->addr)
+ return -1;
+
+ if (grp0->addr > grp1->addr)
+ return 1;
+
+ return 0;
+}
+
+static void load_groups(json_object *jcfg)
+{
+ json_object *jgroups;
+ struct l_queue *groups;
+ int i, sz;
+
+ json_object_object_get_ex(jcfg, "groups", &jgroups);
+
+ if (!jgroups || json_object_get_type(jgroups) != json_type_array)
+ return;
+
+ groups = l_queue_new();
+
+ sz = json_object_array_length(jgroups);
+
+ for (i = 0; i < sz; ++i) {
+ json_object *jgroup, *jval;
+ struct mesh_group *grp;
+ uint16_t addr, addr_len;
+ const char *str;
+
+ jgroup = json_object_array_get_idx(jgroups, i);
+ if (!jgroup)
+ continue;
+
+ if (!json_object_object_get_ex(jgroup, "name", &jval))
+ continue;
+
+ str = json_object_get_string(jval);
+ if (strlen(str) != 10)
+ continue;
+
+ if (sscanf(str + 6, "%04hx", &addr) != 1)
+ continue;
+
+ if (!json_object_object_get_ex(jgroup, "address", &jval))
+ continue;
+
+ str = json_object_get_string(jval);
+ addr_len = strlen(str);
+ if (addr_len != 4 && addr_len != 32)
+ continue;
+
+ if (addr_len == 32 && !IS_VIRTUAL(addr))
+ continue;
+
+ grp = l_new(struct mesh_group, 1);
+
+ if (addr_len == 4)
+ sscanf(str, "%04hx", &grp->addr);
+ else {
+ str2hex(str, 32, grp->label, 16);
+ grp->addr = addr;
+ }
+
+ l_queue_insert(groups, grp, compare_group_addr, NULL);
+ }
+
+ cfgcli_restore_groups(groups);
+}
+
static void load_remotes(json_object *jcfg)
{
json_object *jnodes;
@@ -632,6 +708,45 @@ bool mesh_db_app_key_del(uint16_t app_idx)
return delete_key(cfg->jcfg, "appKeys", app_idx);
}
+bool mesh_db_add_group(struct mesh_group *grp)
+{
+ json_object *jgroup, *jgroups, *jval;
+ char buf[16];
+
+ if (!cfg || !cfg->jcfg)
+ return false;
+
+ if (!json_object_object_get_ex(cfg->jcfg, "groups", &jgroups))
+ return false;
+
+ jgroup = json_object_new_object();
+ if (!jgroup)
+ return false;
+
+ snprintf(buf, 11, "Group_%4.4x", grp->addr);
+ jval = json_object_new_string(buf);
+ json_object_object_add(jgroup, "name", jval);
+
+ if (IS_VIRTUAL(grp->addr)) {
+ if (!add_u8_16(jgroup, grp->label, "address"))
+ goto fail;
+ } else {
+ snprintf(buf, 5, "%4.4x", grp->addr);
+ jval = json_object_new_string(buf);
+ if (!jval)
+ goto fail;
+ json_object_object_add(jgroup, "address", jval);
+ }
+
+ json_object_array_add(jgroups, jgroup);
+
+ return mesh_config_save((struct mesh_config *) cfg, true, NULL, NULL);
+
+fail:
+ json_object_put(jgroup);
+ return false;
+}
+
bool mesh_db_add_node(uint8_t uuid[16], uint8_t num_els, uint16_t unicast,
uint16_t net_idx)
{
@@ -803,6 +918,13 @@ bool mesh_db_create(const char *fname, const uint8_t token[8],
json_object_object_add(jcfg, "appKeys", jarray);
+ jarray = json_object_new_array();
+ if (!jarray)
+ goto fail;
+
+ json_object_object_add(jcfg, "groups", jarray);
+
+
if (!mesh_config_save((struct mesh_config *) cfg, true, NULL, NULL))
goto fail;
@@ -866,6 +988,7 @@ bool mesh_db_load(const char *fname)
goto fail;
load_remotes(jcfg);
+ load_groups(jcfg);
return true;
fail:
@@ -19,6 +19,8 @@
#include "mesh/mesh-config.h"
+struct mesh_group;
+
bool mesh_db_create(const char *fname, const uint8_t token[8],
const char *name);
bool mesh_db_load(const char *fname);
@@ -52,3 +54,4 @@ bool mesh_db_node_model_binding_add(uint16_t unicast, uint8_t ele, bool vendor,
uint32_t mod_id, uint16_t app_idx);
bool mesh_db_node_model_binding_del(uint16_t unicast, uint8_t ele, bool vendor,
uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_add_group(struct mesh_group *grp);