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.
33 #include "bluetooth-api.h"
34 #include "bt-internal-types.h"
35 #include "bt-service-common.h"
36 #include "bt-service-event.h"
37 #include "bt-service-event-receiver.h"
38 #include "bt-service-util.h"
40 #include "bt-service-mesh-util.h"
41 #include "bt-service-mesh-network.h"
42 #include "bt-service-mesh-nodes.h"
43 //#include "bt-service-mesh-config-client.h"
48 static void __bt_mesh_handle_pending_request_info(int result,
49 int service_function, void *param,
54 invocation_info_t *req_info = NULL;
56 for (l = _bt_get_invocation_list(); l != NULL; ) {
59 if (req_info == NULL ||
60 req_info->service_function != service_function)
63 switch (service_function) {
64 case BT_MESH_NETWORK_CREATE: {
65 char uuid_str[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
66 bluetooth_mesh_node_t *node;
67 bluetooth_mesh_network_t *network;
68 ret_if(param == NULL);
69 BT_INFO("Mesh: Request: BT_MESH_NETWORK_CREATE Sender: [%s] result[%d]",
70 req_info->sender, result);
72 node = (bluetooth_mesh_node_t*) param;
73 network = (bluetooth_mesh_network_t*)req_info->user_data;
75 _bt_mesh_util_convert_hex_to_string(
76 (uint8_t *) node->uuid, 16, uuid_str,
77 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
79 BT_INFO("Mesh: Network UUID from event [%s] Netw UUID from req [%s]",
80 uuid_str, network->uuid);
82 if (!g_strcmp0(network->uuid, uuid_str)) {
83 BT_INFO("Mesh: BT_MESH_NETWORK_CREATE Request found uuid [%s]",
85 if (BLUETOOTH_ERROR_NONE != _bt_mesh_network_create_cdb(
86 result, req_info->sender,
87 network->app_cred, node->uuid,
88 node->token.u8, network->name.name)) {
89 result = BLUETOOTH_ERROR_INTERNAL;
90 BT_ERR("!!Mesh: BT_MESH_NETWORK_CREATE Failed!!");
93 _bt_mesh_util_convert_hex_to_string(
94 (uint8_t *) node->token.u8, 8,
96 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
98 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
99 g_array_append_vals(out_param, network,
100 sizeof(bluetooth_mesh_network_t));
101 _bt_service_method_return(req_info->context,
103 _bt_free_info_from_invocation_list(req_info);
104 g_free(req_info->user_data);
105 g_array_free(out_param, TRUE);
109 case BT_MESH_NETWORK_LOAD: {
110 char token_str[BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1];
111 bluetooth_mesh_node_t *node;
112 bluetooth_mesh_network_t *network;
113 ret_if(param == NULL);
114 BT_INFO("Mesh: Request: BT_MESH_NETWORK_LOAD Sender: [%s]",
117 node = (bluetooth_mesh_node_t*) param;
118 network = (bluetooth_mesh_network_t*)req_info->user_data;
120 _bt_mesh_util_convert_hex_to_string(
121 (uint8_t *) node->token.u8, 8, token_str,
122 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
124 if (!g_strcmp0(network->token.token, token_str)) {
126 BT_INFO("Mesh: BT_MESH_NETWORK_LOAD Request found Token [%s]",
129 /* TODO: Handle Meh Network Load CDB */
130 /* Send request to mesh-network to load keys and Nodes for the network */
134 case BT_MESH_NETWORK_SCAN: {
135 bluetooth_mesh_network_t *network;
136 event_mesh_scan_status_t *event;
137 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
139 event = (event_mesh_scan_status_t*) param;
140 network = (bluetooth_mesh_network_t*)req_info->user_data;
141 _bt_mesh_util_convert_hex_to_string(
142 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
143 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
145 BT_DBG("Request Sender: [%s]", req_info->sender);
146 if (!g_strcmp0(network->uuid, net_uuid)) {
147 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
148 g_array_append_vals(out_param,
149 network, sizeof(bluetooth_mesh_network_t));
150 _bt_service_method_return(req_info->context,
152 _bt_free_info_from_invocation_list(req_info);
153 g_free(req_info->user_data);
154 g_array_free(out_param, TRUE);
158 case BT_MESH_NETWORK_PROVISION_DEVICE: {
159 bluetooth_mesh_provisioning_request_t *req_data;
160 bluetooth_mesh_provisioning_request_t status_data;
161 event_mesh_provisioning_status_t *event;
163 0x00, sizeof(bluetooth_mesh_provisioning_request_t));
165 event = (event_mesh_provisioning_status_t*) param;
166 req_data = (bluetooth_mesh_provisioning_request_t*) req_info->user_data;
168 _bt_mesh_util_convert_hex_to_string(
169 (uint8_t *) event->net_uuid.uuid, 16, status_data.net_uuid,
170 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
172 _bt_mesh_util_convert_hex_to_string(
173 (uint8_t *) event->dev_uuid.uuid, 16, status_data.dev_uuid,
174 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
176 BT_DBG("Request Sender: [%s]", req_info->sender);
177 if (!g_strcmp0(req_data->net_uuid, status_data.net_uuid)) {
178 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
179 g_array_append_vals(out_param, &status_data,
180 sizeof(bluetooth_mesh_provisioning_request_t));
181 _bt_service_method_return(req_info->context, out_param, result);
182 _bt_free_info_from_invocation_list(req_info);
183 g_free(req_info->user_data);
184 g_array_free(out_param, TRUE);
189 case BT_MESH_NETWORK_DELETE_NETKEY:
190 case BT_MESH_NETWORK_UPDATE_NETKEY:
191 case BT_MESH_NETWORK_ADD_NETKEY: {
192 bluetooth_mesh_network_t *network;
193 event_mesh_netkey_operation_t *event;
194 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
196 event = (event_mesh_netkey_operation_t*) param;
197 network = (bluetooth_mesh_network_t*)req_info->user_data;
198 _bt_mesh_util_convert_hex_to_string(
199 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
200 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
202 BT_DBG("Request Sender: [%s]", req_info->sender);
203 if (!g_strcmp0(network->uuid, net_uuid)) {
204 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
205 g_array_append_vals(out_param, &event->key_idx, sizeof(guint16));
206 _bt_service_method_return(req_info->context, out_param, result);
207 _bt_free_info_from_invocation_list(req_info);
208 g_free(req_info->user_data);
209 g_array_free(out_param, TRUE);
214 case BT_MESH_NETWORK_DELETE_APPKEY:
215 case BT_MESH_NETWORK_UPDATE_APPKEY:
216 case BT_MESH_NETWORK_ADD_APPKEY: {
217 bluetooth_mesh_network_t *network;
218 event_mesh_appkey_operation_t *event;
219 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
221 event = (event_mesh_appkey_operation_t*) param;
222 network = (bluetooth_mesh_network_t*)req_info->user_data;
223 _bt_mesh_util_convert_hex_to_string(
224 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
225 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
227 BT_DBG("Request Sender: [%s]", req_info->sender);
228 if (!g_strcmp0(network->uuid, net_uuid)) {
229 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
230 g_array_append_vals(out_param,
231 &event->app_idx, sizeof(guint16));
232 _bt_service_method_return(req_info->context, out_param, result);
233 _bt_free_info_from_invocation_list(req_info);
234 g_free(req_info->user_data);
235 g_array_free(out_param, TRUE);
240 BT_DBG("Unknown function(%d)", service_function);
246 static void __handle_mesh_devkey_message_received_event(
247 event_mesh_devkey_message_t *event)
249 /* TODO Handle Devkey message Handler */
252 static void __handle_mesh_network_attached_event(
253 event_mesh_network_attached_t *event)
255 int result = BLUETOOTH_ERROR_NONE;
256 bluetooth_mesh_node_t node;
258 if (event->status != OAL_STATUS_SUCCESS)
259 result = BLUETOOTH_ERROR_INTERNAL;
261 memset(&node, 0x00, sizeof(bluetooth_mesh_node_t));
263 memcpy(node.uuid, event->uuid.uuid, 16);
264 memcpy(node.token.u8, event->token, 8);
266 __bt_mesh_handle_pending_request_info(result,
267 BT_MESH_NETWORK_CREATE,
268 &node, sizeof(bluetooth_mesh_node_t));
269 __bt_mesh_handle_pending_request_info(result,
270 BT_MESH_NETWORK_LOAD,
271 &node, sizeof(bluetooth_mesh_node_t));
274 static void __handle_mesh_network_scan_started_event(
275 event_mesh_scan_status_t *event)
277 GVariant *out_var = NULL, *param = NULL;
279 bluetooth_mesh_network_t network;
281 int result = BLUETOOTH_ERROR_NONE;
282 if (event->status != OAL_STATUS_SUCCESS) {
283 result = BLUETOOTH_ERROR_INTERNAL;
284 _bt_mesh_set_scanning_state(false);
286 _bt_mesh_set_scanning_state(true);
288 /* Handle DBUS Context return */
289 __bt_mesh_handle_pending_request_info(result,
290 BT_MESH_NETWORK_SCAN,
291 event, sizeof(event_mesh_scan_status_t));
293 /* Handle Scan started event */
294 if (result == BLUETOOTH_ERROR_NONE) {
295 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
296 _bt_mesh_util_convert_hex_to_string(
297 (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
298 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
300 info = g_array_new(FALSE, FALSE, sizeof(gchar));
301 g_array_append_vals(info, &network,
302 sizeof(bluetooth_mesh_network_t));
304 out_var = g_variant_new_from_data((const GVariantType *)"ay",
305 info->data, info->len,
308 param = g_variant_new("(iv)", result, out_var);
309 _bt_send_event(BT_MESH_EVENT,
310 BLUETOOTH_EVENT_MESH_SCAN_STARTED,
315 static void __handle_mesh_network_scan_finished_event(
316 event_mesh_scan_status_t *event)
318 GVariant *out_var = NULL, *param = NULL;
320 bluetooth_mesh_network_t network;
322 int result = BLUETOOTH_ERROR_NONE;
323 if (event->status != OAL_STATUS_SUCCESS)
324 result = BLUETOOTH_ERROR_INTERNAL;
327 /* Handle Scan finsihed event */
328 if (result == BLUETOOTH_ERROR_NONE) {
329 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
330 _bt_mesh_util_convert_hex_to_string(
331 (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
332 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
334 info = g_array_new(FALSE, FALSE, sizeof(gchar));
335 g_array_append_vals(info, &network,
336 sizeof(bluetooth_mesh_network_t));
338 out_var = g_variant_new_from_data((const GVariantType *)"ay",
339 info->data, info->len,
342 param = g_variant_new("(iv)", result, out_var);
343 _bt_send_event(BT_MESH_EVENT,
344 BLUETOOTH_EVENT_MESH_SCAN_FINISHED,
346 _bt_mesh_set_scanning_state(false);
350 static void __handle_mesh_network_provisioning_started_event(
351 event_mesh_provisioning_status_t *status)
353 int result = BLUETOOTH_ERROR_NONE;
355 __bt_mesh_handle_pending_request_info(result,
356 BT_MESH_NETWORK_PROVISION_DEVICE,
357 status, sizeof(event_mesh_scan_status_t));
359 _bt_mesh_set_provisioning_state(true);
362 static void __handle_mesh_network_provisioning_failed_event(
363 event_mesh_provisioning_status_t *status)
365 int result = BLUETOOTH_ERROR_INTERNAL;
367 __bt_mesh_handle_pending_request_info(result,
368 BT_MESH_NETWORK_PROVISION_DEVICE,
369 status, sizeof(event_mesh_scan_status_t));
371 _bt_mesh_set_provisioning_state(false);
374 static void __handle_mesh_network_provisioning_finished_event(
375 event_mesh_provisioning_finished_t *event)
377 GVariant *out_var = NULL, *param = NULL;
379 bluetooth_mesh_provisioning_result_t prov_result;
381 memset(&prov_result, 0x00,
382 sizeof(bluetooth_mesh_provisioning_result_t));
384 if (event->status != OAL_STATUS_SUCCESS)
385 prov_result.result = BLUETOOTH_ERROR_INTERNAL;
386 prov_result.result = BLUETOOTH_ERROR_NONE;
388 prov_result.reason = event->reason;
389 prov_result.unicast = event->unicast;
390 prov_result.count = event->count;
392 _bt_mesh_util_convert_hex_to_string(
393 (uint8_t *) event->net_uuid.uuid, 16, prov_result.net_uuid,
394 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
396 _bt_mesh_util_convert_hex_to_string(
397 (uint8_t *) event->dev_uuid.uuid, 16, prov_result.dev_uuid,
398 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
400 info = g_array_new(FALSE, FALSE, sizeof(gchar));
401 g_array_append_vals(info, &prov_result,
402 sizeof(bluetooth_mesh_provisioning_result_t));
404 out_var = g_variant_new_from_data((const GVariantType *)"ay",
405 info->data, info->len,
408 param = g_variant_new("(iv)", prov_result.result, out_var);
409 _bt_send_event(BT_MESH_EVENT,
410 BLUETOOTH_EVENT_MESH_PROVISIONING_FINISHED,
413 /* TODO Add newly provisioned Node info in Node Manager */
414 /* Add Remote Node entry in Local CDB */
417 static void __handle_mesh_network_provisioning_data_requested_event(
418 event_mesh_provisioning_data_requested_t *event)
420 _bt_mesh_network_request_provisioning_data_request(
421 event->net_uuid.uuid, event->count);
424 static void __handle_mesh_network_authentication_requested_event(
425 event_mesh_authentication_requested_t *event)
427 GVariant *out_var = NULL, *param = NULL;
429 bluetooth_mesh_authentication_request_t auth_req;
431 memset(&auth_req, 0x00,
432 sizeof(bluetooth_mesh_authentication_request_t));
434 auth_req.auth_type = event->auth_type;
435 g_strlcpy(auth_req.auth_value, event->auth_value,
436 sizeof(auth_req.auth_value));
438 _bt_mesh_util_convert_hex_to_string(
439 (uint8_t *) event->net_uuid.uuid, 16, auth_req.net_uuid,
440 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
442 info = g_array_new(FALSE, FALSE, sizeof(gchar));
443 g_array_append_vals(info, &auth_req,
444 sizeof(bluetooth_mesh_authentication_request_t));
446 out_var = g_variant_new_from_data((const GVariantType *)"ay",
447 info->data, info->len,
450 param = g_variant_new("(iv)", BLUETOOTH_ERROR_NONE, out_var);
451 _bt_send_event(BT_MESH_EVENT,
452 BLUETOOTH_EVENT_MESH_AUTHENTICATION_REQUEST,
456 static void __handle_mesh_network_scan_result_event(
457 event_mesh_scan_result_t *event)
459 GVariant *out_var = NULL, *param = NULL;
461 bluetooth_mesh_scan_result_t data;
462 int result = BLUETOOTH_ERROR_NONE;
464 memset(&data, 0x00, sizeof(bluetooth_mesh_scan_result_t));
466 /* Fill Network UUID */
467 _bt_mesh_util_convert_hex_to_string(
468 (uint8_t *) event->net_uuid.uuid, 16, data.net_uuid,
469 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
471 /* Fill Device UUID */
472 _bt_mesh_util_convert_hex_to_string(
473 (uint8_t *) event->result.dev_uuid.uuid, 16, data.dev_uuid,
474 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
477 data.rssi = event->result.rssi;
480 memcpy(&data.oob_info, event->result.oob_info, 2);
482 /* Fill URI Hash Info */
483 memcpy(&data.uri_hash, event->result.uri_hash, 4);
485 if (event->status != OAL_STATUS_SUCCESS)
486 result = BLUETOOTH_ERROR_INTERNAL;
489 info = g_array_new(FALSE, FALSE, sizeof(gchar));
490 g_array_append_vals(info, &data,
491 sizeof(bluetooth_mesh_scan_result_t));
493 out_var = g_variant_new_from_data((const GVariantType *)"ay",
494 info->data, info->len,
497 param = g_variant_new("(iv)", result, out_var);
498 _bt_send_event(BT_MESH_EVENT,
499 BLUETOOTH_EVENT_MESH_SCAN_RESULT,
503 static void __handle_mesh_events(int event_type,
506 switch (event_type) {
507 case OAL_EVENT_MESH_NETWORK_ATTACHED:
508 __handle_mesh_network_attached_event(
509 (event_mesh_network_attached_t*)event_data);
510 BT_PERMANENT_LOG("Mesh: Network attached!!");
512 case OAL_EVENT_MESH_SCAN_STARTED:
513 __handle_mesh_network_scan_started_event(
514 (event_mesh_scan_status_t*)event_data);
515 BT_PERMANENT_LOG("Mesh: Network Scan Stated!!");
517 case OAL_EVENT_MESH_SCAN_FINISHED:
518 __handle_mesh_network_scan_finished_event(
519 (event_mesh_scan_status_t*)event_data);
520 BT_PERMANENT_LOG("Mesh: Network Scan Finished!!");
522 case OAL_EVENT_MESH_SCAN_RESULT:
523 __handle_mesh_network_scan_result_event(
524 (event_mesh_scan_result_t*)event_data);
525 BT_PERMANENT_LOG("Mesh: Network Scan Result!!");
527 case OAL_EVENT_MESH_PROVISIONING_STARTED:
528 __handle_mesh_network_provisioning_started_event(
529 (event_mesh_provisioning_status_t*)event_data);
530 BT_PERMANENT_LOG("Mesh: Network Provisioning Started");
532 case OAL_EVENT_MESH_PROVISIONING_FAILED:
533 __handle_mesh_network_provisioning_failed_event(
534 (event_mesh_provisioning_status_t*)event_data);
535 BT_PERMANENT_LOG("Mesh: Network Provisioning Failed");
537 case OAL_EVENT_MESH_PROVISIONING_FINISHED:
538 __handle_mesh_network_provisioning_finished_event(
539 (event_mesh_provisioning_finished_t*)event_data);
540 BT_PERMANENT_LOG("Mesh: Network Provisioning Finished");
542 case OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED:
543 __handle_mesh_network_provisioning_data_requested_event(
544 (event_mesh_provisioning_data_requested_t*)event_data);
545 BT_PERMANENT_LOG("Mesh: Network Provisioning Data Requested");
547 case OAL_EVENT_MESH_AUTHENTICATION_REQUESTED:
548 __handle_mesh_network_authentication_requested_event(
549 (event_mesh_authentication_requested_t*)event_data);
550 BT_PERMANENT_LOG("Mesh: Network Authentication Requested");
552 case OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT:
553 /* TODO: Handle Netkey key DBUS Handler & event */
554 BT_PERMANENT_LOG("Mesh: Network Subnet operation event");
556 case OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT:
557 /* TODO: Handle Netkey key DBUS Handler & event */
558 BT_PERMANENT_LOG("Mesh: AppKey operation event");
560 case OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED:
561 __handle_mesh_devkey_message_received_event(
562 (event_mesh_devkey_message_t*)event_data);
563 BT_PERMANENT_LOG("Mesh: DevKey Message Received event");
570 int _bt_mesh_init(void)
572 oal_status_t status = OAL_STATUS_SUCCESS;
574 status = mesh_enable();
575 if (OAL_STATUS_SUCCESS != status) {
576 BT_ERR("Mesh: Failed to initialize Mesh profile, status: %d",
578 return BLUETOOTH_ERROR_INTERNAL;
580 BT_INFO("Mesh: Stack Initialization Done successfully");
582 /* Register MESH event handler */
583 _bt_service_register_event_handler_callback(BT_MESH_MODULE,
584 __handle_mesh_events);
586 return BLUETOOTH_ERROR_NONE;
589 int _bt_mesh_deinit(void)
591 oal_status_t status = OAL_STATUS_SUCCESS;
593 status = mesh_disable();
594 if (OAL_STATUS_SUCCESS != status) {
595 BT_ERR("Mesh: Failed to de-initialize Mesh profile, status: %d",
597 return BLUETOOTH_ERROR_INTERNAL;
600 /* Register AVRCP target event handler */
601 _bt_service_unregister_event_handler_callback(BT_MESH_MODULE);
603 return BLUETOOTH_ERROR_NONE;