Mesh: Unload Network & free handles after de-init 85/241385/1
authorAnupam Roy <anupam.r@samsung.com>
Wed, 19 Aug 2020 15:43:51 +0000 (21:13 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Wed, 19 Aug 2020 15:43:51 +0000 (21:13 +0530)
All Network & its containing handles are freed
after deinitialization of Mesh.

Change-Id: I32d86a119b88b7c282bb890f7aa318212e23624c
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
src/bluetooth-mesh.c

index 2f99232..7df8f01 100644 (file)
@@ -102,6 +102,9 @@ GSList *group_list;
        } \
 } \
 
+/* forward declaration for static methods */
+static void __bt_mesh_destroy_network_handles(bt_mesh_network_s *net);
+
 size_t __bt_mesh_util_convert_hex_to_string(uint8_t *in,
                size_t in_len, char *out, size_t out_len)
 {
@@ -674,6 +677,37 @@ int bt_mesh_initialize(void)
        return BT_ERROR_NONE;
 }
 
+static void __mesh_unload_network_configurations(gpointer data,
+               gpointer user_data)
+{
+       bt_mesh_network_s *network_s = (bt_mesh_network_s*)data;
+       bluetooth_mesh_network_t net;
+
+       memset(&net, 0x00, sizeof(bluetooth_mesh_network_t));
+
+       g_strlcpy(net.uuid, network_s->uuid, 33);
+       g_strlcpy(net.token.token, network_s->token, 17);
+       g_strlcpy(net.name.name, network_s->name,
+                       BT_MESH_NETWORK_NAME_STRING_MAX_LEN + 1);
+
+       BT_INFO("Mesh: Send Network Unload Request");
+       if (BLUETOOTH_ERROR_NONE != bluetooth_mesh_network_unload(&net)) {
+               BT_ERR("Mesh: Failed to Unload Network [%s]",
+                               network_s->uuid);
+       } else {
+               BT_INFO("Mesh: Unoaded Network [%s] successfully",
+                               network_s->uuid);
+
+               __bt_mesh_destroy_network_handles(network_s);
+               networks = g_slist_remove(networks, network_s);
+               g_free(network_s);
+
+               BT_INFO("Mesh: Current number of networks after removing [%d]",
+                               g_slist_length(networks));
+
+       }
+}
+
 int bt_mesh_deinitialize(void)
 {
        FUNC_ENTRY;
@@ -687,6 +721,16 @@ int bt_mesh_deinitialize(void)
                BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error);
 
        is_mesh_initialized = false;
+       BT_INFO("Mesh: Mesh Deinitialized");
+
+       BT_INFO("Mesh: Remove each Network configuration");
+       /* Unload All Network Configurations */
+       g_slist_foreach(networks,
+               __mesh_unload_network_configurations,
+                       NULL);
+
+       BT_INFO("Mesh: After removal: Remaining Networks [%d]",
+               g_slist_length(networks));
 
        FUNC_EXIT;
        return BT_ERROR_NONE;
@@ -805,8 +849,9 @@ static void __bt_mesh_destroy_network_handles(bt_mesh_network_s *net)
        /* Remove all Nodes of Network */
        BT_INFO("Mesh: Total nodes present in Network [%d]",
                g_slist_length(net->nodes));
-       for (l = net->nodes; l != NULL; l = l->next) {
+       for (l = net->nodes; l != NULL;) {
                bt_mesh_node_s *node_s = (bt_mesh_node_s*)l->data;
+               l = g_slist_next(l);
 
                net->nodes = g_slist_remove(net->nodes, node_s);
                node_list = g_slist_remove(node_list, node_s);
@@ -820,8 +865,9 @@ static void __bt_mesh_destroy_network_handles(bt_mesh_network_s *net)
        /* Remove all Netkeys & Appkeys of Network */
        BT_INFO("Mesh: Total netkeys present in Network [%d]",
                g_slist_length(net->netkeys));
-       for (l = net->netkeys; l != NULL; l = l->next) {
+       for (l = net->netkeys; l != NULL;) {
                bt_mesh_netkey_s *netkey_s = (bt_mesh_netkey_s*)l->data;
+               l = g_slist_next(l);
 
                net->netkeys = g_slist_remove(net->netkeys, netkey_s);
                netkey_list = g_slist_remove(netkey_list, netkey_s);
@@ -834,8 +880,9 @@ static void __bt_mesh_destroy_network_handles(bt_mesh_network_s *net)
        /* Remove all groups of Network */
        BT_INFO("Mesh: Total groups present in Network [%d]",
                g_slist_length(net->groups));
-       for (l = net->groups; l != NULL; l = l->next) {
+       for (l = net->groups; l != NULL;) {
                bt_mesh_group_s *group_s = (bt_mesh_group_s*)l->data;
+               l = g_slist_next(l);
 
                net->groups = g_slist_remove(net->groups, group_s);
                group_list = g_slist_remove(group_list, group_s);