Handle bluetooth-meshd life cycle
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / mesh / bt-service-mesh-main.c
index 3ba340e..167b3ba 100644 (file)
@@ -29,6 +29,7 @@
 #include <time.h>
 #include <sys/time.h>
 #include <ell/ell.h>
+#include <actd/unit_control.h>
 
 #include "bluetooth-api.h"
 #include "bt-internal-types.h"
 #include "bt-service-mesh-util.h"
 #include "bt-service-mesh-network.h"
 #include "bt-service-mesh-nodes.h"
-//#include "bt-service-mesh-config-client.h"
+#include "bt-service-mesh-config-client.h"
 
 #include <oal-mesh.h>
 
+#define MESH_SYSTEMD_SERVICE_NAME "bluetooth-mesh.service"
+
 /* Event handlers */
 static void __bt_mesh_handle_pending_request_info(int result,
                int service_function, void *param,
@@ -101,7 +104,6 @@ static void __bt_mesh_handle_pending_request_info(int result,
                                _bt_service_method_return(req_info->context,
                                        out_param, result);
                                _bt_free_info_from_invocation_list(req_info);
-                               g_free(req_info->user_data);
                                g_array_free(out_param, TRUE);
                        }
                        break;
@@ -122,12 +124,26 @@ static void __bt_mesh_handle_pending_request_info(int result,
                                        BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
 
                        if (!g_strcmp0(network->token.token, token_str)) {
-
+                               char *network_name = NULL;
                                BT_INFO("Mesh: BT_MESH_NETWORK_LOAD Request found Token [%s]",
                                        token_str);
 
-                               /* TODO: Handle Meh Network Load CDB */
                                /* Send request to mesh-network to load keys and Nodes for the network */
+                               if (BLUETOOTH_ERROR_NONE == _bt_mesh_network_load_cdb(
+                                               result, req_info->sender, network->app_cred,
+                                                       node->uuid, node->token.u8, &network_name)) {
+                                       g_strlcpy(network->name.name, network_name, strlen(network_name));
+                               } else
+                                       BT_ERR("!!Mesh: BT_MESH_NETWORK_LOAD Failed!!");
+
+                               _bt_mesh_util_convert_hex_to_string((uint8_t *) node->uuid, 16, network->uuid,
+                                               BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
+
+                               out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+                               g_array_append_vals(out_param, network, sizeof(bluetooth_mesh_network_t));
+                               _bt_service_method_return(req_info->context, out_param, result);
+                               _bt_free_info_from_invocation_list(req_info);
+                               g_array_free(out_param, TRUE);
                        }
                        break;
                }
@@ -150,7 +166,6 @@ static void __bt_mesh_handle_pending_request_info(int result,
                                _bt_service_method_return(req_info->context,
                                        out_param, result);
                                _bt_free_info_from_invocation_list(req_info);
-                               g_free(req_info->user_data);
                                g_array_free(out_param, TRUE);
                        }
                        break;
@@ -172,6 +187,13 @@ static void __bt_mesh_handle_pending_request_info(int result,
                        _bt_mesh_util_convert_hex_to_string(
                                (uint8_t *) event->dev_uuid.uuid, 16, status_data.dev_uuid,
                                        BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
+                       BT_INFO("Mesh: Provision Status: Device UUID [%s]", status_data.dev_uuid);
+                       BT_INFO("Mesh: Provision Status: Net UUID [%s]", status_data.net_uuid);
+                       BT_INFO("Mesh: Provision Status: Result [%d]", event->status);
+                       if (event->status == OAL_STATUS_SUCCESS)
+                               BT_INFO("Mesh: Provisioning status : SUCCESS");
+                       else
+                               BT_INFO("Mesh: Provisioning status : FAIL");
 
                        BT_DBG("Request Sender: [%s]", req_info->sender);
                        if (!g_strcmp0(req_data->net_uuid, status_data.net_uuid)) {
@@ -180,7 +202,6 @@ static void __bt_mesh_handle_pending_request_info(int result,
                                        sizeof(bluetooth_mesh_provisioning_request_t));
                                _bt_service_method_return(req_info->context, out_param, result);
                                _bt_free_info_from_invocation_list(req_info);
-                               g_free(req_info->user_data);
                                g_array_free(out_param, TRUE);
                        }
                        break;
@@ -205,7 +226,6 @@ static void __bt_mesh_handle_pending_request_info(int result,
                                g_array_append_vals(out_param, &event->key_idx, sizeof(guint16));
                                _bt_service_method_return(req_info->context, out_param, result);
                                _bt_free_info_from_invocation_list(req_info);
-                               g_free(req_info->user_data);
                                g_array_free(out_param, TRUE);
                        }
                        break;
@@ -220,18 +240,15 @@ static void __bt_mesh_handle_pending_request_info(int result,
 
                        event = (event_mesh_appkey_operation_t*) param;
                        network = (bluetooth_mesh_network_t*)req_info->user_data;
-                       _bt_mesh_util_convert_hex_to_string(
-                               (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
-                                       BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
+                       _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
+                               BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
 
-                       BT_DBG("Request Sender: [%s]", req_info->sender);
+                        BT_DBG("Request Sender: [%s]", req_info->sender);
                        if (!g_strcmp0(network->uuid, net_uuid)) {
                                out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
-                               g_array_append_vals(out_param,
-                                       &event->app_idx, sizeof(guint16));
+                               g_array_append_vals(out_param, &event->app_idx, sizeof(guint16));
                                _bt_service_method_return(req_info->context, out_param, result);
                                _bt_free_info_from_invocation_list(req_info);
-                               g_free(req_info->user_data);
                                g_array_free(out_param, TRUE);
                        }
                        break;
@@ -243,10 +260,70 @@ static void __bt_mesh_handle_pending_request_info(int result,
        }
 }
 
+static void __handle_mesh_network_subnet_operation_event(
+               event_mesh_netkey_operation_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+
+       if (event->status != OAL_STATUS_SUCCESS)
+               result = BLUETOOTH_ERROR_INTERNAL;
+
+       /* Handle DBUS Context return */
+       if (event->op == OAL_MESH_KEY_ADD) {
+               if (result == BLUETOOTH_ERROR_NONE)
+                       _bt_mesh_network_handle_netkey_added(event->net_uuid.uuid, event->key_idx);
+
+               __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_ADD_NETKEY,
+                               event, sizeof(event_mesh_netkey_operation_t));
+       } else if (event->op == OAL_MESH_KEY_DELETE) {
+               if (result == BLUETOOTH_ERROR_NONE)
+                       _bt_mesh_network_handle_netkey_deleted(event->net_uuid.uuid, event->key_idx);
+
+               __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_DELETE_NETKEY,
+                               event, sizeof(event_mesh_netkey_operation_t));
+       } else if (event->op == OAL_MESH_KEY_UPDATE) {
+               _bt_mesh_network_handle_netkey_updated(event->net_uuid.uuid, event->key_idx);
+
+               __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_UPDATE_NETKEY,
+                               event, sizeof(event_mesh_netkey_operation_t));
+       }
+}
+
+static void __handle_mesh_network_appkey_operation_event(
+                       event_mesh_appkey_operation_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+
+       if (event->status != OAL_STATUS_SUCCESS)
+               result = BLUETOOTH_ERROR_INTERNAL;
+       /* Handle DBUS Context return */
+       if (event->op == OAL_MESH_KEY_ADD) {
+               BT_INFO("Mesh: Appkey Add event");
+               if (result == BLUETOOTH_ERROR_NONE)
+                       _bt_mesh_network_handle_appkey_added(
+                                       event->net_uuid.uuid, event->net_idx, event->app_idx);
+
+               __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_ADD_APPKEY,
+                               event, sizeof(event_mesh_netkey_operation_t));
+       } else if (event->op == OAL_MESH_KEY_DELETE) {
+               BT_INFO("Mesh: Appkey Delete event");
+               if (result == BLUETOOTH_ERROR_NONE)
+                       _bt_mesh_network_handle_appkey_deleted(
+                                       event->net_uuid.uuid, event->net_idx, event->app_idx);
+
+               __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_DELETE_APPKEY,
+                               event, sizeof(event_mesh_netkey_operation_t));
+       } else if (event->op == OAL_MESH_KEY_UPDATE) {
+               BT_INFO("Mesh: Appkey Update event");
+               __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_UPDATE_APPKEY,
+                               event, sizeof(event_mesh_netkey_operation_t));
+       }
+}
+
 static void  __handle_mesh_devkey_message_received_event(
                event_mesh_devkey_message_t *event)
 {
-       /* TODO Handle Devkey message Handler */
+       _bt_mesh_config_client_devkey_msg_handler(event);
 }
 
 static void __handle_mesh_network_attached_event(
@@ -318,11 +395,12 @@ static void __handle_mesh_network_scan_finished_event(
        GVariant *out_var = NULL, *param = NULL;
        GArray *info = NULL;
        bluetooth_mesh_network_t network;
-
        int result = BLUETOOTH_ERROR_NONE;
-       if (event->status != OAL_STATUS_SUCCESS)
+       if (event->status != OAL_STATUS_SUCCESS) {
+               BT_INFO("Mesh: Scan Finished: status:: FAILED!");
                result = BLUETOOTH_ERROR_INTERNAL;
-
+       } else
+               BT_INFO("Mesh: Scan Finished: status:: SUCCESS!");
 
        /* Handle Scan finsihed event */
        if (result == BLUETOOTH_ERROR_NONE) {
@@ -351,10 +429,11 @@ static void __handle_mesh_network_provisioning_started_event(
                event_mesh_provisioning_status_t *status)
 {
        int result = BLUETOOTH_ERROR_NONE;
+       BT_INFO("Mesh: Provisioning started");
 
        __bt_mesh_handle_pending_request_info(result,
                        BT_MESH_NETWORK_PROVISION_DEVICE,
-                       status, sizeof(event_mesh_scan_status_t));
+                       status, sizeof(event_mesh_provisioning_status_t));
 
        _bt_mesh_set_provisioning_state(true);
 }
@@ -363,10 +442,10 @@ static void __handle_mesh_network_provisioning_failed_event(
                event_mesh_provisioning_status_t *status)
 {
        int result = BLUETOOTH_ERROR_INTERNAL;
-
+       BT_INFO("Mesh: Provisioning failed!!");
        __bt_mesh_handle_pending_request_info(result,
                        BT_MESH_NETWORK_PROVISION_DEVICE,
-                       status, sizeof(event_mesh_scan_status_t));
+                       status, sizeof(event_mesh_provisioning_status_t));
 
        _bt_mesh_set_provisioning_state(false);
 }
@@ -377,13 +456,15 @@ static void __handle_mesh_network_provisioning_finished_event(
        GVariant *out_var = NULL, *param = NULL;
        GArray *info = NULL;
        bluetooth_mesh_provisioning_result_t prov_result;
+       BT_INFO("Mesh: Provisioning Finished!");
 
        memset(&prov_result, 0x00,
                        sizeof(bluetooth_mesh_provisioning_result_t));
 
        if (event->status != OAL_STATUS_SUCCESS)
                prov_result.result = BLUETOOTH_ERROR_INTERNAL;
-       prov_result.result = BLUETOOTH_ERROR_NONE;
+       else
+               prov_result.result = BLUETOOTH_ERROR_NONE;
 
        prov_result.reason = event->reason;
        prov_result.unicast = event->unicast;
@@ -410,8 +491,19 @@ static void __handle_mesh_network_provisioning_finished_event(
                        BLUETOOTH_EVENT_MESH_PROVISIONING_FINISHED,
                        param);
 
-       /* TODO Add newly provisioned Node info in Node Manager */
        /* Add Remote Node entry in Local CDB */
+       if (event->status == OAL_STATUS_SUCCESS) {
+               BT_INFO("Mesh: Provisioning done, add node to Network");
+               BT_INFO("Mesh: Node UUID [%s]", prov_result.dev_uuid);
+               BT_INFO("Mesh: Node Unicast[0x%2.2x] Element Count [%d]",
+                       event->unicast, event->count);
+
+               _bt_mesh_network_add_remote_node(
+                       event->net_uuid.uuid, event->dev_uuid.uuid,
+                               event->unicast, event->count);
+       }
+       /* Unset provisioning state */
+       _bt_mesh_set_provisioning_state(false);
 }
 
 static void __handle_mesh_network_provisioning_data_requested_event(
@@ -439,6 +531,8 @@ static void __handle_mesh_network_authentication_requested_event(
                        (uint8_t *) event->net_uuid.uuid, 16, auth_req.net_uuid,
                        BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
 
+       BT_INFO("Mesh: Authentication Requested by Device: Network [%s]",
+               auth_req.net_uuid);
        info = g_array_new(FALSE, FALSE, sizeof(gchar));
        g_array_append_vals(info, &auth_req,
                        sizeof(bluetooth_mesh_authentication_request_t));
@@ -503,6 +597,10 @@ static void __handle_mesh_network_scan_result_event(
 static void __handle_mesh_events(int event_type,
                gpointer event_data)
 {
+       BT_INFO("Mesh: Got Mesh event!!! event type [%d]", event_type);
+       if (event_type == OAL_EVENT_MESH_PROVISIONING_STARTED)
+               BT_INFO("Mesh: Provisioning started event");
+
        switch (event_type) {
        case OAL_EVENT_MESH_NETWORK_ATTACHED:
                __handle_mesh_network_attached_event(
@@ -525,11 +623,13 @@ static void __handle_mesh_events(int event_type,
                BT_PERMANENT_LOG("Mesh: Network Scan Result!!");
                break;
        case OAL_EVENT_MESH_PROVISIONING_STARTED:
+               BT_INFO("Mesh: Network Provisioning Started");
                __handle_mesh_network_provisioning_started_event(
                        (event_mesh_provisioning_status_t*)event_data);
                BT_PERMANENT_LOG("Mesh: Network Provisioning Started");
-       break;
+               break;
        case OAL_EVENT_MESH_PROVISIONING_FAILED:
+               BT_INFO("Mesh: Network Provisioning Failed!!!!");
                __handle_mesh_network_provisioning_failed_event(
                        (event_mesh_provisioning_status_t*)event_data);
                BT_PERMANENT_LOG("Mesh: Network Provisioning Failed");
@@ -550,11 +650,13 @@ static void __handle_mesh_events(int event_type,
                BT_PERMANENT_LOG("Mesh: Network Authentication Requested");
                break;
        case OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT:
-               /* TODO: Handle Netkey key DBUS Handler & event */
+               __handle_mesh_network_subnet_operation_event(
+                       (event_mesh_netkey_operation_t*)event_data);
                BT_PERMANENT_LOG("Mesh: Network Subnet operation event");
                break;
        case OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT:
-               /* TODO: Handle Netkey key DBUS Handler & event */
+                __handle_mesh_network_appkey_operation_event(
+                       (event_mesh_appkey_operation_t*)event_data);
                BT_PERMANENT_LOG("Mesh: AppKey operation event");
                break;
        case OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED:
@@ -569,8 +671,18 @@ static void __handle_mesh_events(int event_type,
 
 int _bt_mesh_init(void)
 {
+       int ret = UNIT_CONTROL_OK;
        oal_status_t status = OAL_STATUS_SUCCESS;
 
+       /* Launch bluetooth-meshd */
+       ret = actd_start_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
+                               MESH_SYSTEMD_SERVICE_NAME, 5000);
+
+       if (ret != UNIT_CONTROL_OK) {
+               BT_ERR("Failed to call systemact service: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
        status = mesh_enable();
        if (OAL_STATUS_SUCCESS != status) {
                BT_ERR("Mesh: Failed to initialize Mesh profile, status: %d",
@@ -589,6 +701,14 @@ int _bt_mesh_init(void)
 int _bt_mesh_deinit(void)
 {
        oal_status_t status = OAL_STATUS_SUCCESS;
+       int ret = UNIT_CONTROL_OK;
+
+       /* Terminate bluetooth-meshd */
+       ret = actd_stop_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
+                       MESH_SYSTEMD_SERVICE_NAME, 5000);
+
+       if (ret != UNIT_CONTROL_OK)
+               BT_ERR("Failed to call systemact service: %d", ret);
 
        status = mesh_disable();
        if (OAL_STATUS_SUCCESS != status) {