Mesh: Handle mesh application termination event 48/242148/2
authorAnupam Roy <anupam.r@samsung.com>
Fri, 21 Aug 2020 04:32:52 +0000 (04:32 +0000)
committerAnupam <anupam.r@samsung.com>
Mon, 24 Aug 2020 13:04:45 +0000 (18:34 +0530)
This patch handles following
- Keeps track of Mesh Apps Init & Deinit requests
- Handle App termination event & cleanup of resouces
  upon termination
- Reset HAL global DBUS resources on mesh stack
  deinitializaiotn (network proxy & agent message)

Change-Id: I4c7bc7287492f945131b6a7bb586fafe43aae064
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
bt-oal/bluez_hal/src/bt-hal-mesh-dbus-handler.c
bt-service/services/bt-request-handler.c
bt-service/services/include/bt-service-mesh-cdb.h
bt-service/services/include/bt-service-mesh-main.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-main.c
bt-service/services/mesh/bt-service-mesh-network.c

index 5c49b59..00b280b 100644 (file)
@@ -605,6 +605,10 @@ void _bt_hal_mesh_stack_deinit(void)
                l_dbus_destroy(dbus);
                dbus = NULL;
        }
+
+       /* Reset Globals */
+       net_proxy = NULL;
+       agent_msg = NULL;
        INFO("Mesh: Number of meshapps present in memory [%d]",
                        g_slist_length(mesh_apps));
 }
