tools/mesh-cfgclient: Keep track of updated keys
authorInga Stotland <inga.stotland@intel.com>
Thu, 23 Sep 2021 03:25:47 +0000 (20:25 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:37 +0000 (19:08 +0530)
Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
tools/mesh/cfgcli.c
tools/mesh/mesh-db.c
tools/mesh/mesh-db.h
tools/mesh/remote.c
tools/mesh/remote.h

index d8eee4e..485d13b 100644 (file)
@@ -447,13 +447,12 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
                if (!cmd)
                        break;
 
-               if (cmd->opcode == OP_APPKEY_ADD) {
-                       if (remote_add_app_key(src, app_idx))
-                               mesh_db_node_app_key_add(src, app_idx);
-               } else if (cmd->opcode == OP_APPKEY_DELETE) {
-                       if (remote_del_app_key(src, app_idx))
-                               mesh_db_node_app_key_del(src, app_idx);
-               }
+               if (cmd->opcode == OP_APPKEY_ADD)
+                       remote_add_app_key(src, app_idx, true);
+               else if (cmd->opcode == OP_APPKEY_DELETE)
+                       remote_del_app_key(src, app_idx);
+               else if (cmd->opcode == OP_APPKEY_UPDATE)
+                       remote_update_app_key(src, app_idx, true, true);
 
                break;
 
@@ -492,13 +491,12 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
                if (!cmd)
                        break;
 
-               if (cmd->opcode == OP_NETKEY_ADD) {
-                       if (remote_add_net_key(src, net_idx))
-                               mesh_db_node_net_key_add(src, net_idx);
-               } else if (cmd->opcode == OP_NETKEY_DELETE) {
-                       if (remote_del_net_key(src, net_idx))
-                               mesh_db_node_net_key_del(src, net_idx);
-               }
+               if (cmd->opcode == OP_NETKEY_ADD)
+                       remote_add_net_key(src, net_idx, true);
+               else if (cmd->opcode == OP_NETKEY_DELETE)
+                       remote_del_net_key(src, net_idx);
+               else if (cmd->opcode == OP_NETKEY_UPDATE)
+                       remote_update_net_key(src, net_idx, true, true);
 
                break;
 
@@ -534,6 +532,13 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
 
                bt_shell_printf("\tNetKey %u (0x%3.3x)\n", net_idx, net_idx);
                bt_shell_printf("\tKR Phase %2.2x\n", data[3]);
+
+               if (data[0] != MESH_STATUS_SUCCESS)
+                       return true;
+
+               if (data[3] == KEY_REFRESH_PHASE_NONE)
+                       remote_finish_key_refresh(src, net_idx);
+
                break;
 
        case OP_MODEL_APP_STATUS:
index f6682dc..d01bf32 100644 (file)
@@ -202,6 +202,38 @@ static bool write_int(json_object *jobj, const char *keyword, int val)
        return true;
 }
 
+static bool get_bool(json_object *jobj, const char *keyword, bool *value)
+{
+       json_object *jvalue;
+
+       if (!json_object_object_get_ex(jobj, keyword, &jvalue))
+               return false;
+
+       if (json_object_get_type(jvalue) != json_type_boolean) {
+               l_error("Error: %s should contain a boolean value\n",
+                                                               keyword);
+               return false;
+       }
+
+       *value = json_object_get_boolean(jvalue);
+
+       return true;
+}
+
+static bool write_bool(json_object *jobj, const char *keyword, bool val)
+{
+       json_object *jval;
+
+       json_object_object_del(jobj, keyword);
+
+       jval = json_object_new_boolean(val);
+       if (!jval)
+               return false;
+
+       json_object_object_add(jobj, keyword, jval);
+       return true;
+}
+
 static json_object *get_key_object(json_object *jarray, uint16_t idx)
 {
        int i, sz = json_object_array_length(jarray);
@@ -349,6 +381,20 @@ static uint16_t node_parse_key(json_object *jarray, int i)
        return (uint16_t)idx;
 }
 
+static bool node_check_key_updated(json_object *jarray, int i, bool *updated)
+{
+       json_object *jkey;
+
+       jkey = json_object_array_get_idx(jarray, i);
+       if (!jkey)
+               return false;
+
+       if (!get_bool(jkey, "updated", updated))
+               return false;
+
+       return true;
+}
+
 static int compare_group_addr(const void *a, const void *b, void *user_data)
 {
        const struct mesh_group *grp0 = a;
@@ -485,10 +531,17 @@ static void load_remotes(json_object *jcfg)
                remote_add_node((const uint8_t *)uuid, unicast, ele_cnt,
                                                                key_idx);
                for (j = 1; j < key_cnt; j++) {
+                       bool updated = false;
+
                        key_idx = node_parse_key(jarray, j);
 
-                       if (key_idx != KEY_IDX_INVALID)
-                               remote_add_net_key(unicast, key_idx);
+                       if (key_idx == KEY_IDX_INVALID)
+                               continue;
+
+                       remote_add_net_key(unicast, key_idx, false);
+
+                       node_check_key_updated(jarray, j, &updated);
+                       remote_update_net_key(unicast, key_idx, updated, false);
                }
 
                json_object_object_get_ex(jnode, "appKeys", &jarray);
@@ -498,10 +551,17 @@ static void load_remotes(json_object *jcfg)
                key_cnt = json_object_array_length(jarray);
 
                for (j = 0; j < key_cnt; j++) {
+                       bool updated = false;
+
                        key_idx = node_parse_key(jarray, j);
 
-                       if (key_idx != KEY_IDX_INVALID)
-                               remote_add_app_key(unicast, key_idx);
+                       if (key_idx == KEY_IDX_INVALID)
+                               continue;
+
+                       remote_add_app_key(unicast, key_idx, false);
+
+                       node_check_key_updated(jarray, j, &updated);
+                       remote_update_app_key(unicast, key_idx, updated, false);
                }
 
                load_composition(jnode, unicast);
@@ -556,28 +616,19 @@ static bool add_node_key(json_object *jobj, const char *desc, uint16_t idx)
 
        jkey = json_object_new_object();
 
-       if (!write_int(jkey, "index", (int)idx)) {
-               json_object_put(jkey);
-               return false;
-       }
+       if (!write_int(jkey, "index", (int)idx))
+               goto fail;
+
+       if (!write_bool(jkey, "updated", false))
+               goto fail;
 
        json_object_array_add(jarray, jkey);
 
        return save_config();
-}
-
-bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx)
-{
-       json_object *jnode;
-
-       if (!cfg || !cfg->jcfg)
-               return false;
 
-       jnode = get_node_by_unicast(unicast);
-       if (!jnode)
-               return false;
-
-       return add_node_key(jnode, "netKeys", idx);
+fail:
+       json_object_put(jkey);
+       return false;
 }
 
 bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl)
@@ -630,6 +681,20 @@ static bool delete_key(json_object *jobj, const char *desc, uint16_t idx)
        return save_config();
 }
 
+bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx)
+{
+       json_object *jnode;
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       jnode = get_node_by_unicast(unicast);
+       if (!jnode)
+               return false;
+
+       return add_node_key(jnode, "netKeys", idx);
+}
+
 bool mesh_db_node_net_key_del(uint16_t unicast, uint16_t net_idx)
 {
        json_object *jnode;
@@ -644,6 +709,45 @@ bool mesh_db_node_net_key_del(uint16_t unicast, uint16_t net_idx)
        return delete_key(jnode, "netKeys", net_idx);
 }
 
+static bool key_update(uint16_t unicast, int16_t idx, bool updated,
+                                                       const char *desc)
+{
+       json_object *jnode, *jarray;
+       int i, sz;
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       jnode = get_node_by_unicast(unicast);
+       if (!jnode)
+               return false;
+
+       if (!json_object_object_get_ex(jnode, desc, &jarray))
+               return false;
+
+       sz = json_object_array_length(jarray);
+
+       for (i = 0; i < sz; ++i) {
+               json_object *jentry;
+               int val;
+
+               jentry = json_object_array_get_idx(jarray, i);
+
+               if (!get_int(jentry, "index", &val))
+                       continue;
+
+               if ((val == idx) && write_bool(jentry, "updated", updated))
+                       return save_config();
+       }
+
+       return false;
+}
+
+bool mesh_db_node_net_key_update(uint16_t unicast, uint16_t idx, bool updated)
+{
+       return key_update(unicast, idx, updated, "netKeys");
+}
+
 bool mesh_db_node_app_key_add(uint16_t unicast, uint16_t idx)
 {
        json_object *jnode;
@@ -672,6 +776,11 @@ bool mesh_db_node_app_key_del(uint16_t unicast, uint16_t idx)
        return delete_key(jnode, "appKeys", idx);
 }
 
+bool mesh_db_node_app_key_update(uint16_t unicast, uint16_t idx, bool updated)
+{
+       return key_update(unicast, idx, updated, "appKeys");
+}
+
 static bool load_keys(json_object *jobj)
 {
        json_object *jarray, *jentry;
index efd5795..c1bcb3a 100644 (file)
@@ -38,8 +38,10 @@ bool mesh_db_node_set_net_transmit(uint16_t unicast, uint8_t cnt,
                                                        uint16_t interval);
 bool mesh_db_node_net_key_add(uint16_t unicast, uint16_t idx);
 bool mesh_db_node_net_key_del(uint16_t unicast, uint16_t idx);
+bool mesh_db_node_net_key_update(uint16_t unicast, uint16_t idx, bool updated);
 bool mesh_db_node_app_key_add(uint16_t unicast, uint16_t idx);
 bool mesh_db_node_app_key_del(uint16_t unicast, uint16_t idx);
+bool mesh_db_node_app_key_update(uint16_t unicast, uint16_t idx, bool updated);
 bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl);
 bool mesh_db_node_write_mode(uint16_t unicast, const char *keyword, int value);
 bool mesh_db_node_model_binding_add(uint16_t unicast, uint8_t ele, bool vendor,
index e60a368..5f598cb 100644 (file)
 
 #define abs_diff(a, b) ((a) > (b) ? (a) - (b) : (b) - (a))
 
+struct remote_key {
+       uint16_t idx;
+       bool updated;
+};
+
 struct remote_node {
        uint16_t unicast;
        struct l_queue *net_keys;
@@ -42,20 +47,6 @@ struct rejected_addr {
 static struct l_queue *nodes;
 static struct l_queue *reject_list;
 
-static bool key_present(struct l_queue *keys, uint16_t app_idx)
-{
-       const struct l_queue_entry *l;
-
-       for (l = l_queue_get_entries(keys); l; l = l->next) {
-               uint16_t idx = L_PTR_TO_UINT(l->data);
-
-               if (idx == app_idx)
-                       return true;
-       }
-
-       return false;
-}
-
 static int compare_mod_id(const void *a, const void *b, void *user_data)
 {
        uint32_t id1 = L_PTR_TO_UINT(a);
@@ -102,12 +93,20 @@ static bool match_node_addr(const void *a, const void *b)
        return false;
 }
 
+static bool match_key(const void *a, const void *b)
+{
+       const struct remote_key *key = a;
+       uint16_t idx = L_PTR_TO_UINT(b);
+
+       return (key->idx == idx);
+}
+
 static bool match_bound_key(const void *a, const void *b)
 {
-       uint16_t app_idx = L_PTR_TO_UINT(a);
+       const struct remote_key *app_key = a;
        uint16_t net_idx = L_PTR_TO_UINT(b);
 
-       return (net_idx == keys_get_bound_key(app_idx));
+       return (net_idx == keys_get_bound_key(app_key->idx));
 }
 
 uint8_t remote_del_node(uint16_t unicast)
@@ -142,6 +141,7 @@ bool remote_add_node(const uint8_t uuid[16], uint16_t unicast,
                                        uint8_t ele_cnt, uint16_t net_idx)
 {
        struct remote_node *rmt;
+       struct remote_key *key;
 
        rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(unicast));
        if (rmt)
@@ -153,7 +153,10 @@ bool remote_add_node(const uint8_t uuid[16], uint16_t unicast,
        rmt->num_ele = ele_cnt;
        rmt->net_keys = l_queue_new();
 
-       l_queue_push_tail(rmt->net_keys, L_UINT_TO_PTR(net_idx));
+       key = l_new(struct remote_key, 1);
+       key->idx = net_idx;
+
+       l_queue_push_tail(rmt->net_keys, key);
 
        rmt->els = l_new(struct l_queue *, ele_cnt);
 
@@ -161,6 +164,7 @@ bool remote_add_node(const uint8_t uuid[16], uint16_t unicast,
                nodes = l_queue_new();
 
        l_queue_insert(nodes, rmt, compare_unicast, NULL);
+
        return true;
 }
 
@@ -188,49 +192,84 @@ bool remote_set_model(uint16_t unicast, uint8_t ele_idx, uint32_t mod_id,
        return true;
 }
 
-bool remote_add_net_key(uint16_t addr, uint16_t net_idx)
+bool remote_add_net_key(uint16_t addr, uint16_t net_idx, bool save)
 {
        struct remote_node *rmt;
+       struct remote_key *key;
 
        rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr));
        if (!rmt)
                return false;
 
-       if (key_present(rmt->net_keys, net_idx))
-               return false;
+       if (l_queue_find(rmt->net_keys, match_key, L_UINT_TO_PTR(net_idx)))
+               return true;
 
-       l_queue_push_tail(rmt->net_keys, L_UINT_TO_PTR(net_idx));
-       return true;
+       key = l_new(struct remote_key, 1);
+       key->idx = net_idx;
+
+       l_queue_push_tail(rmt->net_keys, key);
+
+       if (save)
+               return mesh_db_node_net_key_add(addr, net_idx);
+       else
+               return true;
 }
 
 bool remote_del_net_key(uint16_t addr, uint16_t net_idx)
 {
        struct remote_node *rmt;
-       void *data;
+       struct remote_key *key;
 
        rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr));
        if (!rmt)
                return false;
 
-       if (!l_queue_remove(rmt->net_keys, L_UINT_TO_PTR(net_idx)))
+       key = l_queue_remove_if(rmt->net_keys, match_key,
+                                                       L_UINT_TO_PTR(net_idx));
+       if (!key)
                return false;
 
-       data = l_queue_remove_if(rmt->app_keys, match_bound_key,
+       mesh_db_node_net_key_del(addr, net_idx);
+
+       l_free(key);
+       key = l_queue_remove_if(rmt->app_keys, match_bound_key,
                                                L_UINT_TO_PTR(net_idx));
-       while (data) {
-               uint16_t app_idx = (uint16_t) L_PTR_TO_UINT(data);
 
-               mesh_db_node_app_key_del(rmt->unicast, app_idx);
-               data = l_queue_remove_if(rmt->app_keys, match_bound_key,
+       while (key) {
+               mesh_db_node_app_key_del(rmt->unicast, key->idx);
+               l_free(key);
+
+               key = l_queue_remove_if(rmt->app_keys, match_bound_key,
                                                L_UINT_TO_PTR(net_idx));
        }
 
        return true;
 }
 
-bool remote_add_app_key(uint16_t addr, uint16_t app_idx)
+bool remote_update_net_key(uint16_t addr, uint16_t net_idx, bool update,
+                                                               bool save)
+{
+       struct remote_node *rmt;
+       struct remote_key *key;
+
+       rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr));
+       if (!rmt)
+               return false;
+
+       key = l_queue_find(rmt->net_keys, match_key,
+                                               L_UINT_TO_PTR(net_idx));
+       key->updated = update;
+
+       if (save)
+               return mesh_db_node_net_key_update(addr, net_idx, update);
+       else
+               return true;
+}
+
+bool remote_add_app_key(uint16_t addr, uint16_t app_idx, bool save)
 {
        struct remote_node *rmt;
+       struct remote_key *key;
 
        rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr));
        if (!rmt)
@@ -239,44 +278,105 @@ bool remote_add_app_key(uint16_t addr, uint16_t app_idx)
        if (!rmt->app_keys)
                rmt->app_keys = l_queue_new();
 
-       if (key_present(rmt->app_keys, app_idx))
-               return false;
+       if (l_queue_find(rmt->app_keys, match_key, L_UINT_TO_PTR(app_idx)))
+               return true;
 
-       l_queue_push_tail(rmt->app_keys, L_UINT_TO_PTR(app_idx));
-       return true;
+       key = l_new(struct remote_key, 1);
+       key->idx = app_idx;
+
+       l_queue_push_tail(rmt->app_keys, key);
+
+       if (save)
+               return mesh_db_node_app_key_add(addr, app_idx);
+       else
+               return true;
 }
 
 bool remote_del_app_key(uint16_t addr, uint16_t app_idx)
 {
        struct remote_node *rmt;
+       struct remote_key *key;
+
+       rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr));
+       if (!rmt)
+               return false;
+
+       key = l_queue_remove_if(rmt->app_keys, match_key,
+                                               L_UINT_TO_PTR(app_idx));
+       l_free(key);
+
+       return mesh_db_node_app_key_del(addr, app_idx);
+}
+
+bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update,
+                                                               bool save)
+{
+       struct remote_node *rmt;
+       struct remote_key *key;
 
        rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr));
        if (!rmt)
                return false;
 
