Mesh: Refactor Network group Removal logic 09/239709/2
authorAnupam Roy <anupam.r@samsung.com>
Wed, 29 Jul 2020 06:19:37 +0000 (11:49 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Wed, 29 Jul 2020 06:29:35 +0000 (06:29 +0000)
Network Groups (Mesh group & virtual Mesh group)
are created and saved in Network Configuration DB.
Therefore, removal of groups by user should remove these
groups from Conf DB also, instead of just removing handles
from application.

Apart from above, this patch refactors 'Get All Mesh groups'
logic. Instead of just fetching the group address, now it fetches
all informations of groups (Label UUID, if Virtual group)

Change-Id: I8ca483ddf46140c3e671070f41a6484b5a04935e
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
bt-api/bt-mesh.c
bt-service/services/bt-request-handler.c
bt-service/services/include/bt-service-mesh-cdb.h
bt-service/services/include/bt-service-mesh-network.h
bt-service/services/mesh/bt-service-mesh-cdb.c
bt-service/services/mesh/bt-service-mesh-network.c
include/bluetooth-mesh-api.h
include/bt-internal-types.h

index de10cc3..f168369 100644 (file)
@@ -681,6 +681,7 @@ BT_EXPORT_API int bluetooth_mesh_network_get_all_groups(
                        GPtrArray **groups)
 {
        int result = BLUETOOTH_ERROR_NONE;
+       bluetooth_mesh_network_group_info_t *info;
        guint size;
        int i;
 
@@ -700,21 +701,26 @@ BT_EXPORT_API int bluetooth_mesh_network_get_all_groups(
                        BT_ERR("Mesh: out_param is NULL");
                        result = BLUETOOTH_ERROR_INTERNAL;
                } else {
-                       size = (out_param->len) / sizeof(guint16);
+                       size = (out_param->len) / sizeof(bluetooth_mesh_network_group_info_t);
 
                        if (size == 0) {
                                BT_INFO("Mesh: No Groups created for the network");
                        }
 
+                       BT_INFO("Mesh: Total groups [%d]", size);
                        for (i = 0; i < size; i++) {
-                               uint16_t group_addr;
-                               uint16_t *group_ptr = NULL;
-
-                               group_addr = g_array_index(out_param,
-                                               guint16, i);
+                               bluetooth_mesh_network_group_info_t *grp_info = NULL;
 
-                               group_ptr = g_memdup(&group_addr, sizeof(guint16));
-                               g_ptr_array_add(*groups, (gpointer)group_ptr);
+                               info = &g_array_index(out_param,
+                                       bluetooth_mesh_network_group_info_t, i);
+                               BT_INFO("Mesh: Group addr [0x%2.2x]", info->group_addr);
+                               BT_INFO("Mesh: Group is Virtual [%s]", info->is_virtual? "YES":"NO");
+                               BT_INFO("Mesh: Group net UUID[%s]", info->net_uuid);
+                               if (info->is_virtual)
+                                       BT_INFO("Mesh: Virual Label UUID [%s]", info->label_uuid);
+                               grp_info = g_memdup(info,
+                                       sizeof(bluetooth_mesh_network_group_info_t));
+                               g_ptr_array_add(*groups, (gpointer)grp_info);
                        }
                }
        }
@@ -1010,6 +1016,30 @@ BT_EXPORT_API int bluetooth_mesh_model_get_subscriptopn_list(
        return result;
 }
 
+BT_EXPORT_API int bluetooth_mesh_network_remove_group(
+               bluetooth_mesh_network_t *network,
+                       bluetooth_mesh_network_group_info_t *req)
+{
+       int result;
+
+       BT_CHECK_PARAMETER(network, return);
+       BT_CHECK_PARAMETER(req, return);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       g_array_append_vals(in_param1, network,  sizeof(bluetooth_mesh_network_t));
+       g_array_append_vals(in_param2, req,  sizeof(bluetooth_mesh_network_group_info_t));
+
+       BT_INFO("Mesh: Remove Group Request");
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_MESH_NETWORK_REMOVE_GROUP,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}
+
 BT_EXPORT_API int bluetooth_mesh_network_create_group(
                bluetooth_mesh_network_t *network, bool is_virtual,
                        uint16_t grp_addr, bluetooth_mesh_network_group_info_t *info)
index ae9cc17..91418a8 100644 (file)
@@ -3993,6 +3993,23 @@ normal:
                                sizeof(bluetooth_mesh_network_group_info_t));
                break;
        }
