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 roup 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_conf_set_network_friendly_name(_bt_mesh_cdb_t *cfg,
const char *network_name)
{
return false;
}
+bool _bt_mesh_network_add_model_subscription(
+ uint8_t net_uuid[], uint16_t remote_unicast,
+ int ele_idx, uint32_t mod_id, uint16_t group_addr)
+{
+ GSList *l;
+ _bt_mesh_cdb_t *cdb_cfg = NULL;
+
+ /* Find CDB */
+ l = g_slist_find_custom(cdb_list, net_uuid,
+ __mesh_compare_app_network_uuid);
+ if (!l)
+ return false;
+
+ cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+
+ return _bt_mesh_conf_add_model_config_data(cdb_cfg,
+ remote_unicast, ele_idx, mod_id, group_addr);
+}
+
+bool _bt_mesh_network_delete_model_subscription(
+ uint8_t net_uuid[], uint16_t remote_unicast,
+ int ele_idx, uint32_t mod_id, uint16_t group_addr)
+{
+ GSList *l;
+ _bt_mesh_cdb_t *cdb_cfg = NULL;
+
+ /* Find CDB */
+ l = g_slist_find_custom(cdb_list, net_uuid,
+ __mesh_compare_app_network_uuid);
+ if (!l)
+ return false;
+
+ cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+
+ return _bt_mesh_conf_delete_model_config_data(cdb_cfg,
+ remote_unicast, ele_idx, mod_id, group_addr);
+}
+
+bool _bt_mesh_network_delete_all_model_subscription(
+ uint8_t net_uuid[], uint16_t remote_unicast,
+ int ele_idx, uint32_t mod_id)
+{
+ GSList *l;
+ _bt_mesh_cdb_t *cdb_cfg = NULL;
+
+ /* Find CDB */
+ l = g_slist_find_custom(cdb_list, net_uuid,
+ __mesh_compare_app_network_uuid);
+ if (!l)
+ return false;
+
+ cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+
+ return _bt_mesh_conf_delete_all_model_config_data(cdb_cfg,
+ remote_unicast, ele_idx, mod_id);
+}
+
+bool _bt_mesh_network_overwrite_model_subscription(
+ uint8_t net_uuid[], uint16_t remote_unicast,
+ int ele_idx, uint32_t mod_id, uint16_t group_addr)
+{
+ GSList *l;
+ _bt_mesh_cdb_t *cdb_cfg = NULL;
+
+ /* Find CDB */
+ l = g_slist_find_custom(cdb_list, net_uuid,
+ __mesh_compare_app_network_uuid);
+ if (!l)
+ return false;
+
+ cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+
+ return _bt_mesh_conf_overwrite_model_config_data(cdb_cfg,
+ remote_unicast, ele_idx, mod_id, group_addr);
+}
+
bool _bt_mesh_network_save_remote_node_composition(
uint8_t net_uuid[], uint16_t remote_unicast,
uint8_t *data, uint16_t data_len)