tools/mesh-cfgclient: Store remote node's model bindings
authorInga Stotland <inga.stotland@intel.com>
Thu, 23 Sep 2021 03:25:50 +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 binding after a successful completion
of "bind" or "unbind" 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 485d13b..c3241a9 100644 (file)
@@ -340,7 +340,7 @@ static void print_pub(uint16_t ele_addr, uint32_t mod_id,
                bt_shell_printf("\tModel: %8.8x\n", mod_id);
        else
                bt_shell_printf("\tModel: %4.4x\n",
-                               (uint16_t) (mod_id & 0xffff));
+                                       (uint16_t) (mod_id & ~VENDOR_ID_MASK));
 
        bt_shell_printf("\tApp Key Idx: %u (0x%3.3x)\n", pub->app_idx,
                                                                pub->app_idx);
@@ -552,10 +552,20 @@ static bool msg_recvd(uint16_t src, uint16_t idx, uint8_t *data,
 
                bt_shell_printf("Element Addr\t%4.4x\n", addr);
 
-               print_mod_id(data + 5, len == 9, "");
+               mod_id = print_mod_id(data + 5, len == 9, "");
 
                bt_shell_printf("AppIdx\t\t%u (0x%3.3x)\n ", app_idx, app_idx);
 
+               if (data[0] != MESH_STATUS_SUCCESS || !cmd)
+                       break;
+
+               if (cmd->opcode == OP_MODEL_APP_BIND)
+                       mesh_db_node_model_bind(src, addr, len == 9, mod_id,
+                                                               app_idx);
+               else
+                       mesh_db_node_model_unbind(src, addr, len == 9, mod_id,
+                                                               app_idx);
+
                break;
 
        case OP_NODE_IDENTITY_STATUS:
index 5b161bc..938e52f 100644 (file)
@@ -660,6 +660,162 @@ bool mesh_db_node_ttl_set(uint16_t unicast, uint8_t ttl)
        return save_config();
 }
 
+static json_object *get_element(uint16_t unicast, uint16_t ele_addr)
+{
+       json_object *jnode, *jarray;
+       int i, ele_cnt;
+
+       jnode = get_node_by_unicast(unicast);
+       if (!jnode)
+               return false;
+
+       if (!json_object_object_get_ex(jnode, "elements", &jarray))
+               return NULL;
+
+       if (!jarray || json_object_get_type(jarray) != json_type_array)
+               return NULL;
+
+       ele_cnt = json_object_array_length(jarray);
+
+       for (i = 0; i < ele_cnt; ++i) {
+               json_object *jentry, *jval;
+               int32_t index;
+
+               jentry = json_object_array_get_idx(jarray, i);
+               if (!json_object_object_get_ex(jentry, "index", &jval))
+                       return NULL;
+
+               index = json_object_get_int(jval);
+               if (index > 0xff)
+                       return NULL;
+
+               if (ele_addr == unicast + index)
+                       return jentry;
+       }
+
+       return NULL;
+}
+
+static json_object *get_model(uint16_t unicast, uint16_t ele_addr,
+                                               uint32_t mod_id, bool vendor)
+{
+       json_object *jelement, *jarray;
+       int i, sz;
+
+       jelement = get_element(unicast, ele_addr);
+       if (!jelement)
+               return false;
+
+       if (!json_object_object_get_ex(jelement, "models", &jarray))
+               return NULL;
+
+       if (!jarray || json_object_get_type(jarray) != json_type_array)
+               return NULL;
+
+       if (!vendor)
+               mod_id = mod_id & ~VENDOR_ID_MASK;
+
+       sz = json_object_array_length(jarray);
+
+       for (i = 0; i < sz; ++i) {
+               json_object *jentry, *jval;
+               uint32_t id, len;
+               const char *str;
+
+               jentry = json_object_array_get_idx(jarray, i);
+               if (!json_object_object_get_ex(jentry, "modelId",
+                                                               &jval))
+                       return NULL;
+
+               str = json_object_get_string(jval);
+               len = strlen(str);
+               if (len != 4 && len != 8)
+                       return NULL;
+
+               if ((len == 4 && vendor) || (len == 8 && !vendor))
+                       continue;
+
+               if (sscanf(str, "%08x", &id) != 1)
+                       return NULL;
+
+               if (id == mod_id)
+                       return jentry;
+       }
+
+       return NULL;
+}
+
+static void jarray_int_del(json_object *jarray, int val)
+{
+       int i, sz = json_object_array_length(jarray);
+
+       for (i = 0; i < sz; ++i) {
+               json_object *jentry;
+
+               jentry = json_object_array_get_idx(jarray, i);
+
+               if (val == json_object_get_int(jentry)) {
+                       json_object_array_del_idx(jarray, i, 1);
+                       return;
+               }
+       }
+}
+
+static bool update_model_int_array(uint16_t unicast, uint16_t ele_addr,
+                                       bool vendor, uint32_t mod_id,
+                                       int val, const char *keyword, bool add)
+{
+       json_object *jarray, *jmod, *jvalue;
+
+       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_int_del(jarray, val);
+
+       if (!add)
+               return true;
+
+       jvalue = json_object_new_int(val);
+       if (!jvalue)
+               return false;
+
+       json_object_array_add(jarray, jvalue);
+
+       return save_config();
+}
+
+bool mesh_db_node_model_bind(uint16_t unicast, uint16_t ele_addr, bool vendor,
+                                       uint32_t mod_id, uint16_t app_idx)
+{
+       char buf[5];
+
+       snprintf(buf, 5, "%4.4x", app_idx);
+
+       return update_model_int_array(unicast, ele_addr, vendor, mod_id,
+                                               (int) app_idx, "bind", true);
+}
+
+bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor,
+                                       uint32_t mod_id, uint16_t app_idx)
+{
+       char buf[5];
+
+       snprintf(buf, 5, "%4.4x", app_idx);
+
+       return update_model_int_array(unicast, ele_addr, vendor, mod_id,
+                                               (int) app_idx, "bind", false);
+}
+
 static void jarray_key_del(json_object *jarray, int16_t idx)
 {
        int i, sz = json_object_array_length(jarray);
@@ -1174,7 +1330,7 @@ bool mesh_db_del_node(uint16_t unicast)
 
 static json_object *init_model(uint16_t mod_id)
 {
-       json_object *jmod;
+       json_object *jmod, *jarray;
 
        jmod = json_object_new_object();
 
@@ -1183,12 +1339,15 @@ static json_object *init_model(uint16_t mod_id)
                return NULL;
        }
 
+       jarray = json_object_new_array();
+       json_object_object_add(jmod, "bind", jarray);
+
        return jmod;
 }
 
 static json_object *init_vendor_model(uint32_t mod_id)
 {
-       json_object *jmod;
+       json_object *jmod, *jarray;
 
        jmod = json_object_new_object();
 
@@ -1197,6 +1356,9 @@ static json_object *init_vendor_model(uint32_t mod_id)
                return NULL;
        }
 
+       jarray = json_object_new_array();
+       json_object_object_add(jmod, "bind", jarray);
+
        return jmod;
 }
 
index c1bcb3a..c3ee814 100644 (file)
@@ -44,9 +44,9 @@ 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,
+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_binding_del(uint16_t unicast, uint8_t ele, bool vendor,
+bool mesh_db_node_model_unbind(uint16_t unicast, uint16_t ele_addr, bool vendor,
                                        uint32_t mod_id, uint16_t app_idx);
 struct l_queue *mesh_db_load_groups(void);
 bool mesh_db_add_group(struct mesh_group *grp);