-       return l_queue_remove(rmt->app_keys, L_UINT_TO_PTR(app_idx));
+       key = l_queue_find(rmt->app_keys, match_key,
+                                               L_UINT_TO_PTR(app_idx));
+       key->updated = update;
+
+       if (save)
+               return mesh_db_node_app_key_update(addr, app_idx, update);
+       else
+               return true;
+}
+
+void remote_finish_key_refresh(uint16_t addr, uint16_t net_idx)
+{
+       struct remote_node *rmt;
+       struct remote_key *key;
+       const struct l_queue_entry *l;
+
+       rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr));
+       if (!rmt)
+               return;
+
+       if (!remote_update_net_key(addr, net_idx, false, true))
+               return;
+
+       l = l_queue_get_entries(rmt->app_keys);
+
+       for (; l; l = l->next) {
+               key = l->data;
+
+               if (net_idx != keys_get_bound_key(key->idx))
+                       continue;
+
+               key->updated = false;
+
+               mesh_db_node_app_key_update(addr, key->idx, false);
+       }
+
 }
 
 uint16_t remote_get_subnet_idx(uint16_t addr)
 {
        struct remote_node *rmt;
-       uint32_t net_idx;
+       struct remote_key *key;
 
        rmt = l_queue_find(nodes, match_node_addr, L_UINT_TO_PTR(addr));
 
        if (!rmt || l_queue_isempty(rmt->net_keys))
                return NET_IDX_INVALID;
 
-       net_idx = L_PTR_TO_UINT(l_queue_peek_head(rmt->net_keys));
+       key = l_queue_peek_head(rmt->net_keys);
 
-       return (uint16_t) net_idx;
+       return key->idx;
 }
 
-static void print_key(void *key, void *user_data)
+static void print_key(void *data, void *user_data)
 {
-       uint16_t idx = L_PTR_TO_UINT(key);
+       struct remote_key *key = data;
 
-       bt_shell_printf("%u (0x%3.3x), ", idx, idx);
+       bt_shell_printf("%u (0x%3.3x) %s, ", key->idx, key->idx,
+                                               key->updated ? ", updated":"");
 }
 
 static void print_model(void *model, void *user_data)
index 8ecb097..9feee86 100644 (file)
@@ -16,9 +16,14 @@ bool remote_set_model(uint16_t unicast, uint8_t ele_idx, uint32_t mod_id,
 void remote_add_rejected_address(uint16_t addr, uint32_t iv_index, bool save);
 void remote_clear_rejected_addresses(uint32_t iv_index);
 uint16_t remote_get_next_unicast(uint16_t low, uint16_t high, uint8_t ele_cnt);
-bool remote_add_net_key(uint16_t addr, uint16_t net_idx);
+bool remote_add_net_key(uint16_t addr, uint16_t net_idx, bool save);
 bool remote_del_net_key(uint16_t addr, uint16_t net_idx);
-bool remote_add_app_key(uint16_t addr, uint16_t app_idx);
+bool remote_update_net_key(uint16_t addr, uint16_t net_idx, bool update,
+                                                               bool save);
+bool remote_add_app_key(uint16_t addr, uint16_t app_idx, bool save);
+bool remote_update_app_key(uint16_t addr, uint16_t app_idx, bool update,
+                                                               bool save);
+void remote_finish_key_refresh(uint16_t addr, uint16_t net_idx);
 bool remote_del_app_key(uint16_t addr, uint16_t app_idx);
 uint16_t remote_get_subnet_idx(uint16_t addr);
 void remote_print_node(uint16_t addr);