2 * Open Adaptation Layer (OAL)
4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6 * @author: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include <bluetooth.h>
25 #include "oal-event.h"
26 #include "oal-internal.h"
27 #include "oal-manager.h"
28 #include "oal-adapter-mgr.h"
29 #include "oal-utils.h"
31 #include "oal-common.h"
34 static const bt_interface_t *blued_api;
35 static const btmesh_interface_t *mesh_api;
37 #define CHECK_OAL_MESH_ENABLED() \
39 if (mesh_api == NULL) { \
40 BT_ERR("Mesh Not Enabled"); \
41 return OAL_STATUS_NOT_READY; \
45 /* Forward declaration: Callbacks from HAL */
46 static void mesh_network_attached_callback(bt_status_t status,
47 bt_mesh_token_t *token, bt_uuid_t *uuid);
48 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
49 bt_status_t status, bt_uuid_t *net_uuid);
50 static void mesh_network_scan_result_callback(bt_status_t status,
51 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result);
52 static void mesh_network_provisioning_status_callback(bt_status_t status,
53 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid);
54 static void mesh_network_provisioning_finished_callback(bt_status_t status,
55 int reason, bt_uuid_t *net_uuid,
56 bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count);
57 static void mesh_network_provisioning_data_requested_callback(
58 bt_uuid_t *net_uuid, uint8_t count);
59 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
60 bt_hal_mesh_auth_variant_e auth_type, char auth_value[]);
61 static void mesh_network_netkey_execute_callback(bt_status_t status,
62 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx);
63 static void mesh_network_appkey_execute_callback(bt_status_t status,
64 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx);
65 static void mesh_network_appkey_execute_callback(bt_status_t status,
66 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx);
67 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
68 uint16_t source_addr, bool is_remote_devkey,
69 uint16_t netkey_idx, uint16_t ata_len, uint8_t *data);
72 static btmesh_callbacks_t sBluetoothMeshCallbacks = {
73 .size = sizeof(sBluetoothMeshCallbacks),
74 .network_attached_cb = mesh_network_attached_callback,
75 .scan_status_cb = mesh_network_scan_status_callback,
76 .scan_result_cb = mesh_network_scan_result_callback,
77 .provisioning_status_cb = mesh_network_provisioning_status_callback,
78 .provisioning_finished_cb = mesh_network_provisioning_finished_callback,
79 .provisioning_data_requested_cb = mesh_network_provisioning_data_requested_callback,
80 .authentication_requested_cb = mesh_network_authentication_requested_callback,
81 .netkey_execute_cb = mesh_network_netkey_execute_callback,
82 .appkey_execute_cb = mesh_network_appkey_execute_callback,
83 .devkey_msg_cb = mesh_devkey_message_received_callback,
86 /* Mesh HAL event handlers */
87 static void mesh_network_attached_callback(bt_status_t status,
88 bt_mesh_token_t *token, bt_uuid_t *uuid)
90 event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1);
92 event->status = convert_to_oal_status(status);
93 BT_INFO("Mesh Event: Network Attached, status: [%s]",
94 status2string(status));
96 memcpy(event->token, token->token, sizeof(bt_mesh_token_t));
97 memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t));
99 send_event_bda_trace(OAL_EVENT_MESH_NETWORK_ATTACHED,
100 event, sizeof(event_mesh_network_attached_t), NULL);
103 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
104 bt_status_t status, bt_uuid_t *net_uuid)
106 event_mesh_scan_status_t *event_data = g_new0(event_mesh_scan_status_t, 1);
109 event_data->status = convert_to_oal_status(status);
110 BT_INFO("Mesh Event: Scan status: [%s] state [%d]",
111 status2string(status), scan_state);
113 memcpy(event_data->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
115 event = (BT_MESH_SCAN_STARTED == scan_state) ? \
116 OAL_EVENT_MESH_SCAN_STARTED : OAL_EVENT_MESH_SCAN_FINISHED;
117 send_event_bda_trace(event, event_data,
118 sizeof(event_mesh_scan_status_t), NULL);
121 static void mesh_network_provisioning_status_callback(bt_status_t status,
122 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
124 event_mesh_provisioning_status_t *event = g_new0(event_mesh_provisioning_status_t, 1);
126 event->status = convert_to_oal_status(status);
127 BT_INFO("Mesh Event: Provisioning status: [%s]",
128 status2string(status));
130 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
131 memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
133 if (event->status == OAL_STATUS_SUCCESS)
134 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_STARTED,
135 event, sizeof(event_mesh_provisioning_status_t), NULL);
137 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FAILED,
138 event, sizeof(event_mesh_provisioning_status_t), NULL);
141 static void mesh_network_provisioning_finished_callback(bt_status_t status,
142 int reason, bt_uuid_t *net_uuid,
143 bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count)
145 event_mesh_provisioning_finished_t *event = \
146 g_new0(event_mesh_provisioning_finished_t, 1);
148 event->status = convert_to_oal_status(status);
149 event->reason = reason;
150 BT_INFO("Mesh Event: Provisioning Completed Result: [%s]",
151 status2string(status));
153 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
154 memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
155 event->unicast = unicast;
156 event->count = count;
158 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FINISHED,
159 event, sizeof(event_mesh_provisioning_finished_t), NULL);
162 static void mesh_network_provisioning_data_requested_callback(
163 bt_uuid_t *net_uuid, uint8_t count)
165 event_mesh_provisioning_data_requested_t *event = \
166 g_new0(event_mesh_provisioning_data_requested_t, 1);
168 BT_INFO("Mesh Event: Provisioning Data requested");
170 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
171 event->count = count;
173 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED,
174 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
177 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
178 bt_hal_mesh_auth_variant_e auth_type,
181 event_mesh_authentication_requested_t *event = \
182 g_new0(event_mesh_authentication_requested_t, 1);
184 BT_INFO("Mesh Event: Authentication requested");
186 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
187 event->auth_type = auth_type;
188 g_strlcpy(event->auth_value, auth_value, sizeof(event->auth_value));
190 send_event_bda_trace(OAL_EVENT_MESH_AUTHENTICATION_REQUESTED,
191 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
194 static void mesh_network_netkey_execute_callback(bt_status_t status,
195 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t index)
197 event_mesh_netkey_operation_t *event = \
198 g_new0(event_mesh_netkey_operation_t, 1);
200 event->status = convert_to_oal_status(status);
201 BT_INFO("Mesh Event: NetKey Execute Event");
203 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
204 event->op = (oal_mesh_key_op_e)key_event;
205 event->key_idx = index;
207 send_event_bda_trace(OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT,
208 event, sizeof(event_mesh_netkey_operation_t), NULL);
211 static void mesh_network_appkey_execute_callback(bt_status_t status,
212 bt_uuid_t *net_uuid, uint8_t key_event,
213 uint16_t net_idx, uint16_t app_idx)
215 event_mesh_appkey_operation_t *event = \
216 g_new0(event_mesh_appkey_operation_t, 1);
218 event->status = convert_to_oal_status(status);
219 BT_INFO("Mesh Event: AppKey Execute Event");
221 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
222 event->op = (oal_mesh_key_op_e)key_event;
223 event->net_idx = net_idx;
224 event->app_idx = app_idx;
226 send_event_bda_trace(OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT,
227 event, sizeof(event_mesh_appkey_operation_t), NULL);
230 static void mesh_network_scan_result_callback(bt_status_t status,
231 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result)
233 event_mesh_scan_result_t *event = g_new0(event_mesh_scan_result_t, 1);
235 event->status = convert_to_oal_status(status);
236 BT_INFO("Mesh Event: Scan Result status: [%s]",
237 status2string(status));
239 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
240 memcpy(&event->result, result, sizeof(bt_mesh_scan_result_t));
242 send_event_bda_trace(OAL_EVENT_MESH_SCAN_RESULT,
243 event, sizeof(event_mesh_scan_result_t), NULL);
246 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
247 uint16_t source_addr,
248 bool is_remote_devkey, uint16_t netkey_idx,
249 uint16_t data_len, uint8_t *data)
251 event_mesh_devkey_message_t *event = g_new0(event_mesh_devkey_message_t, 1);
253 BT_INFO("Mesh Event: Dev Key Message Received");
254 event->source = source_addr;
255 event->remote = is_remote_devkey;
256 event->subnet = netkey_idx;
257 event->data_len = data_len;
258 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
259 memcpy(event->data, data, data_len);
261 send_event_bda_trace(OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED, event,
262 sizeof(event_mesh_devkey_message_t), NULL);
265 oal_status_t mesh_enable(void)
270 /* Get stack interface */
271 blued_api = (const bt_interface_t *) adapter_get_stack_interface();
273 if (blued_api == NULL) {
274 BT_ERR("Stack is not initialized");
275 return OAL_STATUS_NOT_READY;
279 BT_WARN("MESH Interface is already initialized...");
280 return OAL_STATUS_ALREADY_DONE;
283 mesh_api = (const btmesh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_MESH_ID);
284 if (mesh_api == NULL) {
285 BT_ERR("MESH interface failed");
286 return OAL_STATUS_INTERNAL_ERROR;
289 if ((ret = mesh_api->init(&sBluetoothMeshCallbacks)) != BT_STATUS_SUCCESS) {
290 BT_ERR("Error: Unable to initialise MESH :%s", status2string(ret));
293 return convert_to_oal_status(ret);
296 BT_INFO("MESH successfully initialized");
297 return OAL_STATUS_SUCCESS;
300 oal_status_t mesh_disable(void)
303 CHECK_OAL_MESH_ENABLED();
308 return OAL_STATUS_SUCCESS;
311 oal_status_t mesh_register_node(oal_mesh_node_t *node,
312 GSList *model_list, bool is_provisioner)
314 int ret = BT_STATUS_SUCCESS;
316 CHECK_OAL_MESH_ENABLED();
318 BT_INFO("Mesh: Send create network request to stack");
319 ret = mesh_api->create((bt_hal_mesh_node_t*)node, model_list, is_provisioner);
320 if (ret != BT_STATUS_SUCCESS) {
321 BT_ERR("MESH: Create Network failed :failed: %s", status2string(ret));
322 return convert_to_oal_status(ret);
325 BT_INFO("Mesh: Request sent to stack");
326 return OAL_STATUS_SUCCESS;
329 oal_status_t mesh_network_start_scan(oal_uuid_t* network_uuid,
330 oal_mesh_scan_params_t *params)
332 int ret = BT_STATUS_SUCCESS;
334 CHECK_OAL_MESH_ENABLED();
336 ret = mesh_api->scan((bt_uuid_t*)network_uuid,
337 (bt_hal_mesh_scan_param_t*)params);
338 if (ret != BT_STATUS_SUCCESS) {
339 BT_ERR("MESH: Start Scan failed: %s", status2string(ret));
340 return convert_to_oal_status(ret);
343 return OAL_STATUS_SUCCESS;
346 oal_status_t mesh_network_scan_cancel(oal_uuid_t* network_uuid)
348 int ret = BT_STATUS_SUCCESS;
350 CHECK_OAL_MESH_ENABLED();
352 ret = mesh_api->scan_cancel((bt_uuid_t*)network_uuid);
353 if (ret != BT_STATUS_SUCCESS) {
354 BT_ERR("MESH: Scan Cancel failed: %s", status2string(ret));
355 return convert_to_oal_status(ret);
358 return OAL_STATUS_SUCCESS;
361 oal_status_t mesh_network_set_provisioning_capabilities(
362 oal_uuid_t *network_uuid,
363 oal_mesh_capabilities_t *caps)
365 int ret = BT_STATUS_SUCCESS;
367 CHECK_OAL_MESH_ENABLED();
369 ret = mesh_api->capability((bt_uuid_t*)network_uuid,
370 (bt_hal_mesh_prov_caps_t*)caps);
371 if (ret != BT_STATUS_SUCCESS) {
372 BT_ERR("MESH: Set Provisioning capabilities :failed: %s",
374 return convert_to_oal_status(ret);
377 return OAL_STATUS_SUCCESS;
380 oal_status_t mesh_conf_send_message(oal_uuid_t *network_uuid,
381 uint16_t dest, bool is_devkey_remote,
382 uint16_t netkey_idx, uint8_t *buf, int len)
384 int ret = BT_STATUS_SUCCESS;
386 CHECK_OAL_MESH_ENABLED();
388 ret = mesh_api->config_send((bt_uuid_t*)network_uuid,
389 dest, is_devkey_remote, netkey_idx, buf, len);
390 if (ret != BT_STATUS_SUCCESS) {
391 BT_ERR("MESH: Configuration Message sending failed: %s",
393 return convert_to_oal_status(ret);
396 return OAL_STATUS_SUCCESS;
399 oal_status_t mesh_conf_send_key_message(oal_uuid_t *network_uuid,
400 uint16_t dest, bool is_netkey,
401 bool is_update, int key_idx, int netkey_idx)
403 int ret = BT_STATUS_SUCCESS;
405 CHECK_OAL_MESH_ENABLED();
407 ret = mesh_api->key_send((bt_uuid_t*)network_uuid, dest,
408 is_netkey, is_update, key_idx, netkey_idx);
409 if (ret != BT_STATUS_SUCCESS) {
410 BT_ERR("MESH: Key Configuration Message sending failed: %s",
412 return convert_to_oal_status(ret);
415 return OAL_STATUS_SUCCESS;
418 oal_status_t mesh_network_provision_device(oal_uuid_t* network_uuid,
419 oal_uuid_t *dev_uuid)
421 int ret = BT_STATUS_SUCCESS;
423 CHECK_OAL_MESH_ENABLED();
425 ret = mesh_api->provision((bt_uuid_t*)network_uuid, (bt_uuid_t *)dev_uuid);
426 if (ret != BT_STATUS_SUCCESS) {
427 BT_ERR("MESH: Device Provisioning :failed: %s",
429 return convert_to_oal_status(ret);
432 return OAL_STATUS_SUCCESS;
435 oal_status_t mesh_network_send_provisioning_data(oal_uuid_t* network_uuid,
436 uint16_t netkey_idx, uint16_t unicast)
438 int ret = BT_STATUS_SUCCESS;
440 CHECK_OAL_MESH_ENABLED();
442 ret = mesh_api->provision_data((bt_uuid_t*)network_uuid, netkey_idx, unicast);
443 if (ret != BT_STATUS_SUCCESS) {
444 BT_ERR("MESH: Device Provisioning :failed: %s",
446 return convert_to_oal_status(ret);
449 return OAL_STATUS_SUCCESS;
452 oal_status_t mesh_network_subnet_execute(oal_uuid_t* network_uuid,
453 oal_mesh_key_op_e operation, uint16_t net_index)
455 int ret = BT_STATUS_SUCCESS;
457 CHECK_OAL_MESH_ENABLED();
459 ret = mesh_api->subnet_execute((bt_uuid_t*)network_uuid,
460 (bt_mesh_key_op_e)operation, net_index);
461 if (ret != BT_STATUS_SUCCESS) {
462 BT_ERR("MESH: Create Subnet :failed: %s", status2string(ret));
463 return convert_to_oal_status(ret);
466 return OAL_STATUS_SUCCESS;
469 oal_status_t mesh_network_appkey_execute(oal_uuid_t* network_uuid,
470 oal_mesh_key_op_e operation,
471 uint16_t net_index, uint16_t app_index)
473 int ret = BT_STATUS_SUCCESS;
475 CHECK_OAL_MESH_ENABLED();
477 ret = mesh_api->appkey_execute((bt_uuid_t*)network_uuid,
478 (bt_mesh_key_op_e)operation,
479 net_index, app_index);
480 if (ret != BT_STATUS_SUCCESS) {
481 BT_ERR("MESH: Create Subnet :failed: %s",
483 return convert_to_oal_status(ret);
486 return OAL_STATUS_SUCCESS;
489 oal_status_t mesh_authentication_reply(
490 oal_mesh_variant_authentication_e auth_type,
491 const char* auth_value)
493 int ret = BT_STATUS_SUCCESS;
495 CHECK_OAL_MESH_ENABLED();
497 ret = mesh_api->auth_reply((bt_hal_mesh_auth_variant_e)auth_type,
499 if (ret != BT_STATUS_SUCCESS) {
500 BT_ERR("MESH: Device Provisioning :failed: %s",
502 return convert_to_oal_status(ret);
505 return OAL_STATUS_SUCCESS;