From f050aff800bdd9bda43b425154feb17e211ed86e Mon Sep 17 00:00:00 2001 From: Anupam Roy Date: Wed, 19 Aug 2020 21:03:01 +0530 Subject: [PATCH] Mesh: Handle Multi-application init & deinit logic 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 --- bt-api/bt-mesh.c | 19 ++++++++ bt-service/services/bt-request-handler.c | 13 ++++++ .../services/include/bt-service-mesh-network.h | 7 +++ bt-service/services/mesh/bt-service-mesh-main.c | 54 ++++++++++++++++------ bt-service/services/mesh/bt-service-mesh-network.c | 48 +++++++++++++++++++ include/bluetooth-mesh-api.h | 9 ++++ include/bt-internal-types.h | 1 + 7 files changed, 138 insertions(+), 13 deletions(-) diff --git a/bt-api/bt-mesh.c b/bt-api/bt-mesh.c index fa20b68..a1e2920 100644 --- a/bt-api/bt-mesh.c +++ b/bt-api/bt-mesh.c @@ -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; diff --git a/bt-service/services/bt-request-handler.c b/bt-service/services/bt-request-handler.c index 8e17a47..5b0b430 100644 --- a/bt-service/services/bt-request-handler.c +++ b/bt-service/services/bt-request-handler.c @@ -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: diff --git a/bt-service/services/include/bt-service-mesh-network.h b/bt-service/services/include/bt-service-mesh-network.h index 4300455..795700d 100644 --- a/bt-service/services/include/bt-service-mesh-network.h +++ b/bt-service/services/include/bt-service-mesh-network.h @@ -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); diff --git a/bt-service/services/mesh/bt-service-mesh-main.c b/bt-service/services/mesh/bt-service-mesh-main.c index ee82600..849edbc 100644 --- a/bt-service/services/mesh/bt-service-mesh-main.c +++ b/bt-service/services/mesh/bt-service-mesh-main.c @@ -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; } diff --git a/bt-service/services/mesh/bt-service-mesh-network.c b/bt-service/services/mesh/bt-service-mesh-network.c index 43db8fc..353e949 100644 --- a/bt-service/services/mesh/bt-service-mesh-network.c +++ b/bt-service/services/mesh/bt-service-mesh-network.c @@ -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) { diff --git a/include/bluetooth-mesh-api.h b/include/bluetooth-mesh-api.h index eaf5d58..f538a10 100644 --- a/include/bluetooth-mesh-api.h +++ b/include/bluetooth-mesh-api.h @@ -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); diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index 9a38ef9..10b147c 100644 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -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, -- 2.7.4