+       case BT_MESH_NETWORK_REMOVE_GROUP: {
+               bluetooth_mesh_network_t net;
+               bluetooth_mesh_network_group_info_t req;
+
+               memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+               memset(&req, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
+
+               __bt_service_get_parameters(in_param1,
+                               &net, sizeof(bluetooth_mesh_network_t));
+               __bt_service_get_parameters(in_param2,
+                               &req, sizeof(bluetooth_mesh_network_group_info_t));
+
+               result = _bt_mesh_network_remove_group(
+                               requester_unique_creds, sender, &net, &req);
+
+               break;
+       }
        case BT_MESH_MODEL_CONFIG_GROUP_SUB: {
                bluetooth_mesh_model_configure_t req;
 
@@ -4095,6 +4112,7 @@ normal:
                memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
                __bt_service_get_parameters(in_param1,
                                &network, sizeof(bluetooth_mesh_network_t));
+               BT_INFO("Mesh: Request:: Get Groups");
                result = _bt_mesh_network_get_groups(
                                requester_unique_creds, sender, &network, out_param1);
                break;
@@ -5084,6 +5102,7 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_MESH_MODEL_CONFIGURE_APPKEY:
        case BT_MESH_MODEL_GET_APPKEY_LIST:
        case BT_MESH_NETWORK_CREATE_GROUP:
+       case BT_MESH_NETWORK_REMOVE_GROUP:
        case BT_MESH_MODEL_CONFIG_GROUP_SUB:
        case BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB:
        case BT_MESH_MODEL_SET_PUBLICATION:
index 3194f99..8adddc1 100644 (file)
@@ -143,6 +143,9 @@ GSList *_bt_mesh_conf_load_group_info(_bt_mesh_cdb_t *cfg);
 bool _bt_mesh_conf_insert_group_info(_bt_mesh_cdb_t *cfg,
                _bt_mesh_group_t *grp);
 
+bool _bt_mesh_conf_delete_group_entry(_bt_mesh_cdb_t *cfg,
+               uint16_t addr);
+
 bool _bt_mesh_conf_set_network_friendly_name(_bt_mesh_cdb_t *cfg,
                const char *network_name);
 
index 6e86032..781aa85 100644 (file)
@@ -165,6 +165,10 @@ int _bt_mesh_network_create_group(const char *app_cred, const char *sender,
                bluetooth_mesh_network_t *net, bool is_virtual, uint16_t grp_addr,
                        bluetooth_mesh_network_group_info_t *group);
 
+int _bt_mesh_network_remove_group(const char *app_cred,
+               const char *sender, bluetooth_mesh_network_t *net,
+                       bluetooth_mesh_network_group_info_t *req);
+
 int _bt_mesh_network_get_groups(const char *app_cred, const char *sender,
                bluetooth_mesh_network_t *network,  GArray **out_param);
 
index 75cb15e..ce9c3af 100644 (file)
@@ -470,6 +470,42 @@ bool _bt_mesh_conf_parse_data(void *cfg,  int k)
        return true;
 }
 
+static bool __mesh_jarray_group_delete(json_object *jarray, uint16_t group_addr)
+{
+       int i, sz = json_object_array_length(jarray);
+       json_object *jval;
+       char buf[15];
+
+       for (i = 0; i < sz; ++i) {
+               json_object *jentry;
+               uint16_t addr;
+               const char *str;
+
+               jentry = json_object_array_get_idx(jarray, i);
+               if (!json_object_object_get_ex(jentry, "name",
+                                       &jval))
+                       continue;
+
+               str = json_object_get_string(jval);
+               memcpy(buf, str + 6, 5);
+               BT_INFO("Mesh: JSON Group string:[%s]", buf);
+               if (sscanf(buf, "%04hx", &addr) != 1)
+                       continue;
+               BT_INFO("Mesh: JSON Group in Hex [0x%2.2x]", addr);
+
+               if (group_addr == addr)
+                       break;
+
+       }
+       if (i == sz) {
+               BT_INFO("Mesh: Failed to remove group");
+               return false;
+       }
+
+       json_object_array_del_idx(jarray, i, 1);
+       return true;
+}
+
 static void __mesh_jarray_key_del(json_object *jarray, int16_t idx)
 {
        int i, sz = json_object_array_length(jarray);
@@ -490,6 +526,20 @@ static void __mesh_jarray_key_del(json_object *jarray, int16_t idx)
        }
 }
 
