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;
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;
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);
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);
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);
}
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)
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)
{
_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;
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);
json_object *jelement = NULL;
json_object *jmodelarray = NULL;
const char *str;
- uint16_t **models;
+ uint16_t **models = NULL;
if (!cfg)
return NULL;
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;
}
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;
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;
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;
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;
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;
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)
{
_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;
_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;
}
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: