tools/mesh-cfgclient: Store remote node's model subs
authorInga Stotland <inga.stotland@intel.com>
Thu, 23 Sep 2021 03:25:51 +0000 (20:25 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:37 +0000 (19:08 +0530)
Update remote node's model subscriptions after a successful completion
of "sub-add", "sub-del", "sub-wrt" and "sub-del_all" commands.

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

index c3241a9..71bf2e7 100644 (file)
@@ -387,14 +387,21 @@ static void print_appkey_list(uint16_t len, uint8_t *data)
        }
 }
 
+static bool match_group_addr(const void *a, const void *b)
+{
+       const struct mesh_group *grp = a;
+       uint16_t addr = L_PTR_TO_UINT(b);
+
+       return grp->addr == addr;
+}
+
 static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
                                                        uint16_t len)
 {
-       uint32_t opcode;
+       uint32_t opcode, mod_id;
        const struct cfg_cmd *cmd;
-       uint16_t app_idx, net_idx, addr;
-       uint16_t ele_addr;
-       uint32_t mod_id;
+       uint16_t app_idx, net_idx, addr, ele_addr;
+       struct mesh_group *grp;
        struct model_pub pub;
        int n;
        struct pending_req *req;
@@ -664,10 +671,53 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
                addr = get_le16(data + 3);
                bt_shell_printf("Element Addr\t%4.4x\n", ele_addr);
 
-               print_mod_id(data + 5, len == 9, "");
+               mod_id = print_mod_id(data + 5, len == 9, "");
 
                bt_shell_printf("Subscr Addr\t%4.4x\n", addr);
 
+               grp = l_queue_find(groups, match_group_addr,
+                                                       L_UINT_TO_PTR(addr));
+
+               if (data[0] != MESH_STATUS_SUCCESS || !cmd)
+                       return true;
+
+               switch (cmd->opcode) {
+               default:
+                       return true;
+               case OP_CONFIG_MODEL_SUB_ADD:
+                       mesh_db_node_model_add_sub(src, ele_addr, len == 9,
+                                                               mod_id, addr);
+                       break;
+               case OP_CONFIG_MODEL_SUB_DELETE:
+                       mesh_db_node_model_del_sub(src, ele_addr, len == 9,
+                                                               mod_id, addr);
+                       break;
+               case OP_CONFIG_MODEL_SUB_OVERWRITE:
+                       mesh_db_node_model_overwrt_sub(src, ele_addr, len == 9,
+                                                               mod_id, addr);
+                       break;
+               case OP_CONFIG_MODEL_SUB_DELETE_ALL:
+                       mesh_db_node_model_del_sub_all(src, ele_addr, len == 9,
+                                                                       mod_id);
+                       break;
+               case OP_CONFIG_MODEL_SUB_VIRT_ADD:
+                       if (grp)
+                               mesh_db_node_model_add_sub_virt(src, ele_addr,
+                                               len == 9, mod_id, grp->label);
+                       break;
+               case OP_CONFIG_MODEL_SUB_VIRT_DELETE:
+                       if (grp)
+                               mesh_db_node_model_del_sub_virt(src, ele_addr,
+                                               len == 9, mod_id, grp->label);
+                       break;
+               case OP_CONFIG_MODEL_SUB_VIRT_OVERWRITE:
+                       if (grp)
+                               mesh_db_node_model_overwrt_sub_virt(src,
+                                                       ele_addr, len == 9,
+                                                       mod_id, grp->label);
+                       break;
+               }
+
                break;
 
        /* Per Mesh Profile 4.3.2.27 */
@@ -820,14 +870,6 @@ static uint32_t read_input_parameters(int argc, char *argv[])
        return i;
 }
 
-static bool match_group_addr(const void *a, const void *b)
-{
-       const struct mesh_group *grp = a;
-       uint16_t addr = L_PTR_TO_UINT(b);
-
-       return grp->addr == addr;
-}
-
 static int compare_group_addr(const void *a, const void *b, void *user_data)
 {
        const struct mesh_group *grp0 = a;
index 938e52f..d8f11ef 100644 (file)
@@ -816,6 +816,178 @@ bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor,
                                                (int) app_idx, "bind", false);
 }
 
+static void jarray_string_del(json_object *jarray, const char *str, size_t len)
+{
+       int i, sz = json_object_array_length(jarray);
+
+       for (i = 0; i < sz; ++i) {
+               json_object *jentry;
+               char *str_entry;
+
+               jentry = json_object_array_get_idx(jarray, i);
+               str_entry = (char *)json_object_get_string(jentry);
+
+               if (str_entry && (strlen(str_entry) == len) &&
+                                               !strncmp(str, str_entry, len)) {
+                       json_object_array_del_idx(jarray, i, 1);
+                       return;
+               }
+       }
+}
+
+static bool update_model_string_array(uint16_t unicast, uint16_t ele_addr,
+                                               bool vendor, uint32_t mod_id,
+                                               const char *str, uint32_t len,
+                                               const char *keyword, bool add)
+{
+       json_object *jarray, *jmod, *jstring;
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       jmod = get_model(unicast, ele_addr, mod_id, vendor);
+       if (!jmod)
+               return false;
+
+       if (!json_object_object_get_ex(jmod, keyword, &jarray))
+               return false;
+
+       if (!jarray || json_object_get_type(jarray) != json_type_array)
+               return false;
+
+       jarray_string_del(jarray, str, len);
+
+       if (!add)
+               return true;
+
+       jstring = json_object_new_string(str);
+       if (!jstring)
+               return false;
+
+       json_object_array_add(jarray, jstring);
+
+       return save_config();
+}
+
+bool mesh_db_node_model_add_sub(uint16_t unicast, uint16_t ele, bool vendor,
+                                               uint32_t mod_id, uint16_t addr)
+{
+       char buf[5];
+
+       snprintf(buf, 5, "%4.4x", addr);
+
+       return update_model_string_array(unicast, ele, vendor, mod_id, buf, 4,
+                                                       "subscribe", true);
+}
+
+bool mesh_db_node_model_del_sub(uint16_t unicast, uint16_t ele, bool vendor,
+                                               uint32_t mod_id, uint16_t addr)
+{
+       char buf[5];
+
+       snprintf(buf, 5, "%4.4x", addr);
+
+       return update_model_string_array(unicast, ele, vendor, mod_id, buf, 4,
+                                                       "subscribe", false);
+}
+
+bool mesh_db_node_model_add_sub_virt(uint16_t unicast, uint16_t ele,
+                                               bool vendor, uint32_t mod_id,
+                                                               uint8_t *label)
+{
+       char buf[33];
+
+       hex2str(label, 16, buf, sizeof(buf));
+
+       return update_model_string_array(unicast, ele, vendor, mod_id, buf, 32,
+                                                       "subscribe", true);
+
+}
+
+bool mesh_db_node_model_del_sub_virt(uint16_t unicast, uint16_t ele,
+                                               bool vendor, uint32_t mod_id,
+                                                               uint8_t *label)
+{
+       char buf[33];
+
+       hex2str(label, 16, buf, sizeof(buf));
+
+       return update_model_string_array(unicast, ele, vendor, mod_id, buf, 32,
+                                                       "subscribe", false);
+}
+
+static json_object *delete_subs(uint16_t unicast, uint16_t ele, bool vendor,
+                                                               uint32_t mod_id)
+{
+       json_object *jarray, *jmod;
+
+       if (!cfg || !cfg->jcfg)
+               return NULL;
+
+       jmod = get_model(unicast, ele, mod_id, vendor);
+       if (!jmod)
+               return NULL;
+
+       json_object_object_del(jmod, "subscribe");
+
+       jarray = json_object_new_array();
+       if (!jarray)
+               return NULL;
+
+       json_object_object_add(jmod, "subscribe", jarray);
+
+       return jarray;
+}
+
+bool mesh_db_node_model_del_sub_all(uint16_t unicast, uint16_t ele, bool vendor,
+                                                               uint32_t mod_id)
+{
+
+       if (!delete_subs(unicast, ele, vendor, mod_id))
+               return false;
+
+       return save_config();
+}
+
+static bool sub_overwrite(uint16_t unicast, uint16_t ele, bool vendor,
+                                               uint32_t mod_id, char *buf)
+{
+       json_object *jarray, *jstring;
+
+       jarray = delete_subs(unicast, ele, vendor, mod_id);
+       if (!jarray)
+               return false;
+
+       jstring = json_object_new_string(buf);
+       if (!jstring)
+               return false;
+
+       json_object_array_add(jarray, jstring);
+
+       return save_config();
+}
+
+bool mesh_db_node_model_overwrt_sub(uint16_t unicast, uint16_t ele, bool vendor,
+                                               uint32_t mod_id, uint16_t addr)
+{
+       char buf[5];
+
+       snprintf(buf, 5, "%4.4x", addr);
+
+       return sub_overwrite(unicast, ele, vendor, mod_id, buf);
+}
+
+bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele,
+                                               bool vendor, uint32_t mod_id,
+                                                               uint8_t *label)
+{
+       char buf[33];
+
+       hex2str(label, 16, buf, sizeof(buf));
+
+       return sub_overwrite(unicast, ele, vendor, mod_id, buf);
+}
+
 static void jarray_key_del(json_object *jarray, int16_t idx)
 {
        int i, sz = json_object_array_length(jarray);
@@ -1342,6 +1514,9 @@ static json_object *init_model(uint16_t mod_id)
        jarray = json_object_new_array();
        json_object_object_add(jmod, "bind", jarray);
 
+       jarray = json_object_new_array();
+       json_object_object_add(jmod, "subscribe", jarray);
+
        return jmod;
 }
 
@@ -1359,6 +1534,9 @@ static json_object *init_vendor_model(uint32_t mod_id)
        jarray = json_object_new_array();
        json_object_object_add(jmod, "bind", jarray);
 
+       jarray = json_object_new_array();
+       json_object_object_add(jmod, "subscribe", jarray);
+
        return jmod;
 }
 
index c3ee814..384376c 100644 (file)
@@ -48,6 +48,23 @@ bool mesh_db_node_model_bind(uint16_t unicast, uint16_t ele_addr, bool vendor,
                                        uint32_t mod_id, uint16_t app_idx);
 bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor,
                                        uint32_t mod_id, uint16_t app_idx);
+bool mesh_db_node_model_add_sub(uint16_t unicast, uint16_t ele, bool vendor,
+                                               uint32_t mod_id, uint16_t addr);
+bool mesh_db_node_model_del_sub(uint16_t unicast, uint16_t ele, bool vendor,
+                                               uint32_t mod_id, uint16_t addr);
+bool mesh_db_node_model_overwrt_sub(uint16_t unicast, uint16_t ele, bool vendor,
+                                               uint32_t mod_id, uint16_t addr);
+bool mesh_db_node_model_add_sub_virt(uint16_t unicast, uint16_t ele,
+                                               bool vendor, uint32_t mod_id,
+                                                               uint8_t *label);
+bool mesh_db_node_model_del_sub_virt(uint16_t unicast, uint16_t ele,
+                                               bool vendor, uint32_t mod_id,
+                                                               uint8_t *label);
+bool mesh_db_node_model_overwrt_sub_virt(uint16_t unicast, uint16_t ele,
+                                               bool vendor, uint32_t mod_id,
+                                                               uint8_t *label);
+bool mesh_db_node_model_del_sub_all(uint16_t unicast, uint16_t ele, bool vendor,
+                                                       uint32_t mod_id);
 struct l_queue *mesh_db_load_groups(void);
 bool mesh_db_add_group(struct mesh_group *grp);
 bool mesh_db_add_rejected_addr(uint16_t unicast, uint32_t iv_index);