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.
32 #include <actd/unit_control.h>
34 #include "bluetooth-api.h"
35 #include "bt-internal-types.h"
36 #include "bt-service-common.h"
37 #include "bt-service-event.h"
38 #include "bt-service-event-receiver.h"
39 #include "bt-service-util.h"
41 #include "bt-service-mesh-util.h"
42 #include "bt-service-mesh-network.h"
43 #include "bt-service-mesh-nodes.h"
44 #include "bt-service-mesh-config-client.h"
45 #include "bt-service-mesh-model.h"
46 #include "bt-service-mesh-common.h"
50 #define MESH_SYSTEMD_SERVICE_NAME "bluetooth-mesh.service"
51 #define MESH_LAUNCH_DELAY 500
53 static guint launch_timer = 0;
54 static guint mesh_app_ref_count;
55 struct l_timeout *wait_timer;
59 static int __bt_meshd_launch()
61 int ret = UNIT_CONTROL_OK;
62 BT_INFO("Mesh: Launch Meshd");
63 ret = actd_start_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
64 MESH_SYSTEMD_SERVICE_NAME, 5000);
66 if (ret != UNIT_CONTROL_OK) {
67 BT_ERR("Failed to call systemact service: %d", ret);
68 return BLUETOOTH_ERROR_INTERNAL;
70 BT_INFO("Mesh: Launch Meshd successful");
72 return BLUETOOTH_ERROR_NONE;
75 static void __bt_meshd_terminate()
77 int ret = UNIT_CONTROL_OK;
78 BT_INFO("Mesh: Stop Meshd");
80 ret = actd_stop_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
81 MESH_SYSTEMD_SERVICE_NAME, 5000);
82 if (ret != UNIT_CONTROL_OK) {
83 BT_ERR("Failed to call systemact service: %d", ret);
87 BT_INFO("Mesh: Meshd stop successful");
90 static void __bt_mesh_terminate()
92 oal_status_t status = OAL_STATUS_SUCCESS;
94 /* Terminate bluetooth-meshd */
95 __bt_meshd_terminate();
98 _bt_mesh_set_scanning_state(false);
99 _bt_mesh_set_provisioning_state(false);
101 status = mesh_disable();
102 if (OAL_STATUS_SUCCESS != status) {
103 BT_ERR("Mesh: Failed to de-initialize Mesh profile, status: %d",
108 /* Un-Register Mesh event handler */
109 _bt_service_unregister_event_handler_callback(BT_MESH_MODULE);
112 bool _bt_is_mesh_initialized()
114 return (mesh_app_ref_count ? true : false);
118 static void __bt_mesh_handle_pending_request_info(int result,
119 int service_function, void *param,
124 invocation_info_t *req_info = NULL;
126 for (l = _bt_get_invocation_list(); l != NULL; ) {
129 if (req_info == NULL ||
130 req_info->service_function != service_function)
133 switch (service_function) {
135 BT_INFO("Mesh: Request: BT_MESH_INIT Sender: [%s] result[%d]",
136 req_info->sender, result);
138 if (result == BLUETOOTH_ERROR_NONE) {
140 /* Save Mesh App Owner */
141 char *owner = g_strdup(req_info->sender);
142 BT_INFO("Mesh: Insert Sender Mesh App List[%s]",
144 apps = g_slist_append(apps, owner);
146 /* Increase mesh app ref count */
147 mesh_app_ref_count++;
148 l_timeout_remove(wait_timer);
150 /* Init failed - Terminate bluetooth-mesh */
151 __bt_mesh_terminate();
154 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
155 _bt_service_method_return(req_info->context,
157 _bt_free_info_from_invocation_list(req_info);
160 case BT_MESH_NETWORK_CREATE: {
161 char uuid_str[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
162 bluetooth_mesh_node_t *node;
163 bluetooth_mesh_network_t *network;
164 ret_if(param == NULL);
165 BT_INFO("Mesh: Request: BT_MESH_NETWORK_CREATE Sender: [%s] result[%d]",
166 req_info->sender, result);
168 node = (bluetooth_mesh_node_t*) param;
169 network = (bluetooth_mesh_network_t*)req_info->user_data;
171 _bt_mesh_util_convert_hex_to_string(
172 (uint8_t *) node->uuid, 16, uuid_str,
173 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
175 BT_INFO("Mesh: Network UUID from event [%s] Netw UUID from req [%s]",
176 uuid_str, network->uuid);
178 if (!g_strcmp0(network->uuid, uuid_str)) {
179 BT_INFO("Mesh: BT_MESH_NETWORK_CREATE Request found uuid [%s]",
181 if (BLUETOOTH_ERROR_NONE != _bt_mesh_network_create_cdb(
182 result, req_info->sender,
183 network->app_cred, node->uuid,
184 node->token.u8, network->name.name)) {
185 result = BLUETOOTH_ERROR_INTERNAL;
186 BT_ERR("!!Mesh: BT_MESH_NETWORK_CREATE Failed!!");
189 _bt_mesh_util_convert_hex_to_string(
190 (uint8_t *) node->token.u8, 8,
191 network->token.token,
192 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
194 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
195 g_array_append_vals(out_param, network,
196 sizeof(bluetooth_mesh_network_t));
197 _bt_service_method_return(req_info->context,
199 _bt_free_info_from_invocation_list(req_info);
200 g_array_free(out_param, TRUE);
204 case BT_MESH_NETWORK_DESTROY: {
205 bluetooth_mesh_network_t *event;
206 bluetooth_mesh_network_t *network;
207 ret_if(param == NULL);
208 BT_INFO("Mesh: Request: BT_MESH_NETWORK_DESTROY Sender: [%s] result[%d]",
209 req_info->sender, result);
211 event = (bluetooth_mesh_network_t*) param;
212 network = (bluetooth_mesh_network_t*)req_info->user_data;
214 BT_INFO("Mesh: Network UUID from event [%s] Net UUID from req [%s]",
215 event->uuid, network->uuid);
217 if (!g_strcmp0(network->uuid, event->uuid)) {
218 BT_INFO("Mesh: BT_MESH_NETWORK_DESTROY Request found uuid [%s]",
221 result = _bt_mesh_network_remove_net_configuration(network);
223 BT_INFO("Mesh: Return Invocation for BT_MESH_NETWORK_DESTROY");
224 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
225 g_array_append_vals(out_param, network,
226 sizeof(bluetooth_mesh_network_t));
227 _bt_service_method_return(req_info->context,
229 _bt_free_info_from_invocation_list(req_info);
230 g_array_free(out_param, TRUE);
234 case BT_MESH_NETWORK_LOAD: {
235 char token_str[BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1];
236 bluetooth_mesh_node_t *node;
237 bluetooth_mesh_network_t *network;
238 ret_if(param == NULL);
239 BT_INFO("Mesh: Request: BT_MESH_NETWORK_LOAD Sender: [%s]",
242 node = (bluetooth_mesh_node_t*) param;
243 network = (bluetooth_mesh_network_t*)req_info->user_data;
245 _bt_mesh_util_convert_hex_to_string(
246 (uint8_t *) node->token.u8, 8, token_str,
247 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
248 BT_INFO("Mesh: Received Token [%s]", token_str);
250 if (!g_strcmp0(network->token.token, token_str)) {
251 char *network_name = NULL;
252 BT_INFO("Mesh: BT_MESH_NETWORK_LOAD Request found Token [%s]",
255 BT_INFO("Mesh: Load the Network resources");
256 /* Send request to mesh-network to load keys and Nodes for the network */
257 if (BLUETOOTH_ERROR_NONE == _bt_mesh_network_load_cdb(
258 result, req_info->sender, network->app_cred,
259 node->uuid, node->token.u8, &network_name)) {
260 g_strlcpy(network->name.name, network_name,
261 sizeof(network->name.name));
262 BT_INFO("Mesh: Got Name of the Network [%s]",
265 BT_ERR("!!Mesh: BT_MESH_NETWORK_LOAD Failed!!");
267 _bt_mesh_util_convert_hex_to_string((uint8_t *) node->uuid, 16, network->uuid,
268 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
270 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
271 g_array_append_vals(out_param, network, sizeof(bluetooth_mesh_network_t));
272 _bt_service_method_return(req_info->context, out_param, result);
273 _bt_free_info_from_invocation_list(req_info);
274 g_array_free(out_param, TRUE);
278 case BT_MESH_NETWORK_SCAN: {
279 bluetooth_mesh_network_t *network;
280 event_mesh_scan_status_t *event;
281 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
283 event = (event_mesh_scan_status_t*) param;
284 network = (bluetooth_mesh_network_t*)req_info->user_data;
285 _bt_mesh_util_convert_hex_to_string(
286 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
287 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
289 BT_DBG("Request Sender: [%s]", req_info->sender);
290 if (!g_strcmp0(network->uuid, net_uuid)) {
291 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
292 g_array_append_vals(out_param,
293 network, sizeof(bluetooth_mesh_network_t));
294 _bt_service_method_return(req_info->context,
296 _bt_free_info_from_invocation_list(req_info);
297 g_array_free(out_param, TRUE);
301 case BT_MESH_NETWORK_PROVISION_DEVICE: {
302 bluetooth_mesh_provisioning_request_t *req_data;
303 bluetooth_mesh_provisioning_request_t status_data;
304 event_mesh_provisioning_status_t *event;
306 0x00, sizeof(bluetooth_mesh_provisioning_request_t));
308 event = (event_mesh_provisioning_status_t*) param;
309 req_data = (bluetooth_mesh_provisioning_request_t*) req_info->user_data;
311 _bt_mesh_util_convert_hex_to_string(
312 (uint8_t *) event->net_uuid.uuid, 16, status_data.net_uuid,
313 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
315 _bt_mesh_util_convert_hex_to_string(
316 (uint8_t *) event->dev_uuid.uuid, 16, status_data.dev_uuid,
317 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
318 BT_INFO("Mesh: Provision Status: Device UUID [%s]", status_data.dev_uuid);
319 BT_INFO("Mesh: Provision Status: Net UUID [%s]", status_data.net_uuid);
320 BT_INFO("Mesh: Provision Status: Result [%d]", event->status);
321 if (event->status == OAL_STATUS_SUCCESS)
322 BT_INFO("Mesh: Provisioning status : SUCCESS");
324 BT_INFO("Mesh: Provisioning status : FAIL");
326 BT_DBG("Request Sender: [%s]", req_info->sender);
327 if (!g_strcmp0(req_data->net_uuid, status_data.net_uuid)) {
328 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
329 g_array_append_vals(out_param, &status_data,
330 sizeof(bluetooth_mesh_provisioning_request_t));
331 _bt_service_method_return(req_info->context, out_param, result);
332 _bt_free_info_from_invocation_list(req_info);
333 g_array_free(out_param, TRUE);
338 case BT_MESH_NETWORK_DELETE_NETKEY:
339 case BT_MESH_NETWORK_UPDATE_NETKEY:
340 case BT_MESH_NETWORK_ADD_NETKEY: {
341 bluetooth_mesh_network_t *network;
342 event_mesh_netkey_operation_t *event;
343 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
345 event = (event_mesh_netkey_operation_t*) param;
346 network = (bluetooth_mesh_network_t*)req_info->user_data;
347 _bt_mesh_util_convert_hex_to_string(
348 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
349 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
351 BT_DBG("Request Sender: [%s]", req_info->sender);
352 if (!g_strcmp0(network->uuid, net_uuid)) {
353 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
354 g_array_append_vals(out_param, &event->key_idx, sizeof(guint16));
355 _bt_service_method_return(req_info->context, out_param, result);
356 _bt_free_info_from_invocation_list(req_info);
357 g_array_free(out_param, TRUE);
362 case BT_MESH_NETWORK_DELETE_APPKEY:
363 case BT_MESH_NETWORK_UPDATE_APPKEY:
364 case BT_MESH_NETWORK_ADD_APPKEY: {
365 bluetooth_mesh_network_t *network;
366 event_mesh_appkey_operation_t *event;
367 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
369 event = (event_mesh_appkey_operation_t*) param;
370 network = (bluetooth_mesh_network_t*)req_info->user_data;
371 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
372 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
374 BT_DBG("Request Sender: [%s]", req_info->sender);
375 if (!g_strcmp0(network->uuid, net_uuid)) {
376 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
377 g_array_append_vals(out_param, &event->app_idx, sizeof(guint16));
378 _bt_service_method_return(req_info->context, out_param, result);
379 _bt_free_info_from_invocation_list(req_info);
380 g_array_free(out_param, TRUE);
385 BT_DBG("Unknown function(%d)", service_function);
391 static void __handle_mesh_network_subnet_operation_event(
392 event_mesh_netkey_operation_t *event)
394 int result = BLUETOOTH_ERROR_NONE;
396 if (event->status != OAL_STATUS_SUCCESS)
397 result = BLUETOOTH_ERROR_INTERNAL;
399 /* Handle DBUS Context return */
400 if (event->op == OAL_MESH_KEY_ADD) {
401 if (result == BLUETOOTH_ERROR_NONE)
402 _bt_mesh_network_handle_netkey_added(event->net_uuid.uuid, event->key_idx);
404 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_ADD_NETKEY,
405 event, sizeof(event_mesh_netkey_operation_t));
406 } else if (event->op == OAL_MESH_KEY_DELETE) {
407 if (result == BLUETOOTH_ERROR_NONE)
408 _bt_mesh_network_handle_netkey_deleted(event->net_uuid.uuid, event->key_idx);
410 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_DELETE_NETKEY,
411 event, sizeof(event_mesh_netkey_operation_t));
412 } else if (event->op == OAL_MESH_KEY_UPDATE) {
413 _bt_mesh_network_handle_netkey_updated(event->net_uuid.uuid, event->key_idx);
415 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_UPDATE_NETKEY,
416 event, sizeof(event_mesh_netkey_operation_t));
420 static void __handle_mesh_network_appkey_operation_event(
421 event_mesh_appkey_operation_t *event)
423 int result = BLUETOOTH_ERROR_NONE;
425 if (event->status != OAL_STATUS_SUCCESS)
426 result = BLUETOOTH_ERROR_INTERNAL;
427 /* Handle DBUS Context return */
428 if (event->op == OAL_MESH_KEY_ADD) {
429 BT_INFO("Mesh: Appkey Add event");
430 if (result == BLUETOOTH_ERROR_NONE)
431 _bt_mesh_network_handle_appkey_added(
432 event->net_uuid.uuid, event->net_idx, event->app_idx);
434 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_ADD_APPKEY,
435 event, sizeof(event_mesh_netkey_operation_t));
436 } else if (event->op == OAL_MESH_KEY_DELETE) {
437 BT_INFO("Mesh: Appkey Delete event");
438 if (result == BLUETOOTH_ERROR_NONE)
439 _bt_mesh_network_handle_appkey_deleted(
440 event->net_uuid.uuid, event->net_idx, event->app_idx);
442 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_DELETE_APPKEY,
443 event, sizeof(event_mesh_netkey_operation_t));
444 } else if (event->op == OAL_MESH_KEY_UPDATE) {
445 BT_INFO("Mesh: Appkey Update event");
446 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_UPDATE_APPKEY,
447 event, sizeof(event_mesh_netkey_operation_t));
451 static void __handle_mesh_devkey_message_received_event(
452 event_mesh_devkey_message_t *event)
454 _bt_mesh_config_client_devkey_msg_handler(event);
457 static void __handle_mesh_message_received_event(
458 event_mesh_message_t *event)
460 _bt_mesh_msg_handler(event);
463 static void __handle_mesh_network_proxy_added_event(
464 event_mesh_network_proxy_added_t *event)
466 int result = BLUETOOTH_ERROR_NONE;
468 if (event->status != OAL_STATUS_SUCCESS)
469 result = BLUETOOTH_ERROR_INTERNAL;
471 /* Handle DBUS Context return */
472 BT_INFO("Mesh: Handle DBUS Context return");
473 __bt_mesh_handle_pending_request_info(result,
478 static void __handle_mesh_network_attached_event(
479 event_mesh_network_attached_t *event)
481 int result = BLUETOOTH_ERROR_NONE;
482 bluetooth_mesh_node_t node;
484 if (event->status != OAL_STATUS_SUCCESS)
485 result = BLUETOOTH_ERROR_INTERNAL;
487 memset(&node, 0x00, sizeof(bluetooth_mesh_node_t));
489 memcpy(node.uuid, event->uuid.uuid, 16);
490 memcpy(node.token.u8, event->token, 8);
492 __bt_mesh_handle_pending_request_info(result,
493 BT_MESH_NETWORK_CREATE,
494 &node, sizeof(bluetooth_mesh_node_t));
495 __bt_mesh_handle_pending_request_info(result,
496 BT_MESH_NETWORK_LOAD,
497 &node, sizeof(bluetooth_mesh_node_t));
500 static void __handle_mesh_network_destroyed_event(
501 event_mesh_network_destroyed_t *event)
503 int result = BLUETOOTH_ERROR_NONE;
504 bluetooth_mesh_network_t network;
506 if (event->status != OAL_STATUS_SUCCESS) {
507 BT_INFO("Mesh: Network Destroyed Event: result is Failed!");
508 result = BLUETOOTH_ERROR_INTERNAL;
510 BT_INFO("Mesh: Network Destroyed Event: result is Success!");
513 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
514 _bt_mesh_util_convert_hex_to_string(
515 (uint8_t *) event->uuid.uuid, 16, network.uuid,
516 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
517 _bt_mesh_util_convert_hex_to_string(
518 (uint8_t *) event->token, 8, network.token.token,
519 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
521 __bt_mesh_handle_pending_request_info(result,
522 BT_MESH_NETWORK_DESTROY,
523 &network, sizeof(bluetooth_mesh_network_t));
526 static void __handle_mesh_network_scan_started_event(
527 event_mesh_scan_status_t *event)
529 GVariant *out_var = NULL, *param = NULL;
531 bluetooth_mesh_network_t network;
533 int result = BLUETOOTH_ERROR_NONE;
534 if (event->status != OAL_STATUS_SUCCESS) {
535 result = BLUETOOTH_ERROR_INTERNAL;
536 _bt_mesh_set_scanning_state(false);
538 _bt_mesh_set_scanning_state(true);
540 /* Handle DBUS Context return */
541 __bt_mesh_handle_pending_request_info(result,
542 BT_MESH_NETWORK_SCAN,
543 event, sizeof(event_mesh_scan_status_t));
545 /* Handle Scan started event */
546 if (result == BLUETOOTH_ERROR_NONE) {
547 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
548 _bt_mesh_util_convert_hex_to_string(
549 (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
550 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
552 info = g_array_new(FALSE, FALSE, sizeof(gchar));
553 g_array_append_vals(info, &network,
554 sizeof(bluetooth_mesh_network_t));
556 out_var = g_variant_new_from_data((const GVariantType *)"ay",
557 info->data, info->len,
560 param = g_variant_new("(iv)", result, out_var);
561 _bt_send_event(BT_MESH_EVENT,
562 BLUETOOTH_EVENT_MESH_SCAN_STARTED,
567 static void __handle_mesh_network_scan_finished_event(
568 event_mesh_scan_status_t *event)
570 GVariant *out_var = NULL, *param = NULL;
572 bluetooth_mesh_network_t network;
573 int result = BLUETOOTH_ERROR_NONE;
574 if (event->status != OAL_STATUS_SUCCESS) {
575 BT_INFO("Mesh: Scan Finished: status:: FAILED!");
576 result = BLUETOOTH_ERROR_INTERNAL;
578 BT_INFO("Mesh: Scan Finished: status:: SUCCESS!");
580 /* Handle Scan finsihed event */
581 if (result == BLUETOOTH_ERROR_NONE) {
582 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
583 _bt_mesh_util_convert_hex_to_string(
584 (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
585 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
587 info = g_array_new(FALSE, FALSE, sizeof(gchar));
588 g_array_append_vals(info, &network,
589 sizeof(bluetooth_mesh_network_t));
591 out_var = g_variant_new_from_data((const GVariantType *)"ay",
592 info->data, info->len,
595 param = g_variant_new("(iv)", result, out_var);
596 _bt_send_event(BT_MESH_EVENT,
597 BLUETOOTH_EVENT_MESH_SCAN_FINISHED,
599 _bt_mesh_set_scanning_state(false);
603 static void __handle_mesh_network_provisioning_started_event(
604 event_mesh_provisioning_status_t *status)
606 int result = BLUETOOTH_ERROR_NONE;
607 BT_INFO("Mesh: Provisioning started");
609 __bt_mesh_handle_pending_request_info(result,
610 BT_MESH_NETWORK_PROVISION_DEVICE,
611 status, sizeof(event_mesh_provisioning_status_t));
613 _bt_mesh_set_provisioning_state(true);
616 static void __handle_mesh_network_provisioning_failed_event(
617 event_mesh_provisioning_status_t *status)
619 int result = BLUETOOTH_ERROR_INTERNAL;
620 BT_INFO("Mesh: Provisioning failed!!");
621 __bt_mesh_handle_pending_request_info(result,
622 BT_MESH_NETWORK_PROVISION_DEVICE,
623 status, sizeof(event_mesh_provisioning_status_t));
625 _bt_mesh_set_provisioning_state(false);
628 static void __handle_mesh_network_provisioning_finished_event(
629 event_mesh_provisioning_finished_t *event)
631 GVariant *out_var = NULL, *param = NULL;
633 bluetooth_mesh_provisioning_result_t prov_result;
634 BT_INFO("Mesh: Provisioning Finished!");
636 memset(&prov_result, 0x00,
637 sizeof(bluetooth_mesh_provisioning_result_t));
639 if (event->status != OAL_STATUS_SUCCESS)
640 prov_result.result = BLUETOOTH_ERROR_INTERNAL;
642 prov_result.result = BLUETOOTH_ERROR_NONE;
644 prov_result.reason = event->reason;
645 prov_result.unicast = event->unicast;
646 prov_result.count = event->count;
648 _bt_mesh_util_convert_hex_to_string(
649 (uint8_t *) event->net_uuid.uuid, 16, prov_result.net_uuid,
650 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
652 _bt_mesh_util_convert_hex_to_string(
653 (uint8_t *) event->dev_uuid.uuid, 16, prov_result.dev_uuid,
654 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
656 info = g_array_new(FALSE, FALSE, sizeof(gchar));
657 g_array_append_vals(info, &prov_result,
658 sizeof(bluetooth_mesh_provisioning_result_t));
660 out_var = g_variant_new_from_data((const GVariantType *)"ay",
661 info->data, info->len,
664 param = g_variant_new("(iv)", prov_result.result, out_var);
665 _bt_send_event(BT_MESH_EVENT,
666 BLUETOOTH_EVENT_MESH_PROVISIONING_FINISHED,
669 /* Add Remote Node entry in Local CDB */
670 if (event->status == OAL_STATUS_SUCCESS) {
671 BT_INFO("Mesh: Provisioning done, add node to Network");
672 BT_INFO("Mesh: Node UUID [%s]", prov_result.dev_uuid);
673 BT_INFO("Mesh: Node Unicast[0x%2.2x] Element Count [%d]",
674 event->unicast, event->count);
676 _bt_mesh_network_add_remote_node(
677 event->net_uuid.uuid, event->dev_uuid.uuid,
678 event->unicast, event->count);
680 /* Unset provisioning state */
681 _bt_mesh_set_provisioning_state(false);
684 static void __handle_mesh_network_provisioning_data_requested_event(
685 event_mesh_provisioning_data_requested_t *event)
687 _bt_mesh_network_request_provisioning_data_request(
688 event->net_uuid.uuid, event->count);
691 static void __handle_mesh_network_authentication_requested_event(
692 event_mesh_authentication_requested_t *event)
694 GVariant *out_var = NULL, *param = NULL;
696 bluetooth_mesh_authentication_request_t auth_req;
698 memset(&auth_req, 0x00,
699 sizeof(bluetooth_mesh_authentication_request_t));
701 auth_req.auth_type = event->auth_type;
702 g_strlcpy(auth_req.auth_value, event->auth_value,
703 sizeof(auth_req.auth_value));
705 _bt_mesh_util_convert_hex_to_string(
706 (uint8_t *) event->net_uuid.uuid, 16, auth_req.net_uuid,
707 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
709 BT_INFO("Mesh: Authentication Requested by Device: Network [%s]",
711 info = g_array_new(FALSE, FALSE, sizeof(gchar));
712 g_array_append_vals(info, &auth_req,
713 sizeof(bluetooth_mesh_authentication_request_t));
715 out_var = g_variant_new_from_data((const GVariantType *)"ay",
716 info->data, info->len,
719 param = g_variant_new("(iv)", BLUETOOTH_ERROR_NONE, out_var);
720 _bt_send_event(BT_MESH_EVENT,
721 BLUETOOTH_EVENT_MESH_AUTHENTICATION_REQUEST,
725 static void __handle_mesh_network_scan_result_event(
726 event_mesh_scan_result_t *event)
728 GVariant *out_var = NULL, *param = NULL;
730 bluetooth_mesh_scan_result_t data;
731 int result = BLUETOOTH_ERROR_NONE;
733 memset(&data, 0x00, sizeof(bluetooth_mesh_scan_result_t));
735 /* Fill Network UUID */
736 _bt_mesh_util_convert_hex_to_string(
737 (uint8_t *) event->net_uuid.uuid, 16, data.net_uuid,
738 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
740 /* Fill Device UUID */
741 _bt_mesh_util_convert_hex_to_string(
742 (uint8_t *) event->result.dev_uuid.uuid, 16, data.dev_uuid,
743 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
746 data.rssi = event->result.rssi;
749 memcpy(&data.oob_info, event->result.oob_info, 2);
751 /* Fill URI Hash Info */
752 memcpy(&data.uri_hash, event->result.uri_hash, 4);
754 if (event->status != OAL_STATUS_SUCCESS)
755 result = BLUETOOTH_ERROR_INTERNAL;
758 info = g_array_new(FALSE, FALSE, sizeof(gchar));
759 g_array_append_vals(info, &data,
760 sizeof(bluetooth_mesh_scan_result_t));
762 out_var = g_variant_new_from_data((const GVariantType *)"ay",
763 info->data, info->len,
766 param = g_variant_new("(iv)", result, out_var);
767 _bt_send_event(BT_MESH_EVENT,
768 BLUETOOTH_EVENT_MESH_SCAN_RESULT,
772 static void __handle_mesh_events(int event_type,
775 BT_INFO("Mesh: Got Mesh event!!! event type [%d]", event_type);
776 if (event_type == OAL_EVENT_MESH_PROVISIONING_STARTED)
777 BT_INFO("Mesh: Provisioning started event");
779 switch (event_type) {
780 case OAL_EVENT_MESH_NETWORK_PROXY_ADDED:
781 __handle_mesh_network_proxy_added_event(
782 (event_mesh_network_proxy_added_t*)event_data);
783 BT_PERMANENT_LOG("Mesh: Network proxy added!!");
785 case OAL_EVENT_MESH_NETWORK_ATTACHED:
786 __handle_mesh_network_attached_event(
787 (event_mesh_network_attached_t*)event_data);
788 BT_PERMANENT_LOG("Mesh: Network attached!!");
790 case OAL_EVENT_MESH_NETWORK_DESTROYED:
791 __handle_mesh_network_destroyed_event(
792 (event_mesh_network_destroyed_t*)event_data);
793 BT_PERMANENT_LOG("Mesh: Network Destroyed!!");
795 case OAL_EVENT_MESH_SCAN_STARTED:
796 __handle_mesh_network_scan_started_event(
797 (event_mesh_scan_status_t*)event_data);
798 BT_PERMANENT_LOG("Mesh: Network Scan Stated!!");
800 case OAL_EVENT_MESH_SCAN_FINISHED:
801 __handle_mesh_network_scan_finished_event(
802 (event_mesh_scan_status_t*)event_data);
803 BT_PERMANENT_LOG("Mesh: Network Scan Finished!!");
805 case OAL_EVENT_MESH_SCAN_RESULT:
806 __handle_mesh_network_scan_result_event(
807 (event_mesh_scan_result_t*)event_data);
808 BT_PERMANENT_LOG("Mesh: Network Scan Result!!");
810 case OAL_EVENT_MESH_PROVISIONING_STARTED:
811 BT_INFO("Mesh: Network Provisioning Started");
812 __handle_mesh_network_provisioning_started_event(
813 (event_mesh_provisioning_status_t*)event_data);
814 BT_PERMANENT_LOG("Mesh: Network Provisioning Started");
816 case OAL_EVENT_MESH_PROVISIONING_FAILED:
817 BT_INFO("Mesh: Network Provisioning Failed!!!!");
818 __handle_mesh_network_provisioning_failed_event(
819 (event_mesh_provisioning_status_t*)event_data);
820 BT_PERMANENT_LOG("Mesh: Network Provisioning Failed");
822 case OAL_EVENT_MESH_PROVISIONING_FINISHED:
823 __handle_mesh_network_provisioning_finished_event(
824 (event_mesh_provisioning_finished_t*)event_data);
825 BT_PERMANENT_LOG("Mesh: Network Provisioning Finished");
827 case OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED:
828 __handle_mesh_network_provisioning_data_requested_event(
829 (event_mesh_provisioning_data_requested_t*)event_data);
830 BT_PERMANENT_LOG("Mesh: Network Provisioning Data Requested");
832 case OAL_EVENT_MESH_AUTHENTICATION_REQUESTED:
833 __handle_mesh_network_authentication_requested_event(
834 (event_mesh_authentication_requested_t*)event_data);
835 BT_PERMANENT_LOG("Mesh: Network Authentication Requested");
837 case OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT:
838 __handle_mesh_network_subnet_operation_event(
839 (event_mesh_netkey_operation_t*)event_data);
840 BT_PERMANENT_LOG("Mesh: Network Subnet operation event");
842 case OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT:
843 __handle_mesh_network_appkey_operation_event(
844 (event_mesh_appkey_operation_t*)event_data);
845 BT_PERMANENT_LOG("Mesh: AppKey operation event");
847 case OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED:
848 __handle_mesh_devkey_message_received_event(
849 (event_mesh_devkey_message_t*)event_data);
850 BT_PERMANENT_LOG("Mesh: DevKey Message Received event");
852 case OAL_EVENT_MESH_MODEL_MESSAGE_RECEIVED:
853 __handle_mesh_message_received_event(
854 (event_mesh_message_t*)event_data);
855 BT_PERMANENT_LOG("Mesh: Model Message Received event");
862 static int __bt_mesh_enable()
864 oal_status_t status = OAL_STATUS_SUCCESS;
865 BT_INFO("Mesh: Set dbus callbacks");
866 status = mesh_enable();
867 if (OAL_STATUS_SUCCESS != status &&
868 OAL_STATUS_ALREADY_DONE != status) {
869 BT_ERR("Mesh: Failed to enable mesh interface, status: %d",
871 return BLUETOOTH_ERROR_INTERNAL;
873 BT_INFO("Mesh: Stack Initialization Done successfully: status [%d]",
876 /* Register MESH event handler */
877 _bt_service_register_event_handler_callback(BT_MESH_MODULE,
878 __handle_mesh_events);
880 return (status == OAL_STATUS_SUCCESS ? BLUETOOTH_ERROR_NONE : \
881 BLUETOOTH_ERROR_ALREADY_INITIALIZED);
884 static gboolean __bt_mesh_launch_timer_expired_cb(gpointer data)
886 BT_INFO("Mesh: Enable Mesh dbus");
887 int ret = BLUETOOTH_ERROR_NONE;
888 ret = __bt_mesh_enable();
889 if (BLUETOOTH_ERROR_NONE != ret &&
890 BLUETOOTH_ERROR_ALREADY_INITIALIZED != ret)
891 BT_ERR("Mesh: Mesh enable failed: %d", ret);
893 /* Reset launch timer ID */
894 BT_INFO("Mesh: Timer ID after expiry [%u]", launch_timer);
900 static void __bt_mesh_init_wait_response_timeout(
901 struct l_timeout *timeout, void *user_data)
903 int result = BLUETOOTH_ERROR_TIMEOUT;
905 /* Handle DBUS Context return */
906 BT_INFO("Mesh: Handle DBUS Context return");
907 __bt_mesh_handle_pending_request_info(result,
910 l_timeout_remove(wait_timer);
913 int _bt_mesh_init(const char *sender)
915 int ret = BLUETOOTH_ERROR_NONE;
917 BT_INFO("Mesh: Total apps using Mesh: [%d]",
920 BT_INFO("Mesh: Mesh App Sender [%s]", sender);
922 BT_INFO("Mesh: Current Timer ID [%u]", launch_timer);
923 if (launch_timer > 0) {
924 BT_INFO("Mesh: BT_MESH_INIT in progress");
928 if (mesh_app_ref_count) {
929 BT_INFO("Mesh: Mesh Stack already initialized");
931 /* Save Mesh App Owner */
932 apps = g_slist_append(apps, g_strdup(sender));
934 /* Increase mesh app ref count */
935 mesh_app_ref_count++;
936 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
939 BT_INFO("Mesh: Mesh Stack init not done yet!");
940 /* Launch bluetooth-meshd */
941 ret = __bt_meshd_launch();
942 if (BLUETOOTH_ERROR_NONE != ret) {
943 BT_ERR("Mesh: Meshd launch failed: %d", ret);
947 /* wait for half a second*/
948 launch_timer = g_timeout_add(MESH_LAUNCH_DELAY,
949 (GSourceFunc)__bt_mesh_launch_timer_expired_cb,
951 BT_INFO("Mesh: Timer ID [%u]", launch_timer);
953 /* Add mesh init request timeout */
954 wait_timer = l_timeout_create(MESH_DEFAULT_RESPONSE_TIMEOUT,
955 __bt_mesh_init_wait_response_timeout, NULL, NULL);
960 static gint __bt_mesh_match_sender(gconstpointer a, gconstpointer b)
962 char *owner_a = (char*) a;
963 char *owner_b = (char*) b;
965 return g_strcmp0(owner_a, owner_b);
968 int _bt_mesh_deinit(const char *sender)
973 BT_INFO("Mesh: Deinit Request from App [%s]", sender);
974 BT_INFO("Mesh: Total Apps available in list [%d]",
975 g_slist_length(apps));
977 /* Find & remove app entry from list */
978 l = g_slist_find_custom(apps, sender,
979 (GCompareFunc)__bt_mesh_match_sender);
981 BT_ERR("Mesh: App is not Mesh App");
982 return BLUETOOTH_ERROR_INTERNAL;
985 BT_INFO("Mesh: Deinit Mesh: Sender Found: [%s]", sender);
987 if (launch_timer > 0) {
988 g_source_remove(launch_timer);
992 BT_INFO("Mesh: Current number of applications using mesh [%d]",
995 if (mesh_app_ref_count == 1) {
996 BT_INFO("Mesh: Only one app using Mesh Stack: Unload & reduce ref count");
998 /* Terminate bluetooth-mesh */
999 __bt_mesh_terminate();
1002 /* Decrease mesh app ref count */
1003 mesh_app_ref_count--;
1006 apps = g_slist_remove(apps, owner);
1009 _bt_mesh_deinitialized();
1011 return BLUETOOTH_ERROR_NONE;
1014 void _bt_mesh_handle_app_termination(const char *sender)
1016 BT_INFO("Mesh: Handle App termination: dbus app name[%s]",
1019 _bt_mesh_deinit(sender);