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_proxy_added_callback(bt_status_t status);
47 static void mesh_network_attached_callback(bt_status_t status,
48 bt_mesh_token_t *token, bt_uuid_t *uuid);
49 static void mesh_network_destroyed_callback(bt_status_t status,
50 bt_mesh_token_t *token, bt_uuid_t *uuid);
51 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
52 bt_status_t status, bt_uuid_t *net_uuid);
53 static void mesh_network_scan_result_callback(bt_status_t status,
54 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result);
55 static void mesh_network_provisioning_status_callback(bt_status_t status,
56 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid);
57 static void mesh_network_provisioning_finished_callback(bt_status_t status,
58 int reason, bt_uuid_t *net_uuid,
59 bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count);
60 static void mesh_network_provisioning_data_requested_callback(
61 bt_uuid_t *net_uuid, uint8_t count);
62 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
63 bt_hal_mesh_auth_variant_e auth_type, char auth_value[]);
64 static void mesh_network_netkey_execute_callback(bt_status_t status,
65 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx);
66 static void mesh_network_appkey_execute_callback(bt_status_t status,
67 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx);
68 static void mesh_network_appkey_execute_callback(bt_status_t status,
69 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t netkey_idx, uint16_t appkey_idx);
70 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
71 uint16_t source_addr, bool is_remote_devkey,
72 uint16_t netkey_idx, uint16_t ata_len, uint8_t *data);
73 static void mesh_message_received_callback(bt_uuid_t *net_uuid,
74 uint16_t source_addr, uint16_t dest_addr,
75 uint16_t key_idx, uint16_t data_len, uint8_t *data);
78 static btmesh_callbacks_t sBluetoothMeshCallbacks = {
79 .size = sizeof(sBluetoothMeshCallbacks),
80 .network_proxy_added_cb = mesh_network_proxy_added_callback,
81 .network_attached_cb = mesh_network_attached_callback,
82 .network_destroyed_cb = mesh_network_destroyed_callback,
83 .scan_status_cb = mesh_network_scan_status_callback,
84 .scan_result_cb = mesh_network_scan_result_callback,
85 .provisioning_status_cb = mesh_network_provisioning_status_callback,
86 .provisioning_finished_cb = mesh_network_provisioning_finished_callback,
87 .provisioning_data_requested_cb = mesh_network_provisioning_data_requested_callback,
88 .authentication_requested_cb = mesh_network_authentication_requested_callback,
89 .netkey_execute_cb = mesh_network_netkey_execute_callback,
90 .appkey_execute_cb = mesh_network_appkey_execute_callback,
91 .devkey_msg_cb = mesh_devkey_message_received_callback,
92 .msg_cb = mesh_message_received_callback,
95 /* Mesh HAL event handlers */
96 static void mesh_network_proxy_added_callback(bt_status_t status)
98 event_mesh_network_proxy_added_t *event = g_new0(event_mesh_network_proxy_added_t, 1);
100 event->status = convert_to_oal_status(status);
101 BT_INFO("Mesh Event: Network Proxy Added, status: [%s]",
102 status2string(status));
104 send_event_bda_trace(OAL_EVENT_MESH_NETWORK_PROXY_ADDED,
105 event, sizeof(event_mesh_network_proxy_added_t), NULL);
108 static void mesh_network_attached_callback(bt_status_t status,
109 bt_mesh_token_t *token, bt_uuid_t *uuid)
111 event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1);
113 event->status = convert_to_oal_status(status);
114 BT_INFO("Mesh Event: Network Attached, status: [%s]",
115 status2string(status));
117 memcpy(event->token, token->token, sizeof(bt_mesh_token_t));
118 memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t));
120 send_event_bda_trace(OAL_EVENT_MESH_NETWORK_ATTACHED,
121 event, sizeof(event_mesh_network_attached_t), NULL);
124 static void mesh_network_destroyed_callback(bt_status_t status,
125 bt_mesh_token_t *token, bt_uuid_t *uuid)
127 event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1);
129 event->status = convert_to_oal_status(status);
130 BT_INFO("Mesh Event: Network Destroyed, status: [%s]",
131 status2string(status));
133 memcpy(event->token, token->token, sizeof(bt_mesh_token_t));
134 memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t));
136 send_event_bda_trace(OAL_EVENT_MESH_NETWORK_DESTROYED,
137 event, sizeof(event_mesh_network_destroyed_t), NULL);
140 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
141 bt_status_t status, bt_uuid_t *net_uuid)
143 event_mesh_scan_status_t *event_data = g_new0(event_mesh_scan_status_t, 1);
146 event_data->status = convert_to_oal_status(status);
147 BT_INFO("Mesh Event: Scan status: [%s] state [%d]",
148 status2string(status), scan_state);
150 memcpy(event_data->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
152 event = (BT_MESH_SCAN_STARTED == scan_state) ? \
153 OAL_EVENT_MESH_SCAN_STARTED : OAL_EVENT_MESH_SCAN_FINISHED;
154 send_event_bda_trace(event, event_data,
155 sizeof(event_mesh_scan_status_t), NULL);
158 static void mesh_network_provisioning_status_callback(bt_status_t status,
159 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
161 event_mesh_provisioning_status_t *event = g_new0(event_mesh_provisioning_status_t, 1);
163 event->status = convert_to_oal_status(status);
164 BT_INFO("Mesh Event: Provisioning status: [%s]",
165 status2string(status));
167 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
168 memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
170 if (event->status == OAL_STATUS_SUCCESS)
171 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_STARTED,
172 event, sizeof(event_mesh_provisioning_status_t), NULL);
174 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FAILED,
175 event, sizeof(event_mesh_provisioning_status_t), NULL);
178 static void mesh_network_provisioning_finished_callback(bt_status_t status,
179 int reason, bt_uuid_t *net_uuid,
180 bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count)
182 event_mesh_provisioning_finished_t *event = \
183 g_new0(event_mesh_provisioning_finished_t, 1);
185 event->status = convert_to_oal_status(status);
186 event->reason = reason;
187 BT_INFO("Mesh Event: Provisioning Completed Result: [%s]",
188 status2string(status));
190 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
191 memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
192 event->unicast = unicast;
193 event->count = count;
195 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FINISHED,
196 event, sizeof(event_mesh_provisioning_finished_t), NULL);
199 static void mesh_network_provisioning_data_requested_callback(
200 bt_uuid_t *net_uuid, uint8_t count)
202 event_mesh_provisioning_data_requested_t *event = \
203 g_new0(event_mesh_provisioning_data_requested_t, 1);
205 BT_INFO("Mesh Event: Provisioning Data requested");
207 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
208 event->count = count;
210 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED,
211 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
214 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
215 bt_hal_mesh_auth_variant_e auth_type,
218 event_mesh_authentication_requested_t *event = \
219 g_new0(event_mesh_authentication_requested_t, 1);
221 BT_INFO("Mesh Event: Authentication requested");
223 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
224 event->auth_type = auth_type;
225 g_strlcpy(event->auth_value, auth_value, sizeof(event->auth_value));
227 send_event_bda_trace(OAL_EVENT_MESH_AUTHENTICATION_REQUESTED,
228 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
231 static void mesh_network_netkey_execute_callback(bt_status_t status,
232 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t index)
234 event_mesh_netkey_operation_t *event = \
235 g_new0(event_mesh_netkey_operation_t, 1);
237 event->status = convert_to_oal_status(status);
238 BT_INFO("Mesh Event: NetKey Execute Event");
240 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
241 event->op = (oal_mesh_key_op_e)key_event;
242 event->key_idx = index;
244 send_event_bda_trace(OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT,
245 event, sizeof(event_mesh_netkey_operation_t), NULL);
248 static void mesh_network_appkey_execute_callback(bt_status_t status,
249 bt_uuid_t *net_uuid, uint8_t key_event,
250 uint16_t net_idx, uint16_t app_idx)
252 event_mesh_appkey_operation_t *event = \
253 g_new0(event_mesh_appkey_operation_t, 1);
255 event->status = convert_to_oal_status(status);
256 BT_INFO("Mesh Event: AppKey Execute Event");
258 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
259 event->op = (oal_mesh_key_op_e)key_event;
260 event->net_idx = net_idx;
261 event->app_idx = app_idx;
263 send_event_bda_trace(OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT,
264 event, sizeof(event_mesh_appkey_operation_t), NULL);
267 static void mesh_network_scan_result_callback(bt_status_t status,
268 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result)
270 event_mesh_scan_result_t *event = g_new0(event_mesh_scan_result_t, 1);
272 event->status = convert_to_oal_status(status);
273 BT_INFO("Mesh Event: Scan Result status: [%s]",
274 status2string(status));
276 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
277 memcpy(&event->result, result, sizeof(bt_mesh_scan_result_t));
279 send_event_bda_trace(OAL_EVENT_MESH_SCAN_RESULT,
280 event, sizeof(event_mesh_scan_result_t), NULL);
283 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
284 uint16_t source_addr,
285 bool is_remote_devkey, uint16_t netkey_idx,
286 uint16_t data_len, uint8_t *data)
288 event_mesh_devkey_message_t *event = g_new0(event_mesh_devkey_message_t, 1);
290 BT_INFO("Mesh Event: Dev Key Message Received");
291 event->source = source_addr;
292 event->remote = is_remote_devkey;
293 event->subnet = netkey_idx;
294 event->data_len = data_len;
295 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
296 memcpy(event->data, data, data_len);
298 send_event_bda_trace(OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED, event,
299 sizeof(event_mesh_devkey_message_t), NULL);
302 static void mesh_message_received_callback(bt_uuid_t *net_uuid,
303 uint16_t source_addr, uint16_t dest_addr, uint16_t key_idx,
304 uint16_t data_len, uint8_t *data)
306 event_mesh_message_t *event = g_new0(event_mesh_message_t, 1);
308 BT_INFO("Mesh Event: Model Message Received");
309 event->source = source_addr;
310 event->dest = dest_addr;
311 event->key_idx = key_idx;
312 event->data_len = data_len;
313 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
314 memcpy(event->data, data, data_len);
316 send_event_bda_trace(OAL_EVENT_MESH_MODEL_MESSAGE_RECEIVED, event,
317 sizeof(event_mesh_message_t), NULL);
320 oal_status_t mesh_enable(void)
325 /* Get stack interface */
326 blued_api = (const bt_interface_t *) adapter_get_stack_interface();
328 if (blued_api == NULL) {
329 BT_ERR("Stack is not initialized");
330 return OAL_STATUS_NOT_READY;
334 BT_WARN("MESH Interface is already initialized...");
335 return OAL_STATUS_ALREADY_DONE;
338 mesh_api = (const btmesh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_MESH_ID);
339 if (mesh_api == NULL) {
340 BT_ERR("MESH interface failed");
341 return OAL_STATUS_INTERNAL_ERROR;
344 if ((ret = mesh_api->init(&sBluetoothMeshCallbacks)) != BT_STATUS_SUCCESS) {
345 BT_ERR("Error: Unable to initialise MESH :%s", status2string(ret));
348 return convert_to_oal_status(ret);
351 BT_INFO("MESH successfully initialized");
352 return OAL_STATUS_SUCCESS;
355 oal_status_t mesh_disable(void)
358 CHECK_OAL_MESH_ENABLED();
363 return OAL_STATUS_SUCCESS;
366 oal_status_t mesh_register_node(oal_mesh_node_t *node,
367 GSList *model_list, bool is_provisioner)
369 int ret = BT_STATUS_SUCCESS;
371 CHECK_OAL_MESH_ENABLED();
373 BT_INFO("Mesh: Send create network request to stack");
374 ret = mesh_api->create((bt_hal_mesh_node_t*)node, model_list, is_provisioner);
375 if (ret != BT_STATUS_SUCCESS) {
376 BT_ERR("MESH: Create Network failed :failed: %s", status2string(ret));
377 return convert_to_oal_status(ret);
380 BT_INFO("Mesh: Request sent to stack");
381 return OAL_STATUS_SUCCESS;
384 oal_status_t mesh_network_release(oal_uuid_t* network_uuid)
386 int ret = BT_STATUS_SUCCESS;
388 CHECK_OAL_MESH_ENABLED();
390 BT_INFO("Mesh: Send Release Network request to stack");
391 ret = mesh_api->release((bt_uuid_t*)network_uuid);
392 if (ret != BT_STATUS_SUCCESS) {
393 BT_ERR("MESH: Network Leave failed: %s", status2string(ret));
394 return convert_to_oal_status(ret);
397 return OAL_STATUS_SUCCESS;
400 oal_status_t mesh_network_destroy(oal_uuid_t* network_uuid)
402 int ret = BT_STATUS_SUCCESS;
404 CHECK_OAL_MESH_ENABLED();
406 ret = mesh_api->destroy((bt_uuid_t*)network_uuid);
407 if (ret != BT_STATUS_SUCCESS) {
408 BT_ERR("MESH: Network Leave failed: %s", status2string(ret));
409 return convert_to_oal_status(ret);
412 return OAL_STATUS_SUCCESS;
415 oal_status_t mesh_delete_remote_node(oal_uuid_t* network_uuid,
416 uint16_t unicast, uint16_t num_elements)
418 int ret = BT_STATUS_SUCCESS;
420 CHECK_OAL_MESH_ENABLED();
422 ret = mesh_api->delete_node((bt_uuid_t*)network_uuid, unicast, num_elements);
423 if (ret != BT_STATUS_SUCCESS) {
424 BT_ERR("Mesh: Remote Node Deletion failed: %s", status2string(ret));
425 return convert_to_oal_status(ret);
428 return OAL_STATUS_SUCCESS;
431 oal_status_t mesh_network_start_scan(oal_uuid_t* network_uuid,
432 oal_mesh_scan_params_t *params)
434 int ret = BT_STATUS_SUCCESS;
436 CHECK_OAL_MESH_ENABLED();
438 ret = mesh_api->scan((bt_uuid_t*)network_uuid,
439 (bt_hal_mesh_scan_param_t*)params);
440 if (ret != BT_STATUS_SUCCESS) {
441 BT_ERR("MESH: Start Scan failed: %s", status2string(ret));
442 return convert_to_oal_status(ret);
445 return OAL_STATUS_SUCCESS;
448 oal_status_t mesh_network_scan_cancel(oal_uuid_t* network_uuid)
450 int ret = BT_STATUS_SUCCESS;
452 CHECK_OAL_MESH_ENABLED();
454 ret = mesh_api->scan_cancel((bt_uuid_t*)network_uuid);
455 if (ret != BT_STATUS_SUCCESS) {
456 BT_ERR("MESH: Scan Cancel failed: %s", status2string(ret));
457 return convert_to_oal_status(ret);
460 return OAL_STATUS_SUCCESS;
463 oal_status_t mesh_network_set_provisioning_capabilities(
464 oal_uuid_t *network_uuid,
465 oal_mesh_capabilities_t *caps)
467 int ret = BT_STATUS_SUCCESS;
469 CHECK_OAL_MESH_ENABLED();
471 ret = mesh_api->capability((bt_uuid_t*)network_uuid,
472 (bt_hal_mesh_prov_caps_t*)caps);
473 if (ret != BT_STATUS_SUCCESS) {
474 BT_ERR("MESH: Set Provisioning capabilities :failed: %s",
476 return convert_to_oal_status(ret);
479 return OAL_STATUS_SUCCESS;
482 oal_status_t mesh_conf_send_message(oal_uuid_t *network_uuid,
483 uint16_t dest, bool is_devkey_remote,
484 uint16_t netkey_idx, uint8_t *buf, int len)
486 int ret = BT_STATUS_SUCCESS;
488 CHECK_OAL_MESH_ENABLED();
490 ret = mesh_api->config_send((bt_uuid_t*)network_uuid,
491 dest, is_devkey_remote, netkey_idx, buf, len);
492 if (ret != BT_STATUS_SUCCESS) {
493 BT_ERR("MESH: Configuration Message sending failed: %s",
495 return convert_to_oal_status(ret);
498 return OAL_STATUS_SUCCESS;
501 oal_status_t mesh_conf_send_key_message(oal_uuid_t *network_uuid,
502 uint16_t dest, bool is_netkey,
503 bool is_update, int key_idx, int netkey_idx)
505 int ret = BT_STATUS_SUCCESS;
507 CHECK_OAL_MESH_ENABLED();
509 ret = mesh_api->key_send((bt_uuid_t*)network_uuid, dest,
510 is_netkey, is_update, key_idx, netkey_idx);
511 if (ret != BT_STATUS_SUCCESS) {
512 BT_ERR("MESH: Key Configuration Message sending failed: %s",
514 return convert_to_oal_status(ret);
517 return OAL_STATUS_SUCCESS;
520 oal_status_t mesh_model_send_message(oal_uuid_t *network_uuid,
521 uint16_t dest, uint16_t appkey_idx,
522 uint8_t *buf, int len)
524 int ret = BT_STATUS_SUCCESS;
526 CHECK_OAL_MESH_ENABLED();
528 ret = mesh_api->msg_execute((bt_uuid_t*)network_uuid,
529 dest, appkey_idx, buf, len);
530 if (ret != BT_STATUS_SUCCESS) {
531 BT_ERR("MESH: Model Message sending failed: %s",
533 return convert_to_oal_status(ret);
536 return OAL_STATUS_SUCCESS;
539 oal_status_t mesh_network_provision_device(oal_uuid_t* network_uuid,
540 oal_uuid_t *dev_uuid)
542 int ret = BT_STATUS_SUCCESS;
544 CHECK_OAL_MESH_ENABLED();
546 ret = mesh_api->provision((bt_uuid_t*)network_uuid, (bt_uuid_t *)dev_uuid);
547 if (ret != BT_STATUS_SUCCESS) {
548 BT_ERR("MESH: Device Provisioning :failed: %s",
550 return convert_to_oal_status(ret);
553 return OAL_STATUS_SUCCESS;
556 oal_status_t mesh_network_send_provisioning_data(oal_uuid_t* network_uuid,
557 uint16_t netkey_idx, uint16_t unicast)
559 int ret = BT_STATUS_SUCCESS;
561 CHECK_OAL_MESH_ENABLED();
563 ret = mesh_api->provision_data((bt_uuid_t*)network_uuid, netkey_idx, unicast);
564 if (ret != BT_STATUS_SUCCESS) {
565 BT_ERR("MESH: Device Provisioning :failed: %s",
567 return convert_to_oal_status(ret);
570 return OAL_STATUS_SUCCESS;
573 oal_status_t mesh_network_subnet_execute(oal_uuid_t* network_uuid,
574 oal_mesh_key_op_e operation, uint16_t net_index)
576 int ret = BT_STATUS_SUCCESS;
578 CHECK_OAL_MESH_ENABLED();
580 ret = mesh_api->subnet_execute((bt_uuid_t*)network_uuid,
581 (bt_mesh_key_op_e)operation, net_index);
582 if (ret != BT_STATUS_SUCCESS) {
583 BT_ERR("MESH: Create Subnet :failed: %s", status2string(ret));
584 return convert_to_oal_status(ret);
587 return OAL_STATUS_SUCCESS;
590 oal_status_t mesh_network_appkey_execute(oal_uuid_t* network_uuid,
591 oal_mesh_key_op_e operation,
592 uint16_t net_index, uint16_t app_index)
594 int ret = BT_STATUS_SUCCESS;
596 CHECK_OAL_MESH_ENABLED();
598 ret = mesh_api->appkey_execute((bt_uuid_t*)network_uuid,
599 (bt_mesh_key_op_e)operation,
600 net_index, app_index);
601 if (ret != BT_STATUS_SUCCESS) {
602 BT_ERR("MESH: Create Subnet :failed: %s",
604 return convert_to_oal_status(ret);
607 return OAL_STATUS_SUCCESS;
610 oal_status_t mesh_authentication_reply(
611 oal_mesh_variant_authentication_e auth_type,
612 const char* auth_value)
614 int ret = BT_STATUS_SUCCESS;
616 CHECK_OAL_MESH_ENABLED();
618 ret = mesh_api->auth_reply((bt_hal_mesh_auth_variant_e)auth_type,
620 if (ret != BT_STATUS_SUCCESS) {
621 BT_ERR("MESH: Device Provisioning :failed: %s",
623 return convert_to_oal_status(ret);
626 return OAL_STATUS_SUCCESS;