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);
70 static void mesh_message_received_callback(bt_uuid_t *net_uuid,
71 uint16_t source_addr, uint16_t dest_addr,
72 uint16_t key_idx, uint16_t data_len, uint8_t *data);
75 static btmesh_callbacks_t sBluetoothMeshCallbacks = {
76 .size = sizeof(sBluetoothMeshCallbacks),
77 .network_attached_cb = mesh_network_attached_callback,
78 .scan_status_cb = mesh_network_scan_status_callback,
79 .scan_result_cb = mesh_network_scan_result_callback,
80 .provisioning_status_cb = mesh_network_provisioning_status_callback,
81 .provisioning_finished_cb = mesh_network_provisioning_finished_callback,
82 .provisioning_data_requested_cb = mesh_network_provisioning_data_requested_callback,
83 .authentication_requested_cb = mesh_network_authentication_requested_callback,
84 .netkey_execute_cb = mesh_network_netkey_execute_callback,
85 .appkey_execute_cb = mesh_network_appkey_execute_callback,
86 .devkey_msg_cb = mesh_devkey_message_received_callback,
87 .msg_cb = mesh_message_received_callback,
90 /* Mesh HAL event handlers */
91 static void mesh_network_attached_callback(bt_status_t status,
92 bt_mesh_token_t *token, bt_uuid_t *uuid)
94 event_mesh_network_attached_t *event = g_new0(event_mesh_network_attached_t, 1);
96 event->status = convert_to_oal_status(status);
97 BT_INFO("Mesh Event: Network Attached, status: [%s]",
98 status2string(status));
100 memcpy(event->token, token->token, sizeof(bt_mesh_token_t));
101 memcpy(event->uuid.uuid, uuid->uu, sizeof(bt_uuid_t));
103 send_event_bda_trace(OAL_EVENT_MESH_NETWORK_ATTACHED,
104 event, sizeof(event_mesh_network_attached_t), NULL);
107 static void mesh_network_scan_status_callback(bt_mesh_scan_state_t scan_state,
108 bt_status_t status, bt_uuid_t *net_uuid)
110 event_mesh_scan_status_t *event_data = g_new0(event_mesh_scan_status_t, 1);
113 event_data->status = convert_to_oal_status(status);
114 BT_INFO("Mesh Event: Scan status: [%s] state [%d]",
115 status2string(status), scan_state);
117 memcpy(event_data->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
119 event = (BT_MESH_SCAN_STARTED == scan_state) ? \
120 OAL_EVENT_MESH_SCAN_STARTED : OAL_EVENT_MESH_SCAN_FINISHED;
121 send_event_bda_trace(event, event_data,
122 sizeof(event_mesh_scan_status_t), NULL);
125 static void mesh_network_provisioning_status_callback(bt_status_t status,
126 bt_uuid_t *net_uuid, bt_uuid_t *dev_uuid)
128 event_mesh_provisioning_status_t *event = g_new0(event_mesh_provisioning_status_t, 1);
130 event->status = convert_to_oal_status(status);
131 BT_INFO("Mesh Event: Provisioning status: [%s]",
132 status2string(status));
134 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
135 memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
137 if (event->status == OAL_STATUS_SUCCESS)
138 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_STARTED,
139 event, sizeof(event_mesh_provisioning_status_t), NULL);
141 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FAILED,
142 event, sizeof(event_mesh_provisioning_status_t), NULL);
145 static void mesh_network_provisioning_finished_callback(bt_status_t status,
146 int reason, bt_uuid_t *net_uuid,
147 bt_uuid_t *dev_uuid, uint16_t unicast, uint8_t count)
149 event_mesh_provisioning_finished_t *event = \
150 g_new0(event_mesh_provisioning_finished_t, 1);
152 event->status = convert_to_oal_status(status);
153 event->reason = reason;
154 BT_INFO("Mesh Event: Provisioning Completed Result: [%s]",
155 status2string(status));
157 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
158 memcpy(event->dev_uuid.uuid, dev_uuid->uu, sizeof(bt_uuid_t));
159 event->unicast = unicast;
160 event->count = count;
162 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_FINISHED,
163 event, sizeof(event_mesh_provisioning_finished_t), NULL);
166 static void mesh_network_provisioning_data_requested_callback(
167 bt_uuid_t *net_uuid, uint8_t count)
169 event_mesh_provisioning_data_requested_t *event = \
170 g_new0(event_mesh_provisioning_data_requested_t, 1);
172 BT_INFO("Mesh Event: Provisioning Data requested");
174 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
175 event->count = count;
177 send_event_bda_trace(OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED,
178 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
181 static void mesh_network_authentication_requested_callback(bt_uuid_t *net_uuid,
182 bt_hal_mesh_auth_variant_e auth_type,
185 event_mesh_authentication_requested_t *event = \
186 g_new0(event_mesh_authentication_requested_t, 1);
188 BT_INFO("Mesh Event: Authentication requested");
190 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
191 event->auth_type = auth_type;
192 g_strlcpy(event->auth_value, auth_value, sizeof(event->auth_value));
194 send_event_bda_trace(OAL_EVENT_MESH_AUTHENTICATION_REQUESTED,
195 event, sizeof(event_mesh_provisioning_data_requested_t), NULL);
198 static void mesh_network_netkey_execute_callback(bt_status_t status,
199 bt_uuid_t *net_uuid, uint8_t key_event, uint16_t index)
201 event_mesh_netkey_operation_t *event = \
202 g_new0(event_mesh_netkey_operation_t, 1);
204 event->status = convert_to_oal_status(status);
205 BT_INFO("Mesh Event: NetKey Execute Event");
207 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
208 event->op = (oal_mesh_key_op_e)key_event;
209 event->key_idx = index;
211 send_event_bda_trace(OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT,
212 event, sizeof(event_mesh_netkey_operation_t), NULL);
215 static void mesh_network_appkey_execute_callback(bt_status_t status,
216 bt_uuid_t *net_uuid, uint8_t key_event,
217 uint16_t net_idx, uint16_t app_idx)
219 event_mesh_appkey_operation_t *event = \
220 g_new0(event_mesh_appkey_operation_t, 1);
222 event->status = convert_to_oal_status(status);
223 BT_INFO("Mesh Event: AppKey Execute Event");
225 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
226 event->op = (oal_mesh_key_op_e)key_event;
227 event->net_idx = net_idx;
228 event->app_idx = app_idx;
230 send_event_bda_trace(OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT,
231 event, sizeof(event_mesh_appkey_operation_t), NULL);
234 static void mesh_network_scan_result_callback(bt_status_t status,
235 bt_uuid_t *net_uuid, bt_mesh_scan_result_t *result)
237 event_mesh_scan_result_t *event = g_new0(event_mesh_scan_result_t, 1);
239 event->status = convert_to_oal_status(status);
240 BT_INFO("Mesh Event: Scan Result status: [%s]",
241 status2string(status));
243 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
244 memcpy(&event->result, result, sizeof(bt_mesh_scan_result_t));
246 send_event_bda_trace(OAL_EVENT_MESH_SCAN_RESULT,
247 event, sizeof(event_mesh_scan_result_t), NULL);
250 static void mesh_devkey_message_received_callback(bt_uuid_t *net_uuid,
251 uint16_t source_addr,
252 bool is_remote_devkey, uint16_t netkey_idx,
253 uint16_t data_len, uint8_t *data)
255 event_mesh_devkey_message_t *event = g_new0(event_mesh_devkey_message_t, 1);
257 BT_INFO("Mesh Event: Dev Key Message Received");
258 event->source = source_addr;
259 event->remote = is_remote_devkey;
260 event->subnet = netkey_idx;
261 event->data_len = data_len;
262 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
263 memcpy(event->data, data, data_len);
265 send_event_bda_trace(OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED, event,
266 sizeof(event_mesh_devkey_message_t), NULL);
269 static void mesh_message_received_callback(bt_uuid_t *net_uuid,
270 uint16_t source_addr, uint16_t dest_addr, uint16_t key_idx,
271 uint16_t data_len, uint8_t *data)
273 event_mesh_message_t *event = g_new0(event_mesh_message_t, 1);
275 BT_INFO("Mesh Event: Model Message Received");
276 event->source = source_addr;
277 event->dest = dest_addr;
278 event->key_idx = key_idx;
279 event->data_len = data_len;
280 memcpy(event->net_uuid.uuid, net_uuid->uu, sizeof(bt_uuid_t));
281 memcpy(event->data, data, data_len);
283 send_event_bda_trace(OAL_EVENT_MESH_MESSAGE_RECEIVED, event,
284 sizeof(event_mesh_message_t), NULL);
287 oal_status_t mesh_enable(void)
292 /* Get stack interface */
293 blued_api = (const bt_interface_t *) adapter_get_stack_interface();
295 if (blued_api == NULL) {
296 BT_ERR("Stack is not initialized");
297 return OAL_STATUS_NOT_READY;
301 BT_WARN("MESH Interface is already initialized...");
302 return OAL_STATUS_ALREADY_DONE;
305 mesh_api = (const btmesh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_MESH_ID);
306 if (mesh_api == NULL) {
307 BT_ERR("MESH interface failed");
308 return OAL_STATUS_INTERNAL_ERROR;
311 if ((ret = mesh_api->init(&sBluetoothMeshCallbacks)) != BT_STATUS_SUCCESS) {
312 BT_ERR("Error: Unable to initialise MESH :%s", status2string(ret));
315 return convert_to_oal_status(ret);
318 BT_INFO("MESH successfully initialized");
319 return OAL_STATUS_SUCCESS;
322 oal_status_t mesh_disable(void)
325 CHECK_OAL_MESH_ENABLED();
330 return OAL_STATUS_SUCCESS;
333 oal_status_t mesh_register_node(oal_mesh_node_t *node,
334 GSList *model_list, bool is_provisioner)
336 int ret = BT_STATUS_SUCCESS;
338 CHECK_OAL_MESH_ENABLED();
340 BT_INFO("Mesh: Send create network request to stack");
341 ret = mesh_api->create((bt_hal_mesh_node_t*)node, model_list, is_provisioner);
342 if (ret != BT_STATUS_SUCCESS) {
343 BT_ERR("MESH: Create Network failed :failed: %s", status2string(ret));
344 return convert_to_oal_status(ret);
347 BT_INFO("Mesh: Request sent to stack");
348 return OAL_STATUS_SUCCESS;
351 oal_status_t mesh_network_start_scan(oal_uuid_t* network_uuid,
352 oal_mesh_scan_params_t *params)
354 int ret = BT_STATUS_SUCCESS;
356 CHECK_OAL_MESH_ENABLED();
358 ret = mesh_api->scan((bt_uuid_t*)network_uuid,
359 (bt_hal_mesh_scan_param_t*)params);
360 if (ret != BT_STATUS_SUCCESS) {
361 BT_ERR("MESH: Start Scan failed: %s", status2string(ret));
362 return convert_to_oal_status(ret);
365 return OAL_STATUS_SUCCESS;
368 oal_status_t mesh_network_scan_cancel(oal_uuid_t* network_uuid)
370 int ret = BT_STATUS_SUCCESS;
372 CHECK_OAL_MESH_ENABLED();
374 ret = mesh_api->scan_cancel((bt_uuid_t*)network_uuid);
375 if (ret != BT_STATUS_SUCCESS) {
376 BT_ERR("MESH: Scan Cancel failed: %s", status2string(ret));
377 return convert_to_oal_status(ret);
380 return OAL_STATUS_SUCCESS;
383 oal_status_t mesh_network_set_provisioning_capabilities(
384 oal_uuid_t *network_uuid,
385 oal_mesh_capabilities_t *caps)
387 int ret = BT_STATUS_SUCCESS;
389 CHECK_OAL_MESH_ENABLED();
391 ret = mesh_api->capability((bt_uuid_t*)network_uuid,
392 (bt_hal_mesh_prov_caps_t*)caps);
393 if (ret != BT_STATUS_SUCCESS) {
394 BT_ERR("MESH: Set Provisioning capabilities :failed: %s",
396 return convert_to_oal_status(ret);
399 return OAL_STATUS_SUCCESS;
402 oal_status_t mesh_conf_send_message(oal_uuid_t *network_uuid,
403 uint16_t dest, bool is_devkey_remote,
404 uint16_t netkey_idx, uint8_t *buf, int len)
406 int ret = BT_STATUS_SUCCESS;
408 CHECK_OAL_MESH_ENABLED();
410 ret = mesh_api->config_send((bt_uuid_t*)network_uuid,
411 dest, is_devkey_remote, netkey_idx, buf, len);
412 if (ret != BT_STATUS_SUCCESS) {
413 BT_ERR("MESH: Configuration Message sending failed: %s",
415 return convert_to_oal_status(ret);
418 return OAL_STATUS_SUCCESS;
421 oal_status_t mesh_conf_send_key_message(oal_uuid_t *network_uuid,
422 uint16_t dest, bool is_netkey,
423 bool is_update, int key_idx, int netkey_idx)
425 int ret = BT_STATUS_SUCCESS;
427 CHECK_OAL_MESH_ENABLED();
429 ret = mesh_api->key_send((bt_uuid_t*)network_uuid, dest,
430 is_netkey, is_update, key_idx, netkey_idx);
431 if (ret != BT_STATUS_SUCCESS) {
432 BT_ERR("MESH: Key Configuration Message sending failed: %s",
434 return convert_to_oal_status(ret);
437 return OAL_STATUS_SUCCESS;
440 oal_status_t mesh_model_send_message(oal_uuid_t *network_uuid,
441 uint16_t dest, uint16_t appkey_idx,
442 uint8_t *buf, int len)
444 int ret = BT_STATUS_SUCCESS;
446 CHECK_OAL_MESH_ENABLED();
448 ret = mesh_api->msg_execute((bt_uuid_t*)network_uuid,
449 dest, appkey_idx, buf, len);
450 if (ret != BT_STATUS_SUCCESS) {
451 BT_ERR("MESH: Key Configuration Message sending failed: %s",
453 return convert_to_oal_status(ret);
456 return OAL_STATUS_SUCCESS;
459 oal_status_t mesh_network_provision_device(oal_uuid_t* network_uuid,
460 oal_uuid_t *dev_uuid)
462 int ret = BT_STATUS_SUCCESS;
464 CHECK_OAL_MESH_ENABLED();
466 ret = mesh_api->provision((bt_uuid_t*)network_uuid, (bt_uuid_t *)dev_uuid);
467 if (ret != BT_STATUS_SUCCESS) {
468 BT_ERR("MESH: Device Provisioning :failed: %s",
470 return convert_to_oal_status(ret);
473 return OAL_STATUS_SUCCESS;
476 oal_status_t mesh_network_send_provisioning_data(oal_uuid_t* network_uuid,
477 uint16_t netkey_idx, uint16_t unicast)
479 int ret = BT_STATUS_SUCCESS;
481 CHECK_OAL_MESH_ENABLED();
483 ret = mesh_api->provision_data((bt_uuid_t*)network_uuid, netkey_idx, unicast);
484 if (ret != BT_STATUS_SUCCESS) {
485 BT_ERR("MESH: Device Provisioning :failed: %s",
487 return convert_to_oal_status(ret);
490 return OAL_STATUS_SUCCESS;
493 oal_status_t mesh_network_subnet_execute(oal_uuid_t* network_uuid,
494 oal_mesh_key_op_e operation, uint16_t net_index)
496 int ret = BT_STATUS_SUCCESS;
498 CHECK_OAL_MESH_ENABLED();
500 ret = mesh_api->subnet_execute((bt_uuid_t*)network_uuid,
501 (bt_mesh_key_op_e)operation, net_index);
502 if (ret != BT_STATUS_SUCCESS) {
503 BT_ERR("MESH: Create Subnet :failed: %s", status2string(ret));
504 return convert_to_oal_status(ret);
507 return OAL_STATUS_SUCCESS;
510 oal_status_t mesh_network_appkey_execute(oal_uuid_t* network_uuid,
511 oal_mesh_key_op_e operation,
512 uint16_t net_index, uint16_t app_index)
514 int ret = BT_STATUS_SUCCESS;
516 CHECK_OAL_MESH_ENABLED();
518 ret = mesh_api->appkey_execute((bt_uuid_t*)network_uuid,
519 (bt_mesh_key_op_e)operation,
520 net_index, app_index);
521 if (ret != BT_STATUS_SUCCESS) {
522 BT_ERR("MESH: Create Subnet :failed: %s",
524 return convert_to_oal_status(ret);
527 return OAL_STATUS_SUCCESS;
530 oal_status_t mesh_authentication_reply(
531 oal_mesh_variant_authentication_e auth_type,
532 const char* auth_value)
534 int ret = BT_STATUS_SUCCESS;
536 CHECK_OAL_MESH_ENABLED();
538 ret = mesh_api->auth_reply((bt_hal_mesh_auth_variant_e)auth_type,
540 if (ret != BT_STATUS_SUCCESS) {
541 BT_ERR("MESH: Device Provisioning :failed: %s",
543 return convert_to_oal_status(ret);
546 return OAL_STATUS_SUCCESS;