From: Anupam Roy Date: Thu, 25 Jun 2020 10:38:40 +0000 (+0530) Subject: Mesh: Implement OAL API's X-Git-Tag: submit/tizen/20200724.011403~26 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b6239463557b36ae3da8fe8e41d14ff94d794487;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git Mesh: Implement OAL API's This patch handles following: - Adds Mesh OAL events - Adds Implementation of Mesh API's Change-Id: I74f7cbf29e06042fd23a27b37b9fb0415269e92a Signed-off-by: Anupam Roy --- diff --git a/bt-oal/CMakeLists.txt b/bt-oal/CMakeLists.txt index a84da6f..e183c0a 100755 --- a/bt-oal/CMakeLists.txt +++ b/bt-oal/CMakeLists.txt @@ -28,6 +28,7 @@ oal-hfp.c oal-hdp.c oal-gatt.c oal-hf-client.c +oal-mesh.c common/oal-utils.c common/oal-common.c common/oal-event-dispatcher.c diff --git a/bt-oal/include/oal-event.h b/bt-oal/include/oal-event.h index b2e8062..4360a88 100644 --- a/bt-oal/include/oal-event.h +++ b/bt-oal/include/oal-event.h @@ -186,6 +186,18 @@ extern "C" { EVENT(OAL_EVENT_GATTC_EXECUTE_WRITE) /* gattc execute write */\ EVENT(OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE) /* gattc acquire write */\ EVENT(OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY) /* gattc acquire notify */\ + EVENT(OAL_EVENT_MESH_NETWORK_ATTACHED) /* mesh network attached */\ + EVENT(OAL_EVENT_MESH_SCAN_STARTED) /* mesh network scan start status */\ + EVENT(OAL_EVENT_MESH_SCAN_FINISHED) /* mesh network scan stop status*/\ + EVENT(OAL_EVENT_MESH_SCAN_RESULT) /* mesh Scan Result */\ + EVENT(OAL_EVENT_MESH_PROVISIONING_STARTED) /* Provisioning started successfully */\ + EVENT(OAL_EVENT_MESH_PROVISIONING_FAILED) /* Provisioning Failed */\ + EVENT(OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED) /* Provisioning Data Requested */\ + EVENT(OAL_EVENT_MESH_AUTHENTICATION_REQUESTED) /* Authentication requsted */\ + EVENT(OAL_EVENT_MESH_PROVISIONING_FINISHED) /* Provisioning Completed Event */\ + EVENT(OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT) /* Subnet Operations (Add/Update/Delete) Event */\ + EVENT(OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT) /* AppKey Operations (Add/Update/Delete) Event */\ + EVENT(OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED) /* DevKey message received Event */\ EVENT(OAL_EVENT_END) /* End of event*/\ diff --git a/bt-oal/include/oal-mesh.h b/bt-oal/include/oal-mesh.h index 5002d11..d13a4d0 100644 --- a/bt-oal/include/oal-mesh.h +++ b/bt-oal/include/oal-mesh.h @@ -388,7 +388,7 @@ oal_status_t mesh_provisioning_cancel(oal_uuid_t *local_device_uuid); * @see cb_mesh_conf_message() */ oal_status_t mesh_conf_send_message(oal_uuid_t *network_uuid, - int16_t dest, bool is_devkey_remote, + uint16_t dest, bool is_devkey_remote, uint16_t netkey_idx, uint8_t *buf, int len); /** diff --git a/bt-oal/oal-mesh.c b/bt-oal/oal-mesh.c new file mode 100644 index 0000000..c3cffc3 --- /dev/null +++ b/bt-oal/oal-mesh.c @@ -0,0 +1,506 @@ +/* + * Open Adaptation Layer (OAL) + * + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * @author: Anupam Roy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include "bt_mesh.h" + +#include "oal-event.h" +#include "oal-internal.h" +#include "oal-manager.h" +#include "oal-adapter-mgr.h" +#include "oal-utils.h" +#include "oal-mesh.h" +#include "oal-common.h" + + +static const bt_interface_t *blued_api; +static const btmesh_interface_t *mesh_api; + +#define CHECK_OAL_MESH_ENABLED() \ + do { \ + if (mesh_api == NULL) { \ + BT_ERR("Mesh Not Enabled"); \ + return OAL_STATUS_NOT_READY; \ + } \ + } while (0) + +/* Forward declaration: Callbacks from HAL */ +static void mesh_network_attached_callback(bt_status_t status, + bt_mesh_token_t *token, bt_uuid_t *uuid); +static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state, + bt_status_t status, bt_uuid_t *net_uuid); +static void mesh_network_scan_result_callback(bt_status_t status, + bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result); +static void mesh_network_provisioning_status_callback(bt_status_t status, + bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid); +static void mesh_network_provisioning_finished_callback(bt_status_t status, + int reason, bt_uuid_t *net_uuid, + bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count); +static void mesh_network_provisioning_data_requested_callback( + bt_uuid_t *net_uuid, uint8_t count); +static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid, + bt_hal_mesh_auth_variant_e auth_type, char auth_value[]); +static void mesh_network_netkey_execute_callback(bt_status_t status, + bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx); +static void mesh_network_appkey_execute_callback(bt_status_t status, + bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx); +static void mesh_network_appkey_execute_callback(bt_status_t status, + bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx); +static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid, + uint16_t source_addr, bool is_remote_devkey, + uint16_t netkey_idx, uint16_t ata_len, uint8_t *data); + + +static btmesh_callbacks_t sBluetoothMeshCallbacks = { + .size = sizeof(sBluetoothMeshCallbacks), + .network_attached_cb = mesh_network_attached_callback, + .scan_status_cb = mesh_network_scan_status_callback, + .scan_result_cb = mesh_network_scan_result_callback, + .provisioning_status_cb = mesh_network_provisioning_status_callback, + .provisioning_finished_cb = mesh_network_provisioning_finished_callback, + .provisioning_data_requested_cb = mesh_network_provisioning_data_requested_callback, + .authentication_requested_cb = mesh_network_authentication_requested_callback, + .netkey_execute_cb = mesh_network_netkey_execute_callback, + .appkey_execute_cb = mesh_network_appkey_execute_callback, + .devkey_msg_cb = mesh_devkey_message_received_callback, +}; + +/* Mesh HAL event handlers */ +static void mesh_network_attached_callback(bt_status_t status, + bt_mesh_token_t *token, bt_uuid_t *uuid) +{ + event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1); + + event->status = convert_to_oal_status(status); + BT_INFO("Mesh Event: Network Attached, status: [%s]", + status2string(status)); + + memcpy(event->token, token->token, sizeof(bt_mesh_token_t)); + memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t)); + + send_event_bda_trace(OAL_EVENT_MESH_NETWORK_ATTACHED, + event, sizeof(event_mesh_network_attached_t), NULL); +} + +static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state, + bt_status_t status, bt_uuid_t *net_uuid) +{ + event_mesh_scan_status_t *event_data = g_new0(event_mesh_scan_status_t, 1); + oal_event_t event; + + event_data->status = convert_to_oal_status(status); + BT_INFO("Mesh Event: Scan status: [%s] state [%d]", + status2string(status), scan_state); + + memcpy(event_data->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + + event = (BT_MESH_SCAN_STARTED == scan_state) ? \ + OAL_EVENT_MESH_SCAN_STARTED : OAL_EVENT_MESH_SCAN_FINISHED; + send_event_bda_trace(event, event_data, + sizeof(event_mesh_scan_status_t), NULL); +} + +static void mesh_network_provisioning_status_callback(bt_status_t status, + bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid) +{ + event_mesh_provisioning_status_t *event = g_new0(event_mesh_provisioning_status_t, 1); + + event->status = convert_to_oal_status(status); + BT_INFO("Mesh Event: Provisioning status: [%s]", + status2string(status)); + + memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t)); + + if (event->status == OAL_STATUS_SUCCESS) + send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_STARTED, + event, sizeof(event_mesh_provisioning_status_t), NULL); + else + send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FAILED, + event, sizeof(event_mesh_provisioning_status_t), NULL); +} + +static void mesh_network_provisioning_finished_callback(bt_status_t status, + int reason, bt_uuid_t *net_uuid, + bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count) +{ + event_mesh_provisioning_finished_t *event = \ + g_new0(event_mesh_provisioning_finished_t, 1); + + event->status = convert_to_oal_status(status); + event->reason = reason; + BT_INFO("Mesh Event: Provisioning Completed Result: [%s]", + status2string(status)); + + memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t)); + event->unicast = unicast; + event->count = count; + + send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FINISHED, + event, sizeof(event_mesh_provisioning_finished_t), NULL); +} + +static void mesh_network_provisioning_data_requested_callback( + bt_uuid_t *net_uuid, uint8_t count) +{ + event_mesh_provisioning_data_requested_t *event = \ + g_new0(event_mesh_provisioning_data_requested_t, 1); + + BT_INFO("Mesh Event: Provisioning Data requested"); + + memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + event->count = count; + + send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED, + event, sizeof(event_mesh_provisioning_data_requested_t), NULL); +} + +static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid, + bt_hal_mesh_auth_variant_e auth_type, + char auth_value[]) +{ + event_mesh_authentication_requested_t *event = \ + g_new0(event_mesh_authentication_requested_t, 1); + + BT_INFO("Mesh Event: Authentication requested"); + + memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + event->auth_type = auth_type; + g_strlcpy(event->auth_value, auth_value, sizeof(event->auth_value)); + + send_event_bda_trace(OAL_EVENT_MESH_AUTHENTICATION_REQUESTED, + event, sizeof(event_mesh_provisioning_data_requested_t), NULL); +} + +static void mesh_network_netkey_execute_callback(bt_status_t status, + bt_uuid_t *net_uuid, uint8_t key_event, uint16_t index) +{ + event_mesh_netkey_operation_t *event = \ + g_new0(event_mesh_netkey_operation_t, 1); + + event->status = convert_to_oal_status(status); + BT_INFO("Mesh Event: NetKey Execute Event"); + + memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + event->op = (oal_mesh_key_op_e)key_event; + event->key_idx = index; + + send_event_bda_trace(OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT, + event, sizeof(event_mesh_netkey_operation_t), NULL); +} + +static void mesh_network_appkey_execute_callback(bt_status_t status, + bt_uuid_t *net_uuid, uint8_t key_event, + uint16_t net_idx, uint16_t app_idx) +{ + event_mesh_appkey_operation_t *event = \ + g_new0(event_mesh_appkey_operation_t, 1); + + event->status = convert_to_oal_status(status); + BT_INFO("Mesh Event: AppKey Execute Event"); + + memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + event->op = (oal_mesh_key_op_e)key_event; + event->net_idx = net_idx; + event->app_idx = app_idx; + + send_event_bda_trace(OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT, + event, sizeof(event_mesh_appkey_operation_t), NULL); +} + +static void mesh_network_scan_result_callback(bt_status_t status, + bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result) +{ + event_mesh_scan_result_t *event = g_new0(event_mesh_scan_result_t, 1); + + event->status = convert_to_oal_status(status); + BT_INFO("Mesh Event: Scan Result status: [%s]", + status2string(status)); + + memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + memcpy(&event->result, result, sizeof(bt_mesh_scan_result_t)); + + send_event_bda_trace(OAL_EVENT_MESH_SCAN_RESULT, + event, sizeof(event_mesh_scan_result_t), NULL); +} + +static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid, + uint16_t source_addr, + bool is_remote_devkey, uint16_t netkey_idx, + uint16_t data_len, uint8_t *data) +{ + event_mesh_devkey_message_t *event = g_new0(event_mesh_devkey_message_t, 1); + + BT_INFO("Mesh Event: Dev Key Message Received"); + event->source = source_addr; + event->remote = is_remote_devkey; + event->subnet = netkey_idx; + event->data_len = data_len; + memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t)); + memcpy(event->data, data, data_len); + + send_event_bda_trace(OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED, event, + sizeof(event_mesh_devkey_message_t), NULL); +} + +oal_status_t mesh_enable(void) +{ + int ret; + API_TRACE(); + + /* Get stack interface */ + blued_api = (const bt_interface_t *) adapter_get_stack_interface(); + + if (blued_api == NULL) { + BT_ERR("Stack is not initialized"); + return OAL_STATUS_NOT_READY; + } + + if (mesh_api) { + BT_WARN("MESH Interface is already initialized..."); + return OAL_STATUS_ALREADY_DONE; + } + + mesh_api = (const btmesh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_MESH_ID); + if (mesh_api == NULL) { + BT_ERR("MESH interface failed"); + return OAL_STATUS_INTERNAL_ERROR; + } + + if ((ret = mesh_api->init(&sBluetoothMeshCallbacks)) != BT_STATUS_SUCCESS) { + BT_ERR("Error: Unable to initialise MESH :%s", status2string(ret)); + mesh_api->cleanup(); + mesh_api = NULL; + return convert_to_oal_status(ret); + } + + BT_INFO("MESH successfully initialized"); + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_disable(void) +{ + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + mesh_api->cleanup(); + + mesh_api = NULL; + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_register_node(oal_mesh_node_t *node, + GSList *model_list, bool is_provisioner) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + BT_INFO("Mesh: Send create network request to stack"); + ret = mesh_api->create((bt_hal_mesh_node_t*)node, model_list, is_provisioner); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Create Network failed :failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + + BT_INFO("Mesh: Request sent to stack"); + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_network_start_scan(oal_uuid_t* network_uuid, + oal_mesh_scan_params_t *params) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->scan((bt_uuid_t*)network_uuid, + (bt_hal_mesh_scan_param_t*)params); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Start Scan failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_network_scan_cancel(oal_uuid_t* network_uuid) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->scan_cancel((bt_uuid_t*)network_uuid); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Scan Cancel failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_network_set_provisioning_capabilities( + oal_uuid_t *network_uuid, + oal_mesh_capabilities_t *caps) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->capability((bt_uuid_t*)network_uuid, + (bt_hal_mesh_prov_caps_t*)caps); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Set Provisioning capabilities :failed: %s", + status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_conf_send_message(oal_uuid_t *network_uuid, + uint16_t dest, bool is_devkey_remote, + uint16_t netkey_idx, uint8_t *buf, int len) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->config_send((bt_uuid_t*)network_uuid, + dest, is_devkey_remote, netkey_idx, buf, len); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Configuration Message sending failed: %s", + status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_conf_send_key_message(oal_uuid_t *network_uuid, + uint16_t dest, bool is_netkey, + bool is_update, int key_idx, int netkey_idx) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->key_send((bt_uuid_t*)network_uuid, dest, + is_netkey, is_update, key_idx, netkey_idx); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Key Configuration Message sending failed: %s", + status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_network_provision_device(oal_uuid_t* network_uuid, + oal_uuid_t *dev_uuid) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->provision((bt_uuid_t*)network_uuid, (bt_uuid_t *)dev_uuid); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Device Provisioning :failed: %s", + status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_network_send_provisioning_data(oal_uuid_t* network_uuid, + uint16_t netkey_idx, uint16_t unicast) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->provision_data((bt_uuid_t*)network_uuid, netkey_idx, unicast); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Device Provisioning :failed: %s", + status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_network_subnet_execute(oal_uuid_t* network_uuid, + oal_mesh_key_op_e operation, uint16_t net_index) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->subnet_execute((bt_uuid_t*)network_uuid, + (bt_mesh_key_op_e)operation, net_index); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Create Subnet :failed: %s", status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_network_appkey_execute(oal_uuid_t* network_uuid, + oal_mesh_key_op_e operation, + uint16_t net_index, uint16_t app_index) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->appkey_execute((bt_uuid_t*)network_uuid, + (bt_mesh_key_op_e)operation, + net_index, app_index); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Create Subnet :failed: %s", + status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +} + +oal_status_t mesh_authentication_reply( + oal_mesh_variant_authentication_e auth_type, + const char* auth_value) +{ + int ret = BT_STATUS_SUCCESS; + API_TRACE(); + CHECK_OAL_MESH_ENABLED(); + + ret = mesh_api->auth_reply((bt_hal_mesh_auth_variant_e)auth_type, + auth_value); + if (ret != BT_STATUS_SUCCESS) { + BT_ERR("MESH: Device Provisioning :failed: %s", + status2string(ret)); + return convert_to_oal_status(ret); + } + + return OAL_STATUS_SUCCESS; +}