@@ -1465,7 +1469,7 @@ static struct l_dbus_message *__mesh_agent_prompt_static_request(
        uint8_t *net_uuid;
        const char *dbus_path;
        GSList *l;
-       meshcfg_app *app;
+       meshcfg_app *app = NULL;
 
        dbus_path =  l_dbus_message_get_path(msg);
        net_uuid = __mesh_get_net_uuid_from_path(dbus_path, true,
@@ -1475,7 +1479,13 @@ static struct l_dbus_message *__mesh_agent_prompt_static_request(
 
        l = g_slist_find_custom(mesh_apps, net_uuid,
                        __mesh_compare_network_uuid);
-       app = l->data;
+
+       if (l) {
+               app = l->data;
+       } else {
+               ERR("Mesh: app not found");
+       }
+
 
        memset(&ev, 0, sizeof(ev));
        memcpy(ev.net_uuid, net_uuid, 16);
@@ -1486,7 +1496,10 @@ static struct l_dbus_message *__mesh_agent_prompt_static_request(
 
                struct hal_ev_mesh_provision_finished ev;
                memset(&ev, 0, sizeof(ev));
-               memcpy(ev.net_uuid, app->uuid, 16);
+
+               if (app)
+                       memcpy(ev.net_uuid, app->uuid, 16);
+
                ev.status = BT_STATUS_FAIL;
                ev.reason = BT_HAL_MESH_PROV_ERR_INTERNAL;
                if (mesh_event_cb)
index 5b0b430..8a2f94e 100644 (file)
@@ -3356,7 +3356,9 @@ normal:
        }
 
        case BT_MESH_INIT:
-               result = _bt_mesh_init();
+               sender = (char*)g_dbus_method_invocation_get_sender(context);
+               BT_INFO("Mesh: Init by [%s]", sender);
+               result = _bt_mesh_init(sender);
                /* Save invocation */
                if (result == BLUETOOTH_ERROR_NONE) {
                        BT_INFO("Mesh: Save Invoation");
@@ -3368,7 +3370,9 @@ normal:
                break;
 
        case BT_MESH_DEINIT:
-               result = _bt_mesh_deinit();
+               sender = (char*)g_dbus_method_invocation_get_sender(context);
+               BT_INFO("Mesh: De-Init by [%s]", sender);
+               result = _bt_mesh_deinit(sender);
                break;
 
        case BT_MESH_NETWORK_CREATE: {
@@ -3425,6 +3429,7 @@ normal:
                                requester_unique_creds,
                                sizeof(network->app_cred));
                        sender = (char*)g_dbus_method_invocation_get_sender(context);
+                       BT_INFO("Mesh: Network Create by [%s]", sender);
                        _bt_save_invocation_context(context,
                                        result, sender,
                                        function_name, (gpointer)network);
@@ -5334,6 +5339,9 @@ static void __name_owner_changed(GDBusConnection *connection,
 
        /* Check if RFCOMM app is terminated */
        _bt_rfcomm_check_termination(name);
+
+       /* Mesh App Termination */
+       _bt_check_mesh_app_termination(name);
 }
 
 static void __bt_service_bus_acquired_handler(GDBusConnection *connection,
index 109c478..17dd398 100644 (file)
@@ -34,6 +34,7 @@ extern "C" {
 
 typedef struct {
        char *cfg_fname;
+       char *owner;
        char *app_cred;
        json_object *jcfg;
        uint8_t token[8];
@@ -56,7 +57,7 @@ bool _bt_mesh_conf_parse_data(void *cfg, int k);
 _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);
 
 bool _bt_mesh_conf_set_phase_network_key(_bt_mesh_cdb_t *cfg,
        uint16_t net_idx, uint8_t phase);
index 33ec0d1..ef6b9da 100644 (file)
 extern "C" {
 #endif
 
-int _bt_mesh_init(void);
+int _bt_mesh_init(const char *sender);
 
-int _bt_mesh_deinit(void);
+int _bt_mesh_deinit(const char *sender);
+
+void _bt_mesh_handle_app_termination(const char *sender);
 
 #ifdef __cplusplus
 }
index 795700d..148f648 100644 (file)
@@ -40,6 +40,8 @@ int _bt_mesh_network_create(const char *app_key,
 int _bt_mesh_network_destroy(const char *app_cred,
                const char *sender, bluetooth_mesh_network_t *network);
 
+void _bt_check_mesh_app_termination(const char *name);
+
 int _bt_mesh_network_remove_net_configuration(bluetooth_mesh_network_t *net);
 
 void _bt_mesh_network_unload_net_configuration(_bt_mesh_cdb_t *cdb_cfg);
index ca6dada..c69ea7f 100644 (file)
@@ -459,6 +459,7 @@ 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);
@@ -816,7 +817,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;
@@ -837,6 +838,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);
index 849edbc..a0779bc 100644 (file)
@@ -52,6 +52,8 @@
 static guint launch_timer = 0;
 static guint mesh_app_ref_count;
 
+static GSList *apps;
+
 /* Event handlers */
 static void __bt_mesh_handle_pending_request_info(int result,
                int service_function, void *param,
@@ -73,9 +75,17 @@ static void __bt_mesh_handle_pending_request_info(int result,
                        BT_INFO("Mesh: Request: BT_MESH_INIT Sender: [%s] result[%d]",
                                        req_info->sender, result);
 
-                       if (result == BLUETOOTH_ERROR_NONE)
+                       if (result == BLUETOOTH_ERROR_NONE) {
+
+                               /* Save Mesh App Owner */
+                               char *owner = g_strdup(req_info->sender);
+                               BT_INFO("Mesh: Insert Sender Mesh App List[%s]",
+                                               req_info->sender);
+                               apps = g_slist_append(apps, owner);
+
                                /* Increase mesh app ref count */
                                mesh_app_ref_count++;
+                       }
 
                        out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
                        _bt_service_method_return(req_info->context,
@@ -820,13 +830,15 @@ static gboolean __bt_mesh_launch_timer_expired_cb(gpointer data)
        return FALSE;
 }
 
-int _bt_mesh_init(void)
+int _bt_mesh_init(const char *sender)
 {
        int ret = BLUETOOTH_ERROR_NONE;
 
        BT_INFO("Mesh: Total apps using Mesh: [%d]",
                mesh_app_ref_count);
 
+       BT_INFO("Mesh: Mesh App Sender [%s]", sender);
+
        BT_INFO("Mesh: Current Timer ID [%u]", launch_timer);
        if (launch_timer > 0) {
                BT_INFO("Mesh: BT_MESH_INIT in progress");
@@ -835,6 +847,10 @@ int _bt_mesh_init(void)
 
        if (mesh_app_ref_count) {
                BT_INFO("Mesh: Mesh Stack already initialized");
+
+               /* Save Mesh App Owner */
+               apps = g_slist_append(apps, g_strdup(sender));
+
                /* Increase mesh app ref count */
                mesh_app_ref_count++;
                return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
@@ -857,11 +873,35 @@ int _bt_mesh_init(void)
        return ret;
 }
 
-int _bt_mesh_deinit(void)
+static gint __bt_mesh_match_sender(gconstpointer a, gconstpointer b)
+{
+       char *owner_a = (char*) a;
+       char *owner_b = (char*) b;
+
+       return g_strcmp0(owner_a, owner_b);
+}
+
+int _bt_mesh_deinit(const char *sender)
 {
+       GSList *l = NULL;
+       char *owner = NULL;
        oal_status_t status = OAL_STATUS_SUCCESS;
        int ret = UNIT_CONTROL_OK;
 
+       BT_INFO("Mesh: Deinit Request from App [%s]", sender);
+       BT_INFO("Mesh: Total Apps available in list [%d]",
+                       g_slist_length(apps));
+
+       /* Find & remove app entry from list */
+       l = g_slist_find_custom(apps, sender,
+                       (GCompareFunc)__bt_mesh_match_sender);
+       if (!l) {
+               BT_ERR("Mesh: App is not Mesh App");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_INFO("Mesh: Deinit Mesh: Sender Found: [%s]", sender);
+
        if (launch_timer > 0) {
                g_source_remove(launch_timer);
                launch_timer = 0;
@@ -893,5 +933,17 @@ int _bt_mesh_deinit(void)
        /* Decrease mesh app ref count */
        mesh_app_ref_count--;
 
+       owner = l->data;
+       apps = g_slist_remove(apps, owner);
+       g_free(owner);
+
        return BLUETOOTH_ERROR_NONE;
 }
+
+void _bt_mesh_handle_app_termination(const char *sender)
+{
+       BT_INFO("Mesh: Handle App termination: dbus app name[%s]",
+                       sender);
+
+       _bt_mesh_deinit(sender);
+}
index eddcc53..15daa0c 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "bt-service-mesh-network.h"
 #include "bt-service-mesh-cdb.h"
+#include "bt-service-mesh-main.h"
 #include "bt-service-mesh-nodes.h"
 #include "bt-service-mesh-keys.h"
 #include "bt-service-mesh-util.h"
@@ -223,6 +224,39 @@ int _bt_mesh_network_remove_node_configuration(
        return BLUETOOTH_ERROR_NONE;
 }
 
+void _bt_check_mesh_app_termination(const char *name)
+{
+       GSList *l;
+       _bt_mesh_cdb_t *cdb_cfg = NULL;
+       const char *app_cred = NULL;
+       BT_INFO("Mesh: App terminated [%s]", name);
+
+       /* TODO: Fetch app cred, when support is added */
+
+       for (l = cdb_list; l != NULL;) {
+               cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+               l = g_slist_next(l);
+
+               if (g_strcmp0(cdb_cfg->owner, name) == 0) {
+
+                       bluetooth_mesh_network_t network;
+                       memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
+
+                       _bt_mesh_util_convert_hex_to_string((uint8_t *) cdb_cfg->uuid,
+                                       16, network.uuid, sizeof(network.uuid));
+
+                       BT_INFO("Mesh: Got Network for unloading: UUID [%s]",
+                                       network.uuid);
+
+                       if (BLUETOOTH_ERROR_NONE != _bt_mesh_network_unload(app_cred, name, &network))
+                               BT_ERR("Mesh: Network unloading failed!!");
+                       else
+                               BT_INFO("Mesh: Network unloading Success!!");
+               }
+       }
+       _bt_mesh_handle_app_termination(name);
+}
+
 void _bt_mesh_network_unload_net_configuration(_bt_mesh_cdb_t *cdb_cfg)
 {
        BT_INFO("Mesh: Unload Network Configuration");
@@ -352,7 +386,7 @@ int _bt_mesh_network_create_cdb(int result,
        BT_INFO("Mesh: CDB File path[%s]", file_path);
        BT_INFO("Mesh: CDB App Cred[%s]", app_creds);
        cdb_cfg = _bt_mesh_conf_database_create(file_path, uuid,
-                       token, network, app_creds);
+                       token, network, sender, app_creds);
 
        /* Cleanup */
        g_free(dir_path);