Fix the coverity issues
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / mesh / bt-service-mesh-cdb.c
index 2648190..6771eda 100644 (file)
@@ -336,12 +336,14 @@ static json_object *__mesh_get_node_by_uuid(json_object *jcfg,
        int i, sz;
 
        _bt_mesh_util_convert_hex_to_string(uuid, 16, buf, sizeof(buf));
+       BT_INFO("Mesh: Find Node with UUID [%s]", buf);
 
        json_object_object_get_ex(jcfg, "nodes", &jarray);
        if (!jarray || json_object_get_type(jarray) != json_type_array)
                return NULL;
 
        sz = json_object_array_length(jarray);
+       BT_INFO("Mesh: Total nodes present in CDB [%d]", sz);
 
        for (i = 0; i < sz; ++i) {
                json_object *jentry, *jval;
@@ -354,6 +356,8 @@ static json_object *__mesh_get_node_by_uuid(json_object *jcfg,
                str = json_object_get_string(jval);
                if (strlen(str) != 32)
                        continue;
+               BT_INFO("Mesh: Got one node with UUID [%s]", str);
+               BT_INFO("Mesh: Match with uuid [%s]", buf);
 
                if (!g_strcmp0(buf, str))
                        return jentry;
@@ -399,7 +403,7 @@ static bool __mesh_get_token(json_object *jobj, uint8_t token[8])
        json_object *jval;
        const char *str;
 
-       if (!json_object_object_get_ex(jobj, "token", &jval))
+       if (!json_object_object_get_ex(jobj, "Network_Token", &jval))
                return false;
 
        str = json_object_get_string(jval);
@@ -414,7 +418,7 @@ static bool __mesh_get_uuid(json_object *jobj, uint8_t uuid[16])
        json_object *jval;
        const char *str;
 
-       if (!json_object_object_get_ex(jobj, "uuid", &jval))
+       if (!json_object_object_get_ex(jobj, "Config_Node_UUID", &jval))
                return false;
 
        str = json_object_get_string(jval);
@@ -457,8 +461,10 @@ static bool __mesh_add_u8_16(json_object *jobj,
 void _bt_mesh_conf_free(_bt_mesh_cdb_t *cfg)
 {
        g_free(cfg->cfg_fname);
+       g_free(cfg->owner);
        g_free(cfg->app_cred);
        json_object_put(cfg->jcfg);
+       g_slist_free_full(cfg->groups, g_free);
        g_free(cfg);
 }
 
@@ -487,6 +493,8 @@ static bool __mesh_jarray_group_delete(json_object *jarray, uint16_t group_addr)
                        continue;
 
                str = json_object_get_string(jval);
+               if (!str)
+                       continue;
                memcpy(buf, str + 6, 5);
                BT_INFO("Mesh: JSON Group string:[%s]", buf);
                if (sscanf(buf, "%04hx", &addr) != 1)
@@ -586,6 +594,132 @@ bool _bt_mesh_conf_delete_application_key(_bt_mesh_cdb_t *cfg, uint16_t app_idx)
        return __mesh_delete_key(cfg, cfg->jcfg, "appKeys", app_idx);
 }
 
+bool _bt_mesh_conf_set_model_info(_bt_mesh_cdb_t *cfg,
+               uint16_t unicast, GSList *models)
+{
+       int sz;
+       json_object *jnode, *jobj, *jelements;
+       GSList *l;
+
+       BT_INFO("Mesh: Set All model informations in the node [0x%2.2x]",
+                       unicast);
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       jnode = __mesh_get_node_by_unicast(cfg, unicast);
+       if (!jnode)
+               return false;
+
+       jelements = json_object_object_get(jnode, "elements");
+       if (!jelements)
+               return false;
+
+       sz = json_object_array_length(jelements);
+       BT_INFO("Mesh: Total elements [%d]", sz);
+       BT_INFO("Mesh: Total Models in List [%d]",
+                       g_slist_length(models));
+
+       for (l = models; l != NULL; l = g_slist_next(l)) {
+               json_object *jentry, *jmods;
+               bluetooth_mesh_model_t *mod = l->data;
+
+               BT_INFO("Mesh: Elem Idx [%u]", mod->elem_index);
+               BT_INFO("Mesh: Model ID [0x%4.4x]", mod->model_id);
+
+               jentry = json_object_array_get_idx(jelements, mod->elem_index);
+               if (!jentry)
+                       return false;
+
+               /* Write Index for the eleement */
+               if (!__mesh_write_int(jentry, "index", (int)mod->elem_index))
+                       return false;
+
+               /* Set Hardcoded location */
+               if (!__mesh_write_uint16_hex(jentry, "location", 0x0000))
+                       return false;
+
+               jmods = json_object_object_get(jentry, "models");
+               if (!jmods) {
+                       /* For backwards compatibility */
+                       jmods = json_object_new_array();
+                       json_object_object_add(jentry, "models", jmods);
+               }
+
+               /* TODO: Vendor Model Entry: Only BT SIG model entry is handled now */
+               jobj = __mesh_init_model((uint16_t)mod->model_id);
+               if (!jobj)
+                       return false;
+
+               json_object_array_add(jmods, jobj);
+       }
+
+       /* Save */
+       return  __bt_mesh_save_configruation_file(cfg);
+}
+
+bool _bt_mesh_conf_set_vendor_info(_bt_mesh_cdb_t *cfg,
+               uint16_t unicast, uint16_t crpl, uint16_t cid,
+                       uint16_t vid, uint16_t pid,
+                               int proxy, int relay,
+                                       int lpn, int frnd)
+{
+       json_object *jnode, *jobj;
+
+       BT_INFO("Mesh: Set Vednor Information in CDB for node [0x%2.2x]",
+                       unicast);
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       jnode = __mesh_get_node_by_unicast(cfg, unicast);
+       if (!jnode) {
+               BT_INFO("Mesh: Node not found");
+               return false;
+       }
+
+       /* Company ID */
+       if (!__mesh_write_uint16_hex(jnode, "crpl", crpl)) {
+               BT_ERR("Mesh: Could not write CRPL");
+               return false;
+       }
+
+       /* Company ID */
+       if (!__mesh_write_uint16_hex(jnode, "cid", cid)) {
+               BT_ERR("Mesh: Could not write CID");
+               return false;
+       }
+
+       /* Vendor ID or Product ID */
+       if (!__mesh_write_uint16_hex(jnode, "pid", pid)) {
+               BT_INFO("Mesh: Could not write PID");
+               return false;
+       }
+
+       /* Version ID */
+       if (!__mesh_write_uint16_hex(jnode, "vid", vid)) {
+               BT_INFO("Mesh: Could not write VID");
+               return false;
+       }
+
+       jobj = json_object_object_get(jnode, "features");
+       if (!jobj) {
+               jobj = json_object_new_object();
+               json_object_object_add(jnode, "features", jobj);
+       }
+
+       BT_INFO("Mesh: Set features in CDB");
+
+       __mesh_write_int(jobj, "relay", relay ? 1 : 0);
+       __mesh_write_int(jobj, "friend", frnd ? 1 : 0);
+       __mesh_write_int(jobj, "proxy", proxy ? 1 : 0);
+       __mesh_write_int(jobj, "lowPower", lpn ? 1 : 0);
+
+       BT_INFO("Mesh: All vendor Info data set successfully");
+
+       return __bt_mesh_save_configruation_file(cfg);
+}
+
 bool _bt_mesh_conf_set_unicast_address_range(_bt_mesh_cdb_t *cfg,
                uint16_t low, uint16_t high)
 {
@@ -811,7 +945,7 @@ bool _bt_mesh_conf_node_delete_application_key(_bt_mesh_cdb_t *cfg,
 _bt_mesh_cdb_t *_bt_mesh_conf_database_create(const char *file_name,
                const uint8_t uuid[16],
                        const uint8_t token[8], const char *network_name,
-                               const char *app_cred)
+                               const char *sender, const char *app_cred)
 {
        _bt_mesh_cdb_t *cfg;
        json_object *jcfg, *jarray;
@@ -832,6 +966,7 @@ _bt_mesh_cdb_t *_bt_mesh_conf_database_create(const char *file_name,
        cfg = g_malloc0(sizeof(_bt_mesh_cdb_t));
        cfg->jcfg = jcfg;
        cfg->cfg_fname = g_strdup(file_name);
+       cfg->owner = g_strdup(sender);
        cfg->app_cred = g_strdup(app_cred);
        memcpy(&cfg->token, (void*)token, 8);
        memcpy(&cfg->uuid, (void*)uuid, 16);
@@ -927,7 +1062,7 @@ uint16_t** _bt_mesh_conf_get_all_model_info(_bt_mesh_cdb_t *cfg,
        json_object *jelement = NULL;
        json_object *jmodelarray = NULL;
        const char *str;
-       uint16_t **models;
+       uint16_t **models = NULL;
 
        if (!cfg)
                return NULL;
@@ -937,44 +1072,72 @@ uint16_t** _bt_mesh_conf_get_all_model_info(_bt_mesh_cdb_t *cfg,
                return NULL;
 
        jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
-       if (jnode)
+       if (!jnode) {
+               BT_ERR("Mesh: Node not found with UUID");
                return NULL;
+       }
 
        /* Get element array object */
        json_object_object_get_ex(jnode, "elements", &jarray);
 
-       if (!jarray || json_object_get_type(jarray) != json_type_array)
+       if (!jarray || json_object_get_type(jarray) != json_type_array) {
+               BT_ERR("Mesh:could not get element array");
                return NULL;
+       }
 
        /* Get specific element by index */
        jelement = __mesh_get_key_object(jarray, element_index);
-       if (!jelement)
+       if (!jelement) {
+               BT_ERR("Mesh: Could not find element");
                return NULL;
-
+       }
 
        /* Get Model array object inside the selected element */
        json_object_object_get_ex(jelement, "models", &jmodelarray);
 
-       if (!jmodelarray || json_object_get_type(jmodelarray) != json_type_array)
+       if (!jmodelarray || json_object_get_type(jmodelarray) != json_type_array) {
+               BT_ERR("Mesh: Could not get Model Array");
                return NULL;
+       }
 
        sz = json_object_array_length(jmodelarray);
+       BT_INFO("Mesh: Total number of Models in Element index [%d] is [%d]",
+                       element_index, sz);
+
        models = (uint16_t**) g_malloc0(sz * sizeof(uint16_t*));
 
        for (i = 0; i < sz; ++i) {
-               json_object *jentry;
+               json_object *jentry, *jval;
+               uint16_t mod_id;
 
+               BT_INFO("Mesh: Model [%d]", i);
                jentry = json_object_array_get_idx(jmodelarray, i);
-               str = json_object_get_string(jentry);
+
+               if (!json_object_object_get_ex(jentry, "modelId", &jval)) {
+                       BT_ERR("Mesh: Failed to read Model in index [%d]", i);
+                       for (int j = 0 ; j < sz; j++)
+                               g_free(models[j]);
+                       g_free(models);
+                       return NULL;
+               }
+
+               str = json_object_get_string(jval);
+               BT_INFO("Mesh: Model ID String [%s]", str);
                /* Only standard models are handled now */
-               if (sscanf(str, "%04hx", models[i]) != 1) {
-                       for (int j =0 ; j < sz; j++)
+               if (sscanf(str, "%04hx", &mod_id) != 1) {
+                       BT_INFO("Mesh: Failed to read Model ID from Model entry [%s]", str);
+                       for (int j = 0 ; j < sz; j++)
                                g_free(models[j]);
                        g_free(models);
                        return NULL;
                }
+
+               BT_INFO("Mesh: Model string [%s] Model ID [0x%4.4x]", str, mod_id);
+               models[i] = g_malloc0(sizeof(uint16_t));
+               *models[i] = mod_id;
        }
        /* TODO: Need to handle vendor models */
+       BT_INFO("Mesh: Got all model info");
        *num_models = sz;
        return models;
 }
@@ -995,27 +1158,34 @@ bool _bt_mesh_conf_get_element_count(_bt_mesh_cdb_t *cfg,
                return false;
 
        jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
-       if (jnode)
+       if (!jnode) {
+               BT_ERR("Mesh: Node by UUID not found");
                return false;
+       }
 
        json_object_object_get_ex(jnode, "elements", &jarray);
 
-       if (!jarray || json_object_get_type(jarray) != json_type_array)
+       if (!jarray || json_object_get_type(jarray) != json_type_array) {
+               BT_ERR("Mesh: Element array not found in Node");
                return false;
+       }
 
        sz = json_object_array_length(jarray);
-       if (sz == 0)
+       if (sz == 0) {
+               BT_ERR("Mesh: Element array length is 0");
                return false;
+       }
        *num_elems = sz;
 
        return true;
 }
 
-bool _bt_mesh_conf_fetch_vendor_specific_info(_bt_mesh_cdb_t *cfg,
-       uint16_t *cid, uint16_t *vid,
-               uint16_t *version, uint16_t *crpl,
-                       int *relay, int *friend,
-                               int *proxy, int *lpn)
+bool _bt_mesh_conf_fetch_vendor_specific_info(
+       _bt_mesh_cdb_t *cfg, uint16_t unicast,
+               uint16_t *cid, uint16_t *vid,
+                       uint16_t *version, uint16_t *crpl,
+                               int *relay, int *friend,
+                                       int *proxy, int *lpn)
 {
        json_object *jcfg;
        json_object *jnode;
@@ -1025,25 +1195,30 @@ bool _bt_mesh_conf_fetch_vendor_specific_info(_bt_mesh_cdb_t *cfg,
 
        if (!cfg)
                return false;
-
        jcfg = cfg->jcfg;
        if (!jcfg)
                return false;
 
-       jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
-       if (jnode)
+       jnode = __mesh_get_node_by_unicast(cfg, unicast);
+       if (!jnode) {
+               BT_ERR("Mesh: Node not found by unicast [0x%2.2x]", unicast);
                return false;
+       }
 
        /* Get CRPL */
-       if (!json_object_object_get_ex(jnode, "crpl", &jobj))
+       if (!json_object_object_get_ex(jnode, "crpl", &jobj)) {
+               BT_ERR("Mesh: CRPL info not found");
                return false;
+       }
 
        str = json_object_get_string(jobj);
        if (!str)
                return false;
+
        if (sscanf(str, "%04hx", crpl) != 1)
                return false;
 
+       BT_INFO("Mesh: Got CRPL[%s]", str);
        /* Get Company ID */
        if (!json_object_object_get_ex(jnode, "cid", &jobj))
                return false;
@@ -1054,6 +1229,7 @@ bool _bt_mesh_conf_fetch_vendor_specific_info(_bt_mesh_cdb_t *cfg,
        if (sscanf(str, "%04hx", cid) != 1)
                return false;
 
+       BT_INFO("Mesh: Got CID[%s]", str);
        /* Get Vendor ID */
        if (!json_object_object_get_ex(jnode, "pid", &jobj))
                return false;
@@ -1065,6 +1241,7 @@ bool _bt_mesh_conf_fetch_vendor_specific_info(_bt_mesh_cdb_t *cfg,
        if (sscanf(str, "%04hx", vid) != 1)
                return false;
 
+       BT_INFO("Mesh: Got PID[%s]", str);
        /* Get Version ID */
        if (!json_object_object_get_ex(jnode, "vid", &jobj))
                return false;
@@ -1075,30 +1252,39 @@ bool _bt_mesh_conf_fetch_vendor_specific_info(_bt_mesh_cdb_t *cfg,
        if (sscanf(str, "%04hx", version) != 1)
                return false;
 
+       BT_INFO("Mesh: got version [%s]", str);
        jobj = json_object_object_get(jnode, "features");
 
        if (jobj) {
                if (json_object_object_get_ex(jobj, "relay", &jobjfeature)) {
-                       str = json_object_get_string(jobj);
-                       if (str)
+                       str = json_object_get_string(jobjfeature);
+                       if (str) {
                                sscanf(str, "%d", relay);
+                               BT_INFO("Mesh: Got Relay [%s]", str);
+                       }
                }
 
                if (json_object_object_get_ex(jobj, "friend", &jobjfeature)) {
-                       str = json_object_get_string(jobj);
-                       if (str)
+                       str = json_object_get_string(jobjfeature);
+                       if (str) {
                                sscanf(str, "%d", friend);
+                               BT_INFO("Mesh: Got Friend [%s]", str);
+                       }
                }
 
                if (json_object_object_get_ex(jobj, "proxy", &jobjfeature)) {
-                       str = json_object_get_string(jobj);
-                       if (str)
+                       str = json_object_get_string(jobjfeature);
+                       if (str) {
                                sscanf(str, "%d", proxy);
+                               BT_INFO("Mesh: Got Proxy[%s]", str);
+                       }
                }
                if (json_object_object_get_ex(jobj, "lowPower", &jobjfeature)) {
-                       str = json_object_get_string(jobj);
-                       if (str)
+                       str = json_object_get_string(jobjfeature);
+                       if (str) {
                                sscanf(str, "%d", lpn);
+                               BT_INFO("Mesh: Got LPN[%s]", str);
+                       }
                }
        }
        return true;
@@ -1220,6 +1406,408 @@ bool _bt_mesh_conf_delete_group_entry(_bt_mesh_cdb_t *cfg, uint16_t addr)
        return __mesh_delete_group(cfg, cfg->jcfg, "groups", addr);
 }
 
+static json_object *__mesh_get_model_by_modelid(json_object *jelement,
+               uint32_t model_id)
+{
+       int sz;
+       json_object *jval = NULL;
+       json_object *jmodelarray = NULL;
+
+       /* Get Model array object inside the selected element */
+       json_object_object_get_ex(jelement, "models", &jmodelarray);
+
+       if (!jmodelarray || json_object_get_type(jmodelarray) != json_type_array) {
+               BT_ERR("Mesh: Could not get Model Array");
+               return NULL;
+       }
+
+       /* Get specific model object inside model array */
+       sz = json_object_array_length(jmodelarray);
+       BT_INFO("Mesh: Total number of Models in Element is [%d]", sz);
+
+       for (int i = 0; i < sz; ++i) {
+               uint16_t mod_id;
+               const char *str;
+               json_object *jentry = NULL;
+
+               BT_INFO("Mesh: Model [%d]", i);
+               jentry = json_object_array_get_idx(jmodelarray, i);
+
+               if (!json_object_object_get_ex(jentry, "modelId", &jval)) {
+                       BT_ERR("Mesh: Failed to read Model in index [%d]", i);
+                       return NULL;
+               }
+
+               str = json_object_get_string(jval);
+               if (sscanf(str, "%04hx", &mod_id) != 1) {
+                       BT_INFO("Mesh: Failed to read Model ID from Model entry [%s]", str);
+                       return NULL;
+               }
+
+               BT_INFO("Mesh: Model string [%s] Model ID [0x%4.4x]", str, mod_id);
+               if ((uint16_t)model_id == mod_id) {
+                       BT_INFO("Mesh: Found required model");
+                       return jentry;
+               }
+       }
+       /* TODO: Need to handle vendor models */
+
+       return NULL;
+}
+
+static json_object *__mesh_get_model_by_unicast_modelid(_bt_mesh_cdb_t *cfg,
+               uint16_t unicast, int element_index, uint32_t model_id)
+{
+       json_object *jnode = NULL;
+       json_object *jarray = NULL;
+       json_object *jelement = NULL;
+       json_object *jmodel = NULL;
+
+       if (!cfg || !cfg->jcfg)
+               return NULL;
+
+       /* Get specific node by unicast */
+       jnode = __mesh_get_node_by_unicast(cfg, unicast);
+       if (!jnode)
+               return NULL;
+
+       /* Get element array object inside node */
+       json_object_object_get_ex(jnode, "elements", &jarray);
+       if (!jarray || json_object_get_type(jarray) != json_type_array) {
+               BT_ERR("Mesh:could not get element array");
+               return NULL;
+       }
+
+       /* Get specific element by index */
+       jelement = __mesh_get_key_object(jarray, element_index);
+       if (!jelement) {
+               BT_ERR("Mesh: Could not find element");
+               return NULL;
+       }
+
+       /* Get specific model by model-id */
+       jmodel = __mesh_get_model_by_modelid(jelement, model_id);
+       if (!jmodel)
+               return NULL;
+
+       return jmodel;
+}
+
+static json_object *__mesh_get_sub_group(json_object *jgroups, uint16_t group_addr)
+{
+       json_object *jval = NULL;
+       int sz = json_object_array_length(jgroups);
+       BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
+
+       for (int i = 0; i < sz; ++i) {
+               uint16_t group_address;
+               const char *str;
+               json_object *jentry = NULL;
+
+               BT_INFO("Mesh: sub-addr [%d]", i);
+               jentry = json_object_array_get_idx(jgroups, i);
+
+               if (!json_object_object_get_ex(jentry, "sub-addr", &jval)) {
+                       BT_ERR("Mesh: Failed to read sub-addr in index [%d]", i);
+                       return NULL;
+               }
+
+               str = json_object_get_string(jval);
+               if (sscanf(str, "%04hx", &group_address) != 1) {
+                       BT_INFO("Mesh: Failed to read group address from sub-addr entry [%s]", str);
+                       return NULL;
+               }
+
+               BT_INFO("Mesh: group addr string [%s] sub-addr [0x%4.4x]", str, group_address);
+               if (group_addr == group_address) {
+                       BT_INFO("Mesh: Found required sub-addr");
+                       return jentry;
+               }
+       }
+       return NULL;
+}
+
+static bool __mesh_del_sub_group(json_object *jgroups, uint16_t group_addr)
+{
+       json_object *jval = NULL;
+       int i = 0;
+       int sz = json_object_array_length(jgroups);
+       BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
+
+       for (i = 0; i < sz; ++i) {
+               uint16_t group_address;
+               const char *str;
+               json_object *jentry = NULL;
+
+               BT_INFO("Mesh: sub-addr [%d]", i);
+               jentry = json_object_array_get_idx(jgroups, i);
+
+               if (!json_object_object_get_ex(jentry, "sub-addr", &jval)) {
+                       BT_ERR("Mesh: Failed to read sub-addr in index [%d]", i);
+                       return false;
+               }
+
+               str = json_object_get_string(jval);
+               if (sscanf(str, "%04hx", &group_address) != 1) {
+                       BT_INFO("Mesh: Failed to read group address from sub-addr entry [%s]", str);
+                       return NULL;
+               }
+
+               BT_INFO("Mesh: group addr string [%s] sub-addr [0x%4.4x]", str, group_address);
+               if (group_addr == group_address) {
+                       BT_INFO("Mesh: Found required sub-addr");
+                       break;
+               }
+       }
+
+       if (i == sz)
+               return true;
+
+       json_object_array_del_idx(jgroups, i, 1);
+
+       return true;
+}
+
+bool _bt_mesh_conf_add_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
+                       int element_index, uint32_t model_id, uint16_t group_addr)
+{
+       json_object *jmodel = NULL;
+       json_object *jgroups = NULL;
+       json_object *jgroup = NULL;
+
+       BT_INFO("Mesh: Set model config informations in the node [0x%2.2x] \
+                       element index [%d] model [0x%4.4x] group addr [0x%2.2x]",
+                       unicast, element_index, model_id, group_addr);
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       /* Get model to be updated */
+       jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
+                                               element_index, model_id);
+       if (!jmodel)
+               return false;
+
+       /* Find existing sub-addr group */
+       if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups)) {
+               BT_INFO("Mesh: Sub-addr group JSON object is not present: Create");
+               jgroups = json_object_new_array();
+               if (!jgroups)
+                       return false;
+
+               json_object_object_add(jmodel, "sub-addr", jgroups);
+       }
+
+       jgroup = __mesh_get_sub_group(jgroups, group_addr);
+       if (jgroup) {
+               BT_DBG("sub-addr already present in list");
+               return true;
+       }
+
+       /* Write group address */
+       jgroup = json_object_new_object();
+       if (!jgroup)
+               return false;
+
+       if (!__mesh_write_uint16_hex(jgroup, "sub-addr", group_addr))
+               return false;
+
+       json_object_array_add(jgroups, jgroup);
+
+       /* Save */
+       return  __bt_mesh_save_configruation_file(cfg);
+}
+
+bool _bt_mesh_conf_delete_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
+                       int element_index, uint32_t model_id, uint16_t group_addr)
+{
+       json_object *jmodel = NULL;
+       json_object *jgroups = NULL;
+
+       BT_INFO("Mesh: Set model config informations in the node [0x%2.2x] \
+                       element index [%d] model [0x%4.4x] group addr [0x%2.2x]",
+                       unicast, element_index, model_id, group_addr);
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       /* Get model to be updated */
+       jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
+                                               element_index, model_id);
+       if (!jmodel)
+               return false;
+
+       /* Delete group address */
+       if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups))
+               return false;
+
+       if (!__mesh_del_sub_group(jgroups, group_addr))
+               return false;
+
+       /* Save */
+       return  __bt_mesh_save_configruation_file(cfg);
+}
+
+bool _bt_mesh_conf_delete_all_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
+                                               int element_index, uint32_t model_id)
+{
+       json_object *jmodel = NULL;
+       json_object *jgroups = NULL;
+       int sz;
+
+       BT_INFO("Mesh: Delete all model sub informations in the node [0x%2.2x] \
+                                       element index [%d] model [0x%4.4x]",
+                                       unicast, element_index, model_id);
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       /* Get model to be updated */
+       jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
+                                               element_index, model_id);
+       if (!jmodel)
+               return false;
+
+       /* Delete all group address */
+       if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups))
+               return false;
+
+       sz = json_object_array_length(jgroups);
+       BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
+
+       for (int i = sz - 1; i >= 0 ; --i)
+               json_object_array_del_idx(jgroups, i, 1);
+
+       /* Save */
+       return  __bt_mesh_save_configruation_file(cfg);
+}
+
+bool _bt_mesh_conf_overwrite_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
+                       int element_index, uint32_t model_id, uint16_t group_addr)
+{
+       json_object *jmodel = NULL;
+       json_object *jgroups = NULL;
+       json_object *jgroup = NULL;
+       int sz;
+
+       BT_INFO("Mesh: Set model config informations in the node [0x%2.2x] \
+                       element index [%d] model [0x%4.4x] group addr [0x%2.2x]",
+                       unicast, element_index, model_id, group_addr);
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       /* Get model to be updated */
+       jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
+                                               element_index, model_id);
+       if (!jmodel)
+               return false;
+
+       /* Find group array */
+       if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups)) {
+               BT_INFO("Mesh: Sub-addr group JSON object is not present: Create");
+               jgroups = json_object_new_array();
+               if (!jgroups)
+                       return false;
+
+               json_object_object_add(jmodel, "sub-addr", jgroups);
+       } else {
+               /* Found group array: Delete all group address */
+               sz = json_object_array_length(jgroups);
+               BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
+
+               for (int i = sz - 1; i >= 0 ; --i) {
+                       BT_INFO("Mesh: Delete sub-addr entry [%d]", i);
+                       json_object_array_del_idx(jgroups, i, 1);
+               }
+       }
+
+       /* Over-write new group address */
+       jgroup = json_object_new_object();
+       if (!jgroup)
+               return false;
+
+       if (!__mesh_write_uint16_hex(jgroup, "sub-addr", group_addr))
+               return false;
+
+       json_object_array_add(jgroups, jgroup);
+
+       /* Save */
+       return  __bt_mesh_save_configruation_file(cfg);
+}
+
+bool _bt_mesh_is_group_subscribed(_bt_mesh_cdb_t *cfg, uint16_t group_addr)
+{
+       json_object *jnodes;
+       int i, sz = 0;
+
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes);
+       if (!jnodes || json_object_get_type(jnodes) != json_type_array)
+               return false;
+
+       sz = json_object_array_length(jnodes);
+
+       for (i = 0; i < sz; ++i) {
+               json_object *jnode, *jarray;
+               int ele_cnt;
+               int j;
+
+               jnode = json_object_array_get_idx(jnodes, i);
+               if (!jnode)
+                       continue;
+
+               if (!json_object_object_get_ex(jnode, "elements", &jarray))
+                       return false;
+
+               if (!jarray || json_object_get_type(jarray) != json_type_array)
+                       return false;
+
+               ele_cnt = json_object_array_length(jarray);
+
+               for (j = 0; j < ele_cnt; ++j) {
+                       json_object *jentry, *jval, *jmods;
+                       int32_t index;
+                       int k, mod_cnt;
+
+                       jentry = json_object_array_get_idx(jarray, j);
+                       if (!json_object_object_get_ex(jentry, "index", &jval))
+                               return false;
+
+                       index = json_object_get_int(jval);
+                       if (index > 0xff)
+                               return false;
+
+                       if (!json_object_object_get_ex(jentry, "models", &jmods))
+                               continue;
+
+                       mod_cnt = json_object_array_length(jmods);
+                       BT_INFO("Mesh: Total Model count in element Index [%d] is [%d]",
+                               index, mod_cnt);
+
+                       for (k = 0; k < mod_cnt; ++k) {
+                               json_object *jmod;
+                               json_object *jgroups, *jgroup;
+
+                               jmod = json_object_array_get_idx(jmods, k);
+
+                               if (!json_object_object_get_ex(jmod, "sub-addr", &jgroups))
+                                       continue;
+
+                               /* Find existing sub-addr group */
+                               jgroup = __mesh_get_sub_group(jgroups, group_addr);
+                               if (jgroup) {
+                                       BT_DBG("sub-addr present in list");
+                                       return true;
+                               }
+                       }
+               }
+       }
+       return false;
+}
+
 bool _bt_mesh_conf_set_network_friendly_name(_bt_mesh_cdb_t *cfg,
                const char *network_name)
 {
@@ -1479,7 +2067,7 @@ fail:
 _bt_mesh_cdb_t* _bt_mesh_conf_load(const char *file_name,
                const char *token)
 {
-       char *token_str = NULL;
+       char token_str[17];
        int fd;
        char *str;
        struct stat st;
@@ -1488,23 +2076,31 @@ _bt_mesh_cdb_t* _bt_mesh_conf_load(const char *file_name,
        _bt_mesh_cdb_t *cfg;
 
        fd = open(file_name, O_RDONLY);
-       if (fd < 0)
+       if (fd < 0) {
+               BT_ERR("Mesh: Could not open file [%s]",
+                               file_name);
                return NULL;
+       }
 
        if (fstat(fd, &st) == -1) {
                close(fd);
+               BT_ERR("Mesh: Could not stat file [%s]",
+                               file_name);
                return NULL;
        }
 
        str = (char *) g_malloc0(st.st_size + 1);
        if (!str) {
                close(fd);
+               BT_ERR("Mesh: Could not stat file [%s]",
+                               file_name);
                return NULL;
        }
 
        sz = read(fd, str, st.st_size);
        if (sz != st.st_size) {
                BT_ERR("Mesh: Failed to read configuration file [%s]", file_name);
+               close(fd);
                g_free(str);
                return NULL;
        }
@@ -1531,14 +2127,16 @@ _bt_mesh_cdb_t* _bt_mesh_conf_load(const char *file_name,
                goto fail;
        }
 
-       token_str = _bt_service_convert_hex_to_string((unsigned char*)cfg->token, 8);
+       _bt_mesh_util_convert_hex_to_string(cfg->token, 8, token_str, 17);
 
        /* Match CDB file tken with user's token */
        if (g_strcmp0(token_str, token)) {
                BT_INFO("Mesh: Token did not match! File token [%s] requested token [%s]",
-                               cfg->token, token);
+                               token_str, token);
                goto fail;
        }
+
+       BT_INFO("Mesh: Token found");
        /* TODO: Load keys and remotes */
        return cfg;
 fail: