Mesh: Handle Multi-application init & deinit logic 84/241384/2 accepted/tizen/unified/20200821.042426 submit/tizen/20200820.041741
authorAnupam Roy <anupam.r@samsung.com>
Wed, 19 Aug 2020 15:33:01 +0000 (21:03 +0530)
committerPyun DoHyun <dh79.pyun@samsung.com>
Thu, 20 Aug 2020 01:34:13 +0000 (01:34 +0000)
This patch handles following:-
- Introduces Network Unload API. This API
  will be used by application to unload
  all network resources from bt-service.
  During mesh application deinit, FRWK
  library will call Network Unload to cleanup
  resources from service layer. CDB will remain
  unaffected due to this.

- Implements init/deinit logic for multiple apps.
  bt-service keeps reference count of applications.
  mesh stack launch/unlaunch is done single time
  based on app reference count logic. Don't allow
  to stop mesh stack service, if atleast one app
  is using mesh service.

Change-Id: I705c9c4d462036a657184dbdbb131c77af83b3a3
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-network.h
bt-service/services/mesh/bt-service-mesh-main.c
bt-service/services/mesh/bt-service-mesh-network.c
include/bluetooth-mesh-api.h
include/bt-internal-types.h

index fa20b68..a1e2920 100644 (file)
@@ -98,6 +98,25 @@ BT_EXPORT_API int bluetooth_mesh_deinit(void)
        return BLUETOOTH_ERROR_NONE;
 }
 
+BT_EXPORT_API int bluetooth_mesh_network_unload(bluetooth_mesh_network_t *network)
+{
+       int result;
+
+       BT_CHECK_PARAMETER(network, 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));
+
+       BT_INFO("Mesh: Network Unload");
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_MESH_NETWORK_UNLOAD,
+                       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_destroy(bluetooth_mesh_network_t *network)
 {
        int result;
index 8e17a47..5b0b430 100644 (file)
@@ -3485,6 +3485,18 @@ normal:
                g_free((gpointer)requester_unique_creds);
                break;
        }
+       case BT_MESH_NETWORK_UNLOAD: {
+               bluetooth_mesh_network_t network;
+               memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
+
+               __bt_service_get_parameters(in_param1,
+                               &network, sizeof(bluetooth_mesh_network_t));
+
+               BT_INFO("MESH: Network Unload: Network UUID [%s]", network.uuid);
+               result = _bt_mesh_network_unload(requester_unique_creds,
+                               sender, &network);
+               break;
+       }
        case BT_MESH_NETWORK_SCAN: {
                bluetooth_mesh_network_t network;
                bluetooth_mesh_scan_param_t param;
@@ -5130,6 +5142,7 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_MESH_NETWORK_CREATE:
        case BT_MESH_NETWORK_DESTROY:
        case BT_MESH_NETWORK_LOAD:
+       case BT_MESH_NETWORK_UNLOAD:
        case BT_MESH_NETWORK_SCAN:
        case BT_MESH_NETWORK_CANCEL_SCAN:
        case BT_MESH_NETWORK_SET_CAPABILITIES:
index 4300455..795700d 100644 (file)
@@ -27,6 +27,8 @@
 #include "bluetooth-api.h"
 #include "bluetooth-mesh-api.h"
 
+#include "bt-service-mesh-cdb.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -40,6 +42,8 @@ int _bt_mesh_network_destroy(const char *app_cred,
 
 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);
+
 int _bt_mesh_network_remove_node_configuration(bluetooth_mesh_node_info_t *node);
 
 int _bt_mesh_network_create_cdb(int result,
@@ -50,6 +54,9 @@ int _bt_mesh_network_create_cdb(int result,
 int _bt_mesh_network_load(const char *app_cred,
                const char *sender, const char *token);
 
+int _bt_mesh_network_unload(const char *app_cred,
+               const char *sender, bluetooth_mesh_network_t *network);
+
 int _bt_mesh_network_load_cdb(int result, const char *sender,
                const char *app_creds, uint8_t uuid[16],
                        uint8_t token[8], char **network);
index ee82600..849edbc 100644 (file)
@@ -50,6 +50,7 @@
 #define MESH_LAUNCH_DELAY 500
 
 static guint launch_timer = 0;
+static guint mesh_app_ref_count;
 
 /* Event handlers */
 static void __bt_mesh_handle_pending_request_info(int result,
@@ -71,6 +72,11 @@ static void __bt_mesh_handle_pending_request_info(int result,
                case BT_MESH_INIT: {
                        BT_INFO("Mesh: Request: BT_MESH_INIT Sender: [%s] result[%d]",
                                        req_info->sender, result);
+
+                       if (result == BLUETOOTH_ERROR_NONE)
+                               /* 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,
                                out_param, result);
@@ -808,6 +814,7 @@ static gboolean __bt_mesh_launch_timer_expired_cb(gpointer data)
                        NULL, 0);
 
        /* Reset launch timer ID */
+       BT_INFO("Mesh: Timer ID after expiry [%u]", launch_timer);
        launch_timer = 0;
 
        return FALSE;
@@ -817,12 +824,23 @@ int _bt_mesh_init(void)
 {
        int ret = BLUETOOTH_ERROR_NONE;
 
-       BT_INFO("Mesh: Launch Timer val [%u]", launch_timer);
+       BT_INFO("Mesh: Total apps using Mesh: [%d]",
+               mesh_app_ref_count);
+
+       BT_INFO("Mesh: Current Timer ID [%u]", launch_timer);
        if (launch_timer > 0) {
                BT_INFO("Mesh: BT_MESH_INIT in progress");
                return ret;
        }
 
+       if (mesh_app_ref_count) {
+               BT_INFO("Mesh: Mesh Stack already initialized");
+               /* Increase mesh app ref count */
+               mesh_app_ref_count++;
+               return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
+       }
+
+       BT_INFO("Mesh: Mesh Stack init not done yet!");
        /* Launch bluetooth-meshd */
        ret = __bt_meshd_launch();
        if (BLUETOOTH_ERROR_NONE != ret) {
@@ -835,6 +853,7 @@ int _bt_mesh_init(void)
                                (GSourceFunc)__bt_mesh_launch_timer_expired_cb,
                                                                        NULL);
 
+       BT_INFO("Mesh: Timer ID [%u]", launch_timer);
        return ret;
 }
 
@@ -848,22 +867,31 @@ int _bt_mesh_deinit(void)
                launch_timer = 0;
        }
 
-       /* Terminate bluetooth-meshd */
-       ret = actd_stop_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
-                       MESH_SYSTEMD_SERVICE_NAME, 5000);
+       BT_INFO("Mesh: Current number of applications using mesh [%d]",
+                       mesh_app_ref_count);
 
-       if (ret != UNIT_CONTROL_OK)
-               BT_ERR("Failed to call systemact service: %d", ret);
+       if (mesh_app_ref_count == 1) {
+               BT_INFO("Mesh: Only one app using Mesh Stack: Unload & reduce ref count");
+               /* Terminate bluetooth-meshd */
+               ret = actd_stop_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
+                               MESH_SYSTEMD_SERVICE_NAME, 5000);
 
-       status = mesh_disable();
-       if (OAL_STATUS_SUCCESS != status) {
-               BT_ERR("Mesh: Failed to de-initialize Mesh profile, status: %d",
-                               status);
-               return BLUETOOTH_ERROR_INTERNAL;
+               if (ret != UNIT_CONTROL_OK)
+                       BT_ERR("Failed to call systemact service: %d", ret);
+
+               status = mesh_disable();
+               if (OAL_STATUS_SUCCESS != status) {
+                       BT_ERR("Mesh: Failed to de-initialize Mesh profile, status: %d",
+                                       status);
+                       return BLUETOOTH_ERROR_INTERNAL;
+               }
+
+               /* Un-Register Mesh event handler */
+               _bt_service_unregister_event_handler_callback(BT_MESH_MODULE);
        }
 
-       /* Register AVRCP target event handler */
-       _bt_service_unregister_event_handler_callback(BT_MESH_MODULE);
+       /* Decrease mesh app ref count */
+       mesh_app_ref_count--;
 
        return BLUETOOTH_ERROR_NONE;
 }
index 43db8fc..353e949 100644 (file)
@@ -223,6 +223,22 @@ int _bt_mesh_network_remove_node_configuration(
        return BLUETOOTH_ERROR_NONE;
 }
 
+void _bt_mesh_network_unload_net_configuration(_bt_mesh_cdb_t *cdb_cfg)
+{
+       BT_INFO("Mesh: Unload Network Configuration");
+
+       /* Unload Network from Keys */
+       _bt_mesh_keys_unload_net(cdb_cfg->uuid);
+
+       /* Unload Network from Nodes */
+       _bt_mesh_node_unload_net(cdb_cfg->uuid);
+
+       cdb_list = g_slist_remove(cdb_list, cdb_cfg);
+       _bt_mesh_conf_free(cdb_cfg);
+       BT_INFO("Mesh: CDB freed from memory: Remaining Networks [%d]",
+                       g_slist_length(cdb_list));
+}
+
 int _bt_mesh_network_remove_net_configuration(
                bluetooth_mesh_network_t *net)
 {
@@ -388,6 +404,38 @@ int _bt_mesh_network_create_cdb(int result,
        return BLUETOOTH_ERROR_NONE;
 }
 
+int _bt_mesh_network_unload(const char *app_cred,
+               const char *sender, bluetooth_mesh_network_t *network)
+{
+       GSList *l;
+       uint8_t net_uuid[16];
+       _bt_mesh_cdb_t *cdb_cfg;
+
+       BT_INFO("Mesh: Unload Network Configuration");
+       /* If Scanning is going on */
+       if (_bt_mesh_is_provisioning() ||
+                       _bt_mesh_is_scanning()) {
+               BT_ERR("Device is buzy..");
+               return BLUETOOTH_ERROR_DEVICE_BUSY;
+       }
+
+       _bt_mesh_util_convert_string_to_hex(network->uuid,
+                       strlen(network->uuid), net_uuid, 16);
+
+       /* Find CDB */
+       l = g_slist_find_custom(cdb_list, net_uuid,
+                       __mesh_compare_app_network_uuid);
+       if (!l) {
+               BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+       }
+
+       cdb_cfg = (_bt_mesh_cdb_t*)l->data;
+
+       _bt_mesh_network_unload_net_configuration(cdb_cfg);
+       return BLUETOOTH_ERROR_NONE;
+}
+
 int _bt_mesh_network_destroy(const char *app_cred,
        const char *sender, bluetooth_mesh_network_t *network)
 {
index eaf5d58..f538a10 100644 (file)
@@ -258,9 +258,18 @@ int bluetooth_mesh_network_create(const char *net_name,
                        bluetooth_mesh_model_t **models,
                                bluetooth_mesh_network_t *network);
 
+
+/**
+ * Destroy Local Network Configuration
+ */
 int bluetooth_mesh_network_destroy(bluetooth_mesh_network_t *network);
 
 /**
+ * Unload Local network Configuration
+ */
+int bluetooth_mesh_network_unload(bluetooth_mesh_network_t *network);
+
+/**
  * Reset a remote Node & remove it from network
  */
 int bluetooth_mesh_node_reset(bluetooth_mesh_node_info_t *node);
index 9a38ef9..10b147c 100644 (file)
@@ -471,6 +471,7 @@ typedef enum {
        BT_MESH_NETWORK_CREATE,
        BT_MESH_NETWORK_DESTROY,
        BT_MESH_NETWORK_LOAD,
+       BT_MESH_NETWORK_UNLOAD,
        BT_MESH_NETWORK_SCAN,
        BT_MESH_NETWORK_CANCEL_SCAN,
        BT_MESH_NETWORK_SET_CAPABILITIES,