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>
1  2 
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

@@@ -605,8 -610,6 +605,12 @@@ 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));
  }
  
  /* To send stack event to hal-mesh handler */
@@@ -3356,7 -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");
                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: {
                                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 -5334,6 +5339,9 @@@ static void __name_owner_changed(GDBusC
  
        /* 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,
@@@ -34,6 -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 -56,7 +57,7 @@@ bool _bt_mesh_conf_parse_data(void *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);
  
  bool _bt_mesh_conf_set_phase_network_key(_bt_mesh_cdb_t *cfg,
        uint16_t net_idx, uint8_t phase);
  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
  }
@@@ -40,6 -40,6 +40,8 @@@ int _bt_mesh_network_create(const char 
  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);
@@@ -459,6 -459,6 +459,7 @@@ static bool __mesh_add_u8_16(json_objec
  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 -816,7 +817,7 @@@ bool _bt_mesh_conf_node_delete_applicat
  _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);
@@@ -52,6 -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,
                        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 -820,13 +830,15 @@@ static gboolean __bt_mesh_launch_timer_
        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");
  
        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;
        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;
        /* 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);
++}
@@@ -44,6 -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 -223,6 +224,39 @@@ int _bt_mesh_network_remove_node_config
        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 -352,7 +386,7 @@@ int _bt_mesh_network_create_cdb(int res
        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);