+static bool __mesh_delete_group(_bt_mesh_cdb_t *cfg,
+               json_object *jobj, const char *desc, uint16_t addr)
+{
+       json_object *jarray;
+
+       if (!json_object_object_get_ex(jobj, desc, &jarray))
+               return false;
+
+       if (!__mesh_jarray_group_delete(jarray, addr))
+               return false;
+
+       return __bt_mesh_save_configruation_file(cfg);
+}
+
 static bool __mesh_delete_key(_bt_mesh_cdb_t *cfg,
                json_object *jobj, const char *desc, uint16_t idx)
 {
@@ -1128,8 +1178,14 @@ bool _bt_mesh_conf_insert_group_info(_bt_mesh_cdb_t *cfg,
        if (!cfg || !cfg->jcfg)
                return false;
 
-       if (!json_object_object_get_ex(cfg->jcfg, "groups", &jgroups))
-               return false;
+       if (!json_object_object_get_ex(cfg->jcfg, "groups", &jgroups)) {
+               BT_INFO("Mesh: Group JSON object is not present: Create");
+               jgroups = json_object_new_array();
+               if (!jgroups)
+                       return false;
+
+               json_object_object_add(cfg->jcfg, "groups", jgroups);
+       }
 
        jgroup = json_object_new_object();
        if (!jgroup)
@@ -1156,6 +1212,14 @@ fail:
        return false;
 }
 
+bool _bt_mesh_conf_delete_group_entry(_bt_mesh_cdb_t *cfg, uint16_t addr)
+{
+       if (!cfg || !cfg->jcfg)
+               return false;
+
+       return __mesh_delete_group(cfg, cfg->jcfg, "groups", addr);
+}
+
 bool _bt_mesh_conf_set_network_friendly_name(_bt_mesh_cdb_t *cfg,
                const char *network_name)
 {
index fd3f2f2..b938079 100644 (file)
@@ -118,7 +118,7 @@ static gint __mesh_compare_app_cdb_token(gconstpointer data,
        _bt_mesh_util_convert_hex_to_string((uint8_t *) cdb->token,
                        8, token_str, 17);
 
-       BT_INFO("Mesh: Match Token 1[%s] Toekn 2 [%s]",
+       BT_INFO("Mesh: Match Token 1[%s] Token 2 [%s]",
                        token_str, token);
        return g_strcmp0(token_str, token);
 }
@@ -128,24 +128,10 @@ static gint __mesh_compare_addr(
 {
        const _bt_mesh_group_t *grp = a;
        uint16_t addr = GPOINTER_TO_UINT(b);
+       BT_INFO("Mesh: Network group addr [0x%2.2x]", grp->grp_addr);
+       BT_INFO("Mesh: To be matched group addr [0x%2.2x]", addr);
 
-       return grp->grp_addr == addr;
-}
-
-static gint __mesh_compare_group_address(
-               const void *a, const void *b,
-                       void *user_data)
-{
-       const _bt_mesh_group_t *grp0 = a;
-       const _bt_mesh_group_t *grp1 = b;
-
-       if (grp0->grp_addr < grp1->grp_addr)
-               return -1;
-
-       if (grp0->grp_addr > grp1->grp_addr)
-               return 1;
-
-       return 0;
+       return (grp->grp_addr - addr);
 }
 
 int _bt_mesh_load_app_networks(const char *app_cred)
@@ -1379,6 +1365,50 @@ bool _bt_mesh_network_get_label_uuid_from_sub_addr(
        return true;
 }
 
+int _bt_mesh_network_remove_group(const char *app_cred,
+       const char *sender, bluetooth_mesh_network_t *net,
+                       bluetooth_mesh_network_group_info_t *req)
+{
+       GSList *l, *l1;
+       _bt_mesh_cdb_t *cdb_cfg = NULL;
+       _bt_mesh_group_t *grp;
+       uint8_t net_uuid[16];
+
+       _bt_mesh_util_convert_string_to_hex(net->uuid,
+                       strlen(net->uuid), net_uuid, 16);
+       /* Find CDB */
+       l = g_slist_find_custom(cdb_list, net_uuid,
+                       __mesh_compare_app_network_uuid);
+       if (!l)
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+
+       cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+       BT_INFO("Mesh: Total groups stored in network [%d]",
+                       g_slist_length(cdb_cfg->groups));
+
+       l1 = g_slist_find_custom(cdb_cfg->groups,
+                       GUINT_TO_POINTER(req->group_addr), __mesh_compare_addr);
+
+       if (!l1) {
+               BT_ERR("Mesh: To be Removed Group: [0x%2.2x] Not Found!", req->group_addr);
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+       }
+       grp = (_bt_mesh_group_t*)l1->data;
+
+       BT_INFO("Mesh: To be Removed Group: [0x%2.2x]", req->group_addr);
+       if (!_bt_mesh_conf_delete_group_entry(cdb_cfg, req->group_addr)) {
+               BT_ERR("Mesh: Failed to remove Group: [0x%2.2x]", req->group_addr);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_INFO("Mesh: Successfully removed Group: [0x%2.2x]", req->group_addr);
+       cdb_cfg->groups = g_slist_remove(cdb_cfg->groups, grp);
+       BT_INFO("Mesh: Total groups after update [%d]",
+                       g_slist_length(cdb_cfg->groups));
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
 int _bt_mesh_network_create_group(const char *app_cred,
        const char *sender, bluetooth_mesh_network_t *net,
                bool is_virtual, uint16_t addr,
@@ -1386,20 +1416,25 @@ int _bt_mesh_network_create_group(const char *app_cred,
 {
        GSList *l, *l1, *l2;
        _bt_mesh_cdb_t *cdb_cfg = NULL;
+       uint8_t net_uuid[16];
 
+       _bt_mesh_util_convert_string_to_hex(net->uuid,
+                       strlen(net->uuid), net_uuid, 16);
        /* Find CDB */
-       l = g_slist_find_custom(cdb_list, net->token.token,
-                       __mesh_compare_app_cdb_token);
+       l = g_slist_find_custom(cdb_list, net_uuid,
+                       __mesh_compare_app_network_uuid);
        if (!l)
                return BLUETOOTH_ERROR_INVALID_PARAM;
 
        cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+       BT_INFO("Mesh: Total Groups present in Network already [%d]",
+                       g_slist_length(cdb_cfg->groups));
 
        if (is_virtual) {
                uint8_t max_tries = 5;
                _bt_mesh_group_t *grp = NULL;
                grp = g_malloc0(sizeof(_bt_mesh_group_t));
-
+               BT_INFO("Mesh: Network Create Virtual group");
 retry:
                l_getrandom(grp->label_uuid, 16);
                _bt_mesh_util_crypto_create_virtual_address(
@@ -1410,18 +1445,23 @@ retry:
                                GUINT_TO_POINTER(grp->grp_addr), __mesh_compare_addr);
 
                if (!l1) {
-                       l2 = g_slist_insert_sorted_with_data(cdb_cfg->groups,
-                                       grp, __mesh_compare_group_address, NULL);
-                       if (l2) {
-                               _bt_mesh_conf_insert_group_info(cdb_cfg, grp);
-                               req->is_virtual = true;
-                               req->group_addr = grp->grp_addr;
-                               _bt_mesh_util_convert_hex_to_string(
-                                               (uint8_t *) grp->label_uuid, 16, req->label_uuid,
-                                               BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
-
-                               return BLUETOOTH_ERROR_NONE;
+                       if (!_bt_mesh_conf_insert_group_info(cdb_cfg, grp)) {
+                               BT_ERR("Mesh: unable to save group in Conf DB!!");
+                               g_free(grp);
+                               return BLUETOOTH_ERROR_INTERNAL;
                        }
+                       req->is_virtual = true;
+                       req->group_addr = grp->grp_addr;
+                       _bt_mesh_util_convert_hex_to_string(
+                                       (uint8_t *) grp->label_uuid, 16, req->label_uuid,
+                                       BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
+
+                       cdb_cfg->groups = g_slist_append(cdb_cfg->groups, grp);
+                       BT_INFO("Mesh: Virtual Group[0x%2.2x] inserted in List",
+                                       grp->grp_addr);
+                       BT_INFO("Mesh: Total groups present in Network after update [%d]",
+                                       g_slist_length(cdb_cfg->groups));
+                       return BLUETOOTH_ERROR_NONE;
                }
 
                max_tries--;
@@ -1432,26 +1472,38 @@ retry:
                /* Failed to create a unique hash */
                return BLUETOOTH_ERROR_INTERNAL;
        } else {
-               if (!MESH_IS_GROUP(addr))
+               BT_INFO("Mesh: Network Create group Addr: [0x%2.2x]", addr);
+
+               if (!MESH_IS_GROUP(addr)) {
+                       BT_ERR("Mesh: Group Address [0x%2.2x] is not valid!", addr);
                        return BLUETOOTH_ERROR_INVALID_PARAM;
+               }
 
-               l1 = g_slist_find_custom(cdb_cfg->groups,
+               l2 = g_slist_find_custom(cdb_cfg->groups,
                                GUINT_TO_POINTER(addr), __mesh_compare_addr);
 
-               if (l1) {
-                       _bt_mesh_group_t *grp = l1->data;
+               if (l2) {
+                       _bt_mesh_group_t *grp = l2->data;
                        req->is_virtual = false;
                        req->group_addr = grp->grp_addr;
+                       BT_INFO("Mesh: Group already found: addr [0x%2.2x]", grp->grp_addr);
                } else {
                        /* Group is not present */
                        _bt_mesh_group_t *grp = g_malloc0(sizeof(_bt_mesh_group_t));
                        grp->grp_addr = addr;
-                       _bt_mesh_conf_insert_group_info(cdb_cfg, grp);
-                       l = g_slist_insert_sorted_with_data(cdb_cfg->groups, grp,
-                                       __mesh_compare_group_address, NULL);
+                       if (!_bt_mesh_conf_insert_group_info(cdb_cfg, grp)) {
+                               BT_ERR("Mesh: unable to save group in Conf DB!!");
+                               g_free(grp);
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       }
+                       cdb_cfg->groups = g_slist_append(cdb_cfg->groups, grp);
                        req->is_virtual = false;
                        req->group_addr = grp->grp_addr;
+                       BT_INFO("Mesh: Group[0x%2.2x] inserted in List",
+                               grp->grp_addr);
                }
+               BT_INFO("Mesh: Total groups present in Network after update [%d]",
+                               g_slist_length(cdb_cfg->groups));
 
        }
        return BLUETOOTH_ERROR_NONE;
@@ -1463,20 +1515,43 @@ int _bt_mesh_network_get_groups(const char *app_cred, const char *sender,
 {
        GSList *l;
        _bt_mesh_cdb_t *cdb_cfg = NULL;
+       uint8_t net_uuid[16];
 
+       BT_INFO("Mesh: Get All groups from Network [%s]", network->uuid);
+       _bt_mesh_util_convert_string_to_hex(network->uuid,
+                       strlen(network->uuid), net_uuid, 16);
        /* Find CDB */
-       l = g_slist_find_custom(cdb_list, network->token.token,
-                       __mesh_compare_app_cdb_token);
+       l = g_slist_find_custom(cdb_list, net_uuid,
+                       __mesh_compare_app_network_uuid);
        if (!l)
                return BLUETOOTH_ERROR_INVALID_PARAM;
 
        cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+       BT_INFO("Mesh: Got CDB");
+
+       BT_INFO("Mesh: Total groups present in Network [%d]",
+                       g_slist_length(cdb_cfg->groups));
 
        for (l = cdb_cfg->groups; l; l = l->next) {
+               bluetooth_mesh_network_group_info_t grp;
                _bt_mesh_group_t *group = l->data;
+               memset(&grp, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
+               g_strlcpy(grp.net_uuid, network->uuid, sizeof(grp.net_uuid));
+               if (MESH_IS_GROUP(group->grp_addr) && !MESH_IS_VIRTUAL(group->grp_addr)) {
+                       grp.is_virtual = false;
+                       grp.group_addr = group->grp_addr;
+                       BT_INFO("Mesh: Found Non-Virtual group, addr[0x%2.2x]", group->grp_addr);
+               } else if (MESH_IS_VIRTUAL(group->grp_addr)){
+                       grp.is_virtual = true;
+                       grp.group_addr = group->grp_addr;
+                       _bt_mesh_util_convert_hex_to_string((uint8_t *) group->label_uuid,
+                                       16, grp.label_uuid, sizeof(grp.label_uuid));
+                       BT_INFO("Mesh: Found Virtual group, addr[0x%2.2x]", group->grp_addr);
+                       BT_INFO("Mesh: Label UUID[%s]", grp.label_uuid);
+               }
 
                g_array_append_vals(*out_param,
-                               &group->grp_addr, sizeof(uint16_t));
+                               &grp, sizeof(bluetooth_mesh_network_group_info_t));
        }
 
        return BLUETOOTH_ERROR_NONE;
index e054b52..5fd4255 100644 (file)
@@ -408,6 +408,12 @@ int bluetooth_mesh_network_create_group(bluetooth_mesh_network_t *network,
                        bluetooth_mesh_network_group_info_t *info);
 
 /**
+ * Remove a group in a network
+ */
+int bluetooth_mesh_network_remove_group(bluetooth_mesh_network_t *network,
+               bluetooth_mesh_network_group_info_t *req);
+
+/**
  * Configure a Mesh group to a Mesh odel
  */
 int bluetooth_mesh_model_configure_group_sub(
index f8e577a..df61ab3 100644 (file)
@@ -506,6 +506,7 @@ typedef enum {
        BT_MESH_MODEL_SET_PUBLICATION,
        BT_MESH_MODEL_GET_PUBLICATION,
        BT_MESH_NETWORK_CREATE_GROUP,
+       BT_MESH_NETWORK_REMOVE_GROUP,
        BT_MESH_NETWORK_GET_GROUPS,
        BT_MESH_MODEL_CONFIG_GROUP_SUB,
        BT_MESH_MODEL_CONFIG_VIRTUAL_GROUP_SUB