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_destroyed_callback(bt_status_t status,
49 bt_mesh_token_t *token, bt_uuid_t *uuid);
50 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
51 bt_status_t status, bt_uuid_t *net_uuid);
52 static void mesh_network_scan_result_callback(bt_status_t status,
53 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result);
54 static void mesh_network_provisioning_status_callback(bt_status_t status,
55 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid);
56 static void mesh_network_provisioning_finished_callback(bt_status_t status,
57 int reason, bt_uuid_t *net_uuid,
58 bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count);
59 static void mesh_network_provisioning_data_requested_callback(
60 bt_uuid_t *net_uuid, uint8_t count);
61 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
62 bt_hal_mesh_auth_variant_e auth_type, char auth_value[]);
63 static void mesh_network_netkey_execute_callback(bt_status_t status,
64 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_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_network_appkey_execute_callback(bt_status_t status,
68 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx);
69 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
70 uint16_t source_addr, bool is_remote_devkey,
71 uint16_t netkey_idx, uint16_t ata_len, uint8_t *data);
72 static void mesh_message_received_callback(bt_uuid_t *net_uuid,
73 uint16_t source_addr, uint16_t dest_addr,
74 uint16_t key_idx, uint16_t data_len, uint8_t *data);
77 static btmesh_callbacks_t sBluetoothMeshCallbacks = {
78 .size = sizeof(sBluetoothMeshCallbacks),
79 .network_attached_cb = mesh_network_attached_callback,
80 .network_destroyed_cb = mesh_network_destroyed_callback,
81 .scan_status_cb = mesh_network_scan_status_callback,
82 .scan_result_cb = mesh_network_scan_result_callback,
83 .provisioning_status_cb = mesh_network_provisioning_status_callback,
84 .provisioning_finished_cb = mesh_network_provisioning_finished_callback,
85 .provisioning_data_requested_cb = mesh_network_provisioning_data_requested_callback,
86 .authentication_requested_cb = mesh_network_authentication_requested_callback,
87 .netkey_execute_cb = mesh_network_netkey_execute_callback,
88 .appkey_execute_cb = mesh_network_appkey_execute_callback,
89 .devkey_msg_cb = mesh_devkey_message_received_callback,
90 .msg_cb = mesh_message_received_callback,
93 /* Mesh HAL event handlers */
94 static void mesh_network_attached_callback(bt_status_t status,
95 bt_mesh_token_t *token, bt_uuid_t *uuid)
97 event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1);
99 event->status = convert_to_oal_status(status);
100 BT_INFO("Mesh Event: Network Attached, status: [%s]",
101 status2string(status));
103 memcpy(event->token, token->token, sizeof(bt_mesh_token_t));
104 memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t));
106 send_event_bda_trace(OAL_EVENT_MESH_NETWORK_ATTACHED,
107 event, sizeof(event_mesh_network_attached_t), NULL);
110 static void mesh_network_destroyed_callback(bt_status_t status,
111 bt_mesh_token_t *token, bt_uuid_t *uuid)
113 event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1);
115 event->status = convert_to_oal_status(status);
116 BT_INFO("Mesh Event: Network Destroyed, status: [%s]",
117 status2string(status));
119 memcpy(event->token, token->token, sizeof(bt_mesh_token_t));
120 memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t));
122 send_event_bda_trace(OAL_EVENT_MESH_NETWORK_DESTROYED,
123 event, sizeof(event_mesh_network_destroyed_t), NULL);
126 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
127 bt_status_t status, bt_uuid_t *net_uuid)
129 event_mesh_scan_status_t *event_data = g_new0(event_mesh_scan_status_t, 1);
132 event_data->status = convert_to_oal_status(status);
133 BT_INFO("Mesh Event: Scan status: [%s] state [%d]",
134 status2string(status), scan_state);
136 memcpy(event_data->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
138 event = (BT_MESH_SCAN_STARTED == scan_state) ? \
139 OAL_EVENT_MESH_SCAN_STARTED : OAL_EVENT_MESH_SCAN_FINISHED;
140 send_event_bda_trace(event, event_data,
141 sizeof(event_mesh_scan_status_t), NULL);
144 static void mesh_network_provisioning_status_callback(bt_status_t status,
145 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
147 event_mesh_provisioning_status_t *event = g_new0(event_mesh_provisioning_status_t, 1);
149 event->status = convert_to_oal_status(status);
150 BT_INFO("Mesh Event: Provisioning status: [%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));
156 if (event->status == OAL_STATUS_SUCCESS)
157 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_STARTED,
158 event, sizeof(event_mesh_provisioning_status_t), NULL);
160 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FAILED,
161 event, sizeof(event_mesh_provisioning_status_t), NULL);
164 static void mesh_network_provisioning_finished_callback(bt_status_t status,
165 int reason, bt_uuid_t *net_uuid,
166 bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count)
168 event_mesh_provisioning_finished_t *event = \
169 g_new0(event_mesh_provisioning_finished_t, 1);
171 event->status = convert_to_oal_status(status);
172 event->reason = reason;
173 BT_INFO("Mesh Event: Provisioning Completed Result: [%s]",
174 status2string(status));
176 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
177 memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
178 event->unicast = unicast;
179 event->count = count;
181 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FINISHED,
182 event, sizeof(event_mesh_provisioning_finished_t), NULL);
185 static void mesh_network_provisioning_data_requested_callback(
186 bt_uuid_t *net_uuid, uint8_t count)
188 event_mesh_provisioning_data_requested_t *event = \
189 g_new0(event_mesh_provisioning_data_requested_t, 1);
191 BT_INFO("Mesh Event: Provisioning Data requested");
193 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
194 event->count = count;
196 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED,
197 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
200 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
201 bt_hal_mesh_auth_variant_e auth_type,
204 event_mesh_authentication_requested_t *event = \
205 g_new0(event_mesh_authentication_requested_t, 1);
207 BT_INFO("Mesh Event: Authentication requested");
209 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
210 event->auth_type = auth_type;
211 g_strlcpy(event->auth_value, auth_value, sizeof(event->auth_value));
213 send_event_bda_trace(OAL_EVENT_MESH_AUTHENTICATION_REQUESTED,
214 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
217 static void mesh_network_netkey_execute_callback(bt_status_t status,
218 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t index)
220 event_mesh_netkey_operation_t *event = \
221 g_new0(event_mesh_netkey_operation_t, 1);
223 event->status = convert_to_oal_status(status);
224 BT_INFO("Mesh Event: NetKey Execute Event");
226 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
227 event->op = (oal_mesh_key_op_e)key_event;
228 event->key_idx = index;
230 send_event_bda_trace(OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT,
231 event, sizeof(event_mesh_netkey_operation_t), NULL);
234 static void mesh_network_appkey_execute_callback(bt_status_t status,
235 bt_uuid_t *net_uuid, uint8_t key_event,
236 uint16_t net_idx, uint16_t app_idx)
238 event_mesh_appkey_operation_t *event = \
239 g_new0(event_mesh_appkey_operation_t, 1);
241 event->status = convert_to_oal_status(status);
242 BT_INFO("Mesh Event: AppKey Execute Event");
244 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
245 event->op = (oal_mesh_key_op_e)key_event;
246 event->net_idx = net_idx;
247 event->app_idx = app_idx;
249 send_event_bda_trace(OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT,
250 event, sizeof(event_mesh_appkey_operation_t), NULL);
253 static void mesh_network_scan_result_callback(bt_status_t status,
254 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result)
256 event_mesh_scan_result_t *event = g_new0(event_mesh_scan_result_t, 1);
258 event->status = convert_to_oal_status(status);
259 BT_INFO("Mesh Event: Scan Result status: [%s]",
260 status2string(status));
262 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
263 memcpy(&event->result, result, sizeof(bt_mesh_scan_result_t));
265 send_event_bda_trace(OAL_EVENT_MESH_SCAN_RESULT,
266 event, sizeof(event_mesh_scan_result_t), NULL);
269 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
270 uint16_t source_addr,
271 bool is_remote_devkey, uint16_t netkey_idx,
272 uint16_t data_len, uint8_t *data)
274 event_mesh_devkey_message_t *event = g_new0(event_mesh_devkey_message_t, 1);
276 BT_INFO("Mesh Event: Dev Key Message Received");
277 event->source = source_addr;
278 event->remote = is_remote_devkey;
279 event->subnet = netkey_idx;
280 event->data_len = data_len;
281 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
282 memcpy(event->data, data, data_len);
284 send_event_bda_trace(OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED, event,
285 sizeof(event_mesh_devkey_message_t), NULL);
288 static void mesh_message_received_callback(bt_uuid_t *net_uuid,
289 uint16_t source_addr, uint16_t dest_addr, uint16_t key_idx,
290 uint16_t data_len, uint8_t *data)
292 event_mesh_message_t *event = g_new0(event_mesh_message_t, 1);
294 BT_INFO("Mesh Event: Model Message Received");
295 event->source = source_addr;
296 event->dest = dest_addr;
297 event->key_idx = key_idx;
298 event->data_len = data_len;
299 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
300 memcpy(event->data, data, data_len);
302 send_event_bda_trace(OAL_EVENT_MESH_MODEL_MESSAGE_RECEIVED, event,
303 sizeof(event_mesh_message_t), NULL);
306 oal_status_t mesh_enable(void)
311 /* Get stack interface */
312 blued_api = (const bt_interface_t *) adapter_get_stack_interface();
314 if (blued_api == NULL) {
315 BT_ERR("Stack is not initialized");
316 return OAL_STATUS_NOT_READY;
320 BT_WARN("MESH Interface is already initialized...");
321 return OAL_STATUS_ALREADY_DONE;
324 mesh_api = (const btmesh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_MESH_ID);
325 if (mesh_api == NULL) {
326 BT_ERR("MESH interface failed");
327 return OAL_STATUS_INTERNAL_ERROR;
330 if ((ret = mesh_api->init(&sBluetoothMeshCallbacks)) != BT_STATUS_SUCCESS) {
331 BT_ERR("Error: Unable to initialise MESH :%s", status2string(ret));
334 return convert_to_oal_status(ret);
337 BT_INFO("MESH successfully initialized");
338 return OAL_STATUS_SUCCESS;
341 oal_status_t mesh_disable(void)
344 CHECK_OAL_MESH_ENABLED();
349 return OAL_STATUS_SUCCESS;
352 oal_status_t mesh_register_node(oal_mesh_node_t *node,
353 GSList *model_list, bool is_provisioner)
355 int ret = BT_STATUS_SUCCESS;
357 CHECK_OAL_MESH_ENABLED();
359 BT_INFO("Mesh: Send create network request to stack");
360 ret = mesh_api->create((bt_hal_mesh_node_t*)node, model_list, is_provisioner);
361 if (ret != BT_STATUS_SUCCESS) {
362 BT_ERR("MESH: Create Network failed :failed: %s", status2string(ret));
363 return convert_to_oal_status(ret);
366 BT_INFO("Mesh: Request sent to stack");
367 return OAL_STATUS_SUCCESS;
370 oal_status_t mesh_network_release(oal_uuid_t* network_uuid)
372 int ret = BT_STATUS_SUCCESS;
374 CHECK_OAL_MESH_ENABLED();
376 BT_INFO("Mesh: Send Release Network request to stack");
377 ret = mesh_api->release((bt_uuid_t*)network_uuid);
378 if (ret != BT_STATUS_SUCCESS) {
379 BT_ERR("MESH: Network Leave failed: %s", status2string(ret));
380 return convert_to_oal_status(ret);
383 return OAL_STATUS_SUCCESS;
386 oal_status_t mesh_network_destroy(oal_uuid_t* network_uuid)
388 int ret = BT_STATUS_SUCCESS;
390 CHECK_OAL_MESH_ENABLED();
392 ret = mesh_api->destroy((bt_uuid_t*)network_uuid);
393 if (ret != BT_STATUS_SUCCESS) {
394 BT_ERR("MESH: Network Leave failed: %s", status2string(ret));
395 return convert_to_oal_status(ret);
398 return OAL_STATUS_SUCCESS;
401 oal_status_t mesh_delete_remote_node(oal_uuid_t* network_uuid,
402 uint16_t unicast, uint16_t num_elements)
404 int ret = BT_STATUS_SUCCESS;
406 CHECK_OAL_MESH_ENABLED();
408 ret = mesh_api->delete_node((bt_uuid_t*)network_uuid, unicast, num_elements);
409 if (ret != BT_STATUS_SUCCESS) {
410 BT_ERR("Mesh: Remote Node Deletion failed: %s", status2string(ret));
411 return convert_to_oal_status(ret);
414 return OAL_STATUS_SUCCESS;
417 oal_status_t mesh_network_start_scan(oal_uuid_t* network_uuid,
418 oal_mesh_scan_params_t *params)
420 int ret = BT_STATUS_SUCCESS;
422 CHECK_OAL_MESH_ENABLED();
424 ret = mesh_api->scan((bt_uuid_t*)network_uuid,
425 (bt_hal_mesh_scan_param_t*)params);
426 if (ret != BT_STATUS_SUCCESS) {
427 BT_ERR("MESH: Start Scan failed: %s", status2string(ret));
428 return convert_to_oal_status(ret);
431 return OAL_STATUS_SUCCESS;
434 oal_status_t mesh_network_scan_cancel(oal_uuid_t* network_uuid)
436 int ret = BT_STATUS_SUCCESS;
438 CHECK_OAL_MESH_ENABLED();
440 ret = mesh_api->scan_cancel((bt_uuid_t*)network_uuid);
441 if (ret != BT_STATUS_SUCCESS) {
442 BT_ERR("MESH: Scan Cancel failed: %s", status2string(ret));
443 return convert_to_oal_status(ret);
446 return OAL_STATUS_SUCCESS;
449 oal_status_t mesh_network_set_provisioning_capabilities(
450 oal_uuid_t *network_uuid,
451 oal_mesh_capabilities_t *caps)
453 int ret = BT_STATUS_SUCCESS;
455 CHECK_OAL_MESH_ENABLED();
457 ret = mesh_api->capability((bt_uuid_t*)network_uuid,
458 (bt_hal_mesh_prov_caps_t*)caps);
459 if (ret != BT_STATUS_SUCCESS) {
460 BT_ERR("MESH: Set Provisioning capabilities :failed: %s",
462 return convert_to_oal_status(ret);
465 return OAL_STATUS_SUCCESS;
468 oal_status_t mesh_conf_send_message(oal_uuid_t *network_uuid,
469 uint16_t dest, bool is_devkey_remote,
470 uint16_t netkey_idx, uint8_t *buf, int len)
472 int ret = BT_STATUS_SUCCESS;
474 CHECK_OAL_MESH_ENABLED();
476 ret = mesh_api->config_send((bt_uuid_t*)network_uuid,
477 dest, is_devkey_remote, netkey_idx, buf, len);
478 if (ret != BT_STATUS_SUCCESS) {
479 BT_ERR("MESH: Configuration Message sending failed: %s",
481 return convert_to_oal_status(ret);
484 return OAL_STATUS_SUCCESS;
487 oal_status_t mesh_conf_send_key_message(oal_uuid_t *network_uuid,
488 uint16_t dest, bool is_netkey,
489 bool is_update, int key_idx, int netkey_idx)
491 int ret = BT_STATUS_SUCCESS;
493 CHECK_OAL_MESH_ENABLED();
495 ret = mesh_api->key_send((bt_uuid_t*)network_uuid, dest,
496 is_netkey, is_update, key_idx, netkey_idx);
497 if (ret != BT_STATUS_SUCCESS) {
498 BT_ERR("MESH: Key Configuration Message sending failed: %s",
500 return convert_to_oal_status(ret);
503 return OAL_STATUS_SUCCESS;
506 oal_status_t mesh_model_send_message(oal_uuid_t *network_uuid,
507 uint16_t dest, uint16_t appkey_idx,
508 uint8_t *buf, int len)
510 int ret = BT_STATUS_SUCCESS;
512 CHECK_OAL_MESH_ENABLED();
514 ret = mesh_api->msg_execute((bt_uuid_t*)network_uuid,
515 dest, appkey_idx, buf, len);
516 if (ret != BT_STATUS_SUCCESS) {
517 BT_ERR("MESH: Model Message sending failed: %s",
519 return convert_to_oal_status(ret);
522 return OAL_STATUS_SUCCESS;
525 oal_status_t mesh_network_provision_device(oal_uuid_t* network_uuid,
526 oal_uuid_t *dev_uuid)
528 int ret = BT_STATUS_SUCCESS;
530 CHECK_OAL_MESH_ENABLED();
532 ret = mesh_api->provision((bt_uuid_t*)network_uuid, (bt_uuid_t *)dev_uuid);
533 if (ret != BT_STATUS_SUCCESS) {
534 BT_ERR("MESH: Device Provisioning :failed: %s",
536 return convert_to_oal_status(ret);
539 return OAL_STATUS_SUCCESS;
542 oal_status_t mesh_network_send_provisioning_data(oal_uuid_t* network_uuid,
543 uint16_t netkey_idx, uint16_t unicast)
545 int ret = BT_STATUS_SUCCESS;
547 CHECK_OAL_MESH_ENABLED();
549 ret = mesh_api->provision_data((bt_uuid_t*)network_uuid, netkey_idx, unicast);
550 if (ret != BT_STATUS_SUCCESS) {
551 BT_ERR("MESH: Device Provisioning :failed: %s",
553 return convert_to_oal_status(ret);
556 return OAL_STATUS_SUCCESS;
559 oal_status_t mesh_network_subnet_execute(oal_uuid_t* network_uuid,
560 oal_mesh_key_op_e operation, uint16_t net_index)
562 int ret = BT_STATUS_SUCCESS;
564 CHECK_OAL_MESH_ENABLED();
566 ret = mesh_api->subnet_execute((bt_uuid_t*)network_uuid,
567 (bt_mesh_key_op_e)operation, net_index);
568 if (ret != BT_STATUS_SUCCESS) {
569 BT_ERR("MESH: Create Subnet :failed: %s", status2string(ret));
570 return convert_to_oal_status(ret);
573 return OAL_STATUS_SUCCESS;
576 oal_status_t mesh_network_appkey_execute(oal_uuid_t* network_uuid,
577 oal_mesh_key_op_e operation,
578 uint16_t net_index, uint16_t app_index)
580 int ret = BT_STATUS_SUCCESS;
582 CHECK_OAL_MESH_ENABLED();
584 ret = mesh_api->appkey_execute((bt_uuid_t*)network_uuid,
585 (bt_mesh_key_op_e)operation,
586 net_index, app_index);
587 if (ret != BT_STATUS_SUCCESS) {
588 BT_ERR("MESH: Create Subnet :failed: %s",
590 return convert_to_oal_status(ret);
593 return OAL_STATUS_SUCCESS;
596 oal_status_t mesh_authentication_reply(
597 oal_mesh_variant_authentication_e auth_type,
598 const char* auth_value)
600 int ret = BT_STATUS_SUCCESS;
602 CHECK_OAL_MESH_ENABLED();
604 ret = mesh_api->auth_reply((bt_hal_mesh_auth_variant_e)auth_type,
606 if (ret != BT_STATUS_SUCCESS) {
607 BT_ERR("MESH: Device Provisioning :failed: %s",
609 return convert_to_oal_status(ret);
612 return OAL_STATUS_SUCCESS;