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;
58 static int __bt_meshd_launch()
60 int ret = UNIT_CONTROL_OK;
61 BT_INFO("Mesh: Launch Meshd");
62 ret = actd_start_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
63 MESH_SYSTEMD_SERVICE_NAME, 5000);
65 if (ret != UNIT_CONTROL_OK) {
66 BT_ERR("Failed to call systemact service: %d", ret);
67 return BLUETOOTH_ERROR_INTERNAL;
69 BT_INFO("Mesh: Launch Meshd successful");
71 return BLUETOOTH_ERROR_NONE;
74 static void __bt_meshd_terminate()
76 int ret = UNIT_CONTROL_OK;
77 BT_INFO("Mesh: Stop Meshd");
79 ret = actd_stop_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
80 MESH_SYSTEMD_SERVICE_NAME, 5000);
81 if (ret != UNIT_CONTROL_OK) {
82 BT_ERR("Failed to call systemact service: %d", ret);
86 BT_INFO("Mesh: Meshd stop successful");
89 static void __bt_mesh_terminate()
91 oal_status_t status = OAL_STATUS_SUCCESS;
93 /* Terminate bluetooth-meshd */
94 __bt_meshd_terminate();
97 _bt_mesh_set_scanning_state(false);
98 _bt_mesh_set_provisioning_state(false);
100 status = mesh_disable();
101 if (OAL_STATUS_SUCCESS != status) {
102 BT_ERR("Mesh: Failed to de-initialize Mesh profile, status: %d",
107 /* Un-Register Mesh event handler */
108 _bt_service_unregister_event_handler_callback(BT_MESH_MODULE);
111 bool _bt_is_mesh_initialized()
113 return (mesh_app_ref_count ? true : false);
117 static void __bt_mesh_handle_pending_request_info(int result,
118 int service_function, void *param,
123 invocation_info_t *req_info = NULL;
125 for (l = _bt_get_invocation_list(); l != NULL; ) {
128 if (req_info == NULL ||
129 req_info->service_function != service_function)
132 switch (service_function) {
134 BT_INFO("Mesh: Request: BT_MESH_INIT Sender: [%s] result[%d]",
135 req_info->sender, result);
137 if (result == BLUETOOTH_ERROR_NONE) {
139 /* Save Mesh App Owner */
140 char *owner = g_strdup(req_info->sender);
141 BT_INFO("Mesh: Insert Sender Mesh App List[%s]",
143 apps = g_slist_append(apps, owner);
145 /* Increase mesh app ref count */
146 mesh_app_ref_count++;
147 l_timeout_remove(wait_timer);
149 /* Init failed - Terminate bluetooth-mesh */
150 __bt_mesh_terminate();
153 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
154 _bt_service_method_return(req_info->context,
156 _bt_free_info_from_invocation_list(req_info);
159 case BT_MESH_NETWORK_CREATE: {
160 char uuid_str[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
161 bluetooth_mesh_node_t *node;
162 bluetooth_mesh_network_t *network;
163 ret_if(param == NULL);
164 BT_INFO("Mesh: Request: BT_MESH_NETWORK_CREATE Sender: [%s] result[%d]",
165 req_info->sender, result);
167 node = (bluetooth_mesh_node_t*) param;
168 network = (bluetooth_mesh_network_t*)req_info->user_data;
170 _bt_mesh_util_convert_hex_to_string(
171 (uint8_t *) node->uuid, 16, uuid_str,
172 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
174 BT_INFO("Mesh: Network UUID from event [%s] Netw UUID from req [%s]",
175 uuid_str, network->uuid);
177 if (!g_strcmp0(network->uuid, uuid_str)) {
178 BT_INFO("Mesh: BT_MESH_NETWORK_CREATE Request found uuid [%s]",
180 if (BLUETOOTH_ERROR_NONE != _bt_mesh_network_create_cdb(
181 result, req_info->sender,
182 network->app_cred, node->uuid,
183 node->token.u8, network->name.name)) {
184 result = BLUETOOTH_ERROR_INTERNAL;
185 BT_ERR("!!Mesh: BT_MESH_NETWORK_CREATE Failed!!");
188 _bt_mesh_util_convert_hex_to_string(
189 (uint8_t *) node->token.u8, 8,
190 network->token.token,
191 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
193 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
194 g_array_append_vals(out_param, network,
195 sizeof(bluetooth_mesh_network_t));
196 _bt_service_method_return(req_info->context,
198 _bt_free_info_from_invocation_list(req_info);
199 g_array_free(out_param, TRUE);
203 case BT_MESH_NETWORK_DESTROY: {
204 bluetooth_mesh_network_t *event;
205 bluetooth_mesh_network_t *network;
206 ret_if(param == NULL);
207 BT_INFO("Mesh: Request: BT_MESH_NETWORK_DESTROY Sender: [%s] result[%d]",
208 req_info->sender, result);
210 event = (bluetooth_mesh_network_t*) param;
211 network = (bluetooth_mesh_network_t*)req_info->user_data;
213 BT_INFO("Mesh: Network UUID from event [%s] Net UUID from req [%s]",
214 event->uuid, network->uuid);
216 if (!g_strcmp0(network->uuid, event->uuid)) {
217 BT_INFO("Mesh: BT_MESH_NETWORK_DESTROY Request found uuid [%s]",
220 result = _bt_mesh_network_remove_net_configuration(network);
222 BT_INFO("Mesh: Return Invocation for BT_MESH_NETWORK_DESTROY");
223 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
224 g_array_append_vals(out_param, network,
225 sizeof(bluetooth_mesh_network_t));
226 _bt_service_method_return(req_info->context,
228 _bt_free_info_from_invocation_list(req_info);
229 g_array_free(out_param, TRUE);
233 case BT_MESH_NETWORK_LOAD: {
234 char token_str[BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1];
235 bluetooth_mesh_node_t *node;
236 bluetooth_mesh_network_t *network;
237 ret_if(param == NULL);
238 BT_INFO("Mesh: Request: BT_MESH_NETWORK_LOAD Sender: [%s]",
241 node = (bluetooth_mesh_node_t*) param;
242 network = (bluetooth_mesh_network_t*)req_info->user_data;
244 _bt_mesh_util_convert_hex_to_string(
245 (uint8_t *) node->token.u8, 8, token_str,
246 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
247 BT_INFO("Mesh: Received Token [%s]", token_str);
249 if (!g_strcmp0(network->token.token, token_str)) {
250 char *network_name = NULL;
251 BT_INFO("Mesh: BT_MESH_NETWORK_LOAD Request found Token [%s]",
254 BT_INFO("Mesh: Load the Network resources");
255 /* Send request to mesh-network to load keys and Nodes for the network */
256 if (BLUETOOTH_ERROR_NONE == _bt_mesh_network_load_cdb(
257 result, req_info->sender, network->app_cred,
258 node->uuid, node->token.u8, &network_name)) {
259 g_strlcpy(network->name.name, network_name,
260 sizeof(network->name.name));
261 BT_INFO("Mesh: Got Name of the Network [%s]",
264 BT_ERR("!!Mesh: BT_MESH_NETWORK_LOAD Failed!!");
266 _bt_mesh_util_convert_hex_to_string((uint8_t *) node->uuid, 16, network->uuid,
267 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
269 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
270 g_array_append_vals(out_param, network, sizeof(bluetooth_mesh_network_t));
271 _bt_service_method_return(req_info->context, out_param, result);
272 _bt_free_info_from_invocation_list(req_info);
273 g_array_free(out_param, TRUE);
277 case BT_MESH_NETWORK_SCAN: {
278 bluetooth_mesh_network_t *network;
279 event_mesh_scan_status_t *event;
280 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
282 event = (event_mesh_scan_status_t*) param;
283 network = (bluetooth_mesh_network_t*)req_info->user_data;
284 _bt_mesh_util_convert_hex_to_string(
285 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
286 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
288 BT_DBG("Request Sender: [%s]", req_info->sender);
289 if (!g_strcmp0(network->uuid, net_uuid)) {
290 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
291 g_array_append_vals(out_param,
292 network, sizeof(bluetooth_mesh_network_t));
293 _bt_service_method_return(req_info->context,
295 _bt_free_info_from_invocation_list(req_info);
296 g_array_free(out_param, TRUE);
300 case BT_MESH_NETWORK_PROVISION_DEVICE: {
301 bluetooth_mesh_provisioning_request_t *req_data;
302 bluetooth_mesh_provisioning_request_t status_data;
303 event_mesh_provisioning_status_t *event;
305 0x00, sizeof(bluetooth_mesh_provisioning_request_t));
307 event = (event_mesh_provisioning_status_t*) param;
308 req_data = (bluetooth_mesh_provisioning_request_t*) req_info->user_data;
310 _bt_mesh_util_convert_hex_to_string(
311 (uint8_t *) event->net_uuid.uuid, 16, status_data.net_uuid,
312 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
314 _bt_mesh_util_convert_hex_to_string(
315 (uint8_t *) event->dev_uuid.uuid, 16, status_data.dev_uuid,
316 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
317 BT_INFO("Mesh: Provision Status: Device UUID [%s]", status_data.dev_uuid);
318 BT_INFO("Mesh: Provision Status: Net UUID [%s]", status_data.net_uuid);
319 BT_INFO("Mesh: Provision Status: Result [%d]", event->status);
320 if (event->status == OAL_STATUS_SUCCESS)
321 BT_INFO("Mesh: Provisioning status : SUCCESS");
323 BT_INFO("Mesh: Provisioning status : FAIL");
325 BT_DBG("Request Sender: [%s]", req_info->sender);
326 if (!g_strcmp0(req_data->net_uuid, status_data.net_uuid)) {
327 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
328 g_array_append_vals(out_param, &status_data,
329 sizeof(bluetooth_mesh_provisioning_request_t));
330 _bt_service_method_return(req_info->context, out_param, result);
331 _bt_free_info_from_invocation_list(req_info);
332 g_array_free(out_param, TRUE);
337 case BT_MESH_NETWORK_DELETE_NETKEY:
338 case BT_MESH_NETWORK_UPDATE_NETKEY:
339 case BT_MESH_NETWORK_ADD_NETKEY: {
340 bluetooth_mesh_network_t *network;
341 event_mesh_netkey_operation_t *event;
342 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
344 event = (event_mesh_netkey_operation_t*) param;
345 network = (bluetooth_mesh_network_t*)req_info->user_data;
346 _bt_mesh_util_convert_hex_to_string(
347 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
348 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
350 BT_DBG("Request Sender: [%s]", req_info->sender);
351 if (!g_strcmp0(network->uuid, net_uuid)) {
352 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
353 g_array_append_vals(out_param, &event->key_idx, sizeof(guint16));
354 _bt_service_method_return(req_info->context, out_param, result);
355 _bt_free_info_from_invocation_list(req_info);
356 g_array_free(out_param, TRUE);
361 case BT_MESH_NETWORK_DELETE_APPKEY:
362 case BT_MESH_NETWORK_UPDATE_APPKEY:
363 case BT_MESH_NETWORK_ADD_APPKEY: {
364 bluetooth_mesh_network_t *network;
365 event_mesh_appkey_operation_t *event;
366 char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
368 event = (event_mesh_appkey_operation_t*) param;
369 network = (bluetooth_mesh_network_t*)req_info->user_data;
370 _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
371 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
373 BT_DBG("Request Sender: [%s]", req_info->sender);
374 if (!g_strcmp0(network->uuid, net_uuid)) {
375 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
376 g_array_append_vals(out_param, &event->app_idx, sizeof(guint16));
377 _bt_service_method_return(req_info->context, out_param, result);
378 _bt_free_info_from_invocation_list(req_info);
379 g_array_free(out_param, TRUE);
384 BT_DBG("Unknown function(%d)", service_function);
390 static void __handle_mesh_network_subnet_operation_event(
391 event_mesh_netkey_operation_t *event)
393 int result = BLUETOOTH_ERROR_NONE;
395 if (event->status != OAL_STATUS_SUCCESS)
396 result = BLUETOOTH_ERROR_INTERNAL;
398 /* Handle DBUS Context return */
399 if (event->op == OAL_MESH_KEY_ADD) {
400 if (result == BLUETOOTH_ERROR_NONE)
401 _bt_mesh_network_handle_netkey_added(event->net_uuid.uuid, event->key_idx);
403 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_ADD_NETKEY,
404 event, sizeof(event_mesh_netkey_operation_t));
405 } else if (event->op == OAL_MESH_KEY_DELETE) {
406 if (result == BLUETOOTH_ERROR_NONE)
407 _bt_mesh_network_handle_netkey_deleted(event->net_uuid.uuid, event->key_idx);
409 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_DELETE_NETKEY,
410 event, sizeof(event_mesh_netkey_operation_t));
411 } else if (event->op == OAL_MESH_KEY_UPDATE) {
412 _bt_mesh_network_handle_netkey_updated(event->net_uuid.uuid, event->key_idx);
414 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_UPDATE_NETKEY,
415 event, sizeof(event_mesh_netkey_operation_t));
419 static void __handle_mesh_network_appkey_operation_event(
420 event_mesh_appkey_operation_t *event)
422 int result = BLUETOOTH_ERROR_NONE;
424 if (event->status != OAL_STATUS_SUCCESS)
425 result = BLUETOOTH_ERROR_INTERNAL;
426 /* Handle DBUS Context return */
427 if (event->op == OAL_MESH_KEY_ADD) {
428 BT_INFO("Mesh: Appkey Add event");
429 if (result == BLUETOOTH_ERROR_NONE)
430 _bt_mesh_network_handle_appkey_added(
431 event->net_uuid.uuid, event->net_idx, event->app_idx);
433 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_ADD_APPKEY,
434 event, sizeof(event_mesh_netkey_operation_t));
435 } else if (event->op == OAL_MESH_KEY_DELETE) {
436 BT_INFO("Mesh: Appkey Delete event");
437 if (result == BLUETOOTH_ERROR_NONE)
438 _bt_mesh_network_handle_appkey_deleted(
439 event->net_uuid.uuid, event->net_idx, event->app_idx);
441 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_DELETE_APPKEY,
442 event, sizeof(event_mesh_netkey_operation_t));
443 } else if (event->op == OAL_MESH_KEY_UPDATE) {
444 BT_INFO("Mesh: Appkey Update event");
445 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_UPDATE_APPKEY,
446 event, sizeof(event_mesh_netkey_operation_t));
450 static void __handle_mesh_devkey_message_received_event(
451 event_mesh_devkey_message_t *event)
453 _bt_mesh_config_client_devkey_msg_handler(event);
456 static void __handle_mesh_message_received_event(
457 event_mesh_message_t *event)
459 _bt_mesh_msg_handler(event);
462 static void __handle_mesh_network_proxy_added_event(
463 event_mesh_network_proxy_added_t *event)
465 int result = BLUETOOTH_ERROR_NONE;
467 if (event->status != OAL_STATUS_SUCCESS)
468 result = BLUETOOTH_ERROR_INTERNAL;
470 /* Handle DBUS Context return */
471 BT_INFO("Mesh: Handle DBUS Context return");
472 __bt_mesh_handle_pending_request_info(result,
477 static void __handle_mesh_network_join_completed_event(
478 event_mesh_network_attached_t *event)
480 GVariant *out_var = NULL, *param = NULL;
482 bluetooth_mesh_node_t node;
483 int result = BLUETOOTH_ERROR_NONE;
484 if (event->status != OAL_STATUS_SUCCESS) {
485 BT_INFO("Mesh: Join Finished: status:: FAILED!");
486 result = BLUETOOTH_ERROR_INTERNAL;
489 BT_INFO("Mesh: Join Finished: status:: SUCCESS!");
491 if (result == BLUETOOTH_ERROR_NONE) {
492 memset(&node, 0x00, sizeof(bluetooth_mesh_node_t));
493 memcpy(node.uuid, event->uuid.uuid, 16);
494 info = g_array_new(FALSE, FALSE, sizeof(gchar));
495 g_array_append_vals(info, &node,
496 sizeof(bluetooth_mesh_node_t));
497 out_var = g_variant_new_from_data((const GVariantType *)"ay",
498 info->data, info->len,
501 param = g_variant_new("(iv)", result, out_var);
502 _bt_send_event(BT_MESH_EVENT,
503 BLUETOOTH_EVENT_MESH_JOIN_COMPLETED,
508 static void __handle_mesh_network_attached_event(
509 event_mesh_network_attached_t *event)
511 int result = BLUETOOTH_ERROR_NONE;
512 bluetooth_mesh_node_t node;
514 if (event->status != OAL_STATUS_SUCCESS)
515 result = BLUETOOTH_ERROR_INTERNAL;
517 memset(&node, 0x00, sizeof(bluetooth_mesh_node_t));
519 memcpy(node.uuid, event->uuid.uuid, 16);
520 memcpy(node.token.u8, event->token, 8);
522 __bt_mesh_handle_pending_request_info(result,
523 BT_MESH_NETWORK_CREATE,
524 &node, sizeof(bluetooth_mesh_node_t));
525 __bt_mesh_handle_pending_request_info(result,
526 BT_MESH_NETWORK_LOAD,
527 &node, sizeof(bluetooth_mesh_node_t));
529 __handle_mesh_network_join_completed_event(event);
532 static void __handle_mesh_network_destroyed_event(
533 event_mesh_network_destroyed_t *event)
535 int result = BLUETOOTH_ERROR_NONE;
536 bluetooth_mesh_network_t network;
538 if (event->status != OAL_STATUS_SUCCESS) {
539 BT_INFO("Mesh: Network Destroyed Event: result is Failed!");
540 result = BLUETOOTH_ERROR_INTERNAL;
542 BT_INFO("Mesh: Network Destroyed Event: result is Success!");
545 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
546 _bt_mesh_util_convert_hex_to_string(
547 (uint8_t *) event->uuid.uuid, 16, network.uuid,
548 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
549 _bt_mesh_util_convert_hex_to_string(
550 (uint8_t *) event->token, 8, network.token.token,
551 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
553 __bt_mesh_handle_pending_request_info(result,
554 BT_MESH_NETWORK_DESTROY,
555 &network, sizeof(bluetooth_mesh_network_t));
558 static void __handle_mesh_network_scan_started_event(
559 event_mesh_scan_status_t *event)
561 GVariant *out_var = NULL, *param = NULL;
563 bluetooth_mesh_network_t network;
565 int result = BLUETOOTH_ERROR_NONE;
566 if (event->status != OAL_STATUS_SUCCESS) {
567 result = BLUETOOTH_ERROR_INTERNAL;
568 _bt_mesh_set_scanning_state(false);
570 _bt_mesh_set_scanning_state(true);
572 /* Handle DBUS Context return */
573 __bt_mesh_handle_pending_request_info(result,
574 BT_MESH_NETWORK_SCAN,
575 event, sizeof(event_mesh_scan_status_t));
577 /* Handle Scan started event */
578 if (result == BLUETOOTH_ERROR_NONE) {
579 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
580 _bt_mesh_util_convert_hex_to_string(
581 (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
582 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
584 info = g_array_new(FALSE, FALSE, sizeof(gchar));
585 g_array_append_vals(info, &network,
586 sizeof(bluetooth_mesh_network_t));
588 out_var = g_variant_new_from_data((const GVariantType *)"ay",
589 info->data, info->len,
592 param = g_variant_new("(iv)", result, out_var);
593 _bt_send_event(BT_MESH_EVENT,
594 BLUETOOTH_EVENT_MESH_SCAN_STARTED,
599 static void __handle_mesh_network_scan_finished_event(
600 event_mesh_scan_status_t *event)
602 GVariant *out_var = NULL, *param = NULL;
604 bluetooth_mesh_network_t network;
605 int result = BLUETOOTH_ERROR_NONE;
606 if (event->status != OAL_STATUS_SUCCESS) {
607 BT_INFO("Mesh: Scan Finished: status:: FAILED!");
608 result = BLUETOOTH_ERROR_INTERNAL;
610 BT_INFO("Mesh: Scan Finished: status:: SUCCESS!");
612 /* Handle Scan finsihed event */
613 if (result == BLUETOOTH_ERROR_NONE) {
614 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
615 _bt_mesh_util_convert_hex_to_string(
616 (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
617 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
619 info = g_array_new(FALSE, FALSE, sizeof(gchar));
620 g_array_append_vals(info, &network,
621 sizeof(bluetooth_mesh_network_t));
623 out_var = g_variant_new_from_data((const GVariantType *)"ay",
624 info->data, info->len,
627 param = g_variant_new("(iv)", result, out_var);
628 _bt_send_event(BT_MESH_EVENT,
629 BLUETOOTH_EVENT_MESH_SCAN_FINISHED,
631 _bt_mesh_set_scanning_state(false);
635 static void __handle_mesh_network_provisioning_started_event(
636 event_mesh_provisioning_status_t *status)
638 int result = BLUETOOTH_ERROR_NONE;
639 BT_INFO("Mesh: Provisioning started");
641 __bt_mesh_handle_pending_request_info(result,
642 BT_MESH_NETWORK_PROVISION_DEVICE,
643 status, sizeof(event_mesh_provisioning_status_t));
645 _bt_mesh_set_provisioning_state(true);
648 static void __handle_mesh_network_provisioning_failed_event(
649 event_mesh_provisioning_status_t *status)
651 int result = BLUETOOTH_ERROR_INTERNAL;
652 BT_INFO("Mesh: Provisioning failed!!");
653 __bt_mesh_handle_pending_request_info(result,
654 BT_MESH_NETWORK_PROVISION_DEVICE,
655 status, sizeof(event_mesh_provisioning_status_t));
657 _bt_mesh_set_provisioning_state(false);
660 static void __handle_mesh_network_provisioning_finished_event(
661 event_mesh_provisioning_finished_t *event)
663 GVariant *out_var = NULL, *param = NULL;
665 bluetooth_mesh_provisioning_result_t prov_result;
666 BT_INFO("Mesh: Provisioning Finished!");
668 memset(&prov_result, 0x00,
669 sizeof(bluetooth_mesh_provisioning_result_t));
671 if (event->status != OAL_STATUS_SUCCESS)
672 prov_result.result = BLUETOOTH_ERROR_INTERNAL;
674 prov_result.result = BLUETOOTH_ERROR_NONE;
676 prov_result.reason = event->reason;
677 prov_result.unicast = event->unicast;
678 prov_result.count = event->count;
680 _bt_mesh_util_convert_hex_to_string(
681 (uint8_t *) event->net_uuid.uuid, 16, prov_result.net_uuid,
682 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
684 _bt_mesh_util_convert_hex_to_string(
685 (uint8_t *) event->dev_uuid.uuid, 16, prov_result.dev_uuid,
686 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
688 info = g_array_new(FALSE, FALSE, sizeof(gchar));
689 g_array_append_vals(info, &prov_result,
690 sizeof(bluetooth_mesh_provisioning_result_t));
692 out_var = g_variant_new_from_data((const GVariantType *)"ay",
693 info->data, info->len,
696 param = g_variant_new("(iv)", prov_result.result, out_var);
697 _bt_send_event(BT_MESH_EVENT,
698 BLUETOOTH_EVENT_MESH_PROVISIONING_FINISHED,
701 /* Add Remote Node entry in Local CDB */
702 if (event->status == OAL_STATUS_SUCCESS) {
703 BT_INFO("Mesh: Provisioning done, add node to Network");
704 BT_INFO("Mesh: Node UUID [%s]", prov_result.dev_uuid);
705 BT_INFO("Mesh: Node Unicast[0x%2.2x] Element Count [%d]",
706 event->unicast, event->count);
708 _bt_mesh_network_add_remote_node(
709 event->net_uuid.uuid, event->dev_uuid.uuid,
710 event->unicast, event->count);
712 /* Unset provisioning state */
713 _bt_mesh_set_provisioning_state(false);
716 static void __handle_mesh_network_provisioning_data_requested_event(
717 event_mesh_provisioning_data_requested_t *event)
719 _bt_mesh_network_request_provisioning_data_request(
720 event->net_uuid.uuid, event->count);
723 static void __handle_mesh_network_authentication_requested_event(
724 event_mesh_authentication_requested_t *event)
726 GVariant *out_var = NULL, *param = NULL;
728 bluetooth_mesh_authentication_request_t auth_req;
730 memset(&auth_req, 0x00,
731 sizeof(bluetooth_mesh_authentication_request_t));
733 auth_req.auth_type = event->auth_type;
734 g_strlcpy(auth_req.auth_value, event->auth_value,
735 sizeof(auth_req.auth_value));
737 _bt_mesh_util_convert_hex_to_string(
738 (uint8_t *) event->net_uuid.uuid, 16, auth_req.net_uuid,
739 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
741 BT_INFO("Mesh: Authentication Requested by Device: Network [%s]",
743 info = g_array_new(FALSE, FALSE, sizeof(gchar));
744 g_array_append_vals(info, &auth_req,
745 sizeof(bluetooth_mesh_authentication_request_t));
747 out_var = g_variant_new_from_data((const GVariantType *)"ay",
748 info->data, info->len,
751 param = g_variant_new("(iv)", BLUETOOTH_ERROR_NONE, out_var);
752 _bt_send_event(BT_MESH_EVENT,
753 BLUETOOTH_EVENT_MESH_AUTHENTICATION_REQUEST,
757 static void __handle_mesh_network_scan_result_event(
758 event_mesh_scan_result_t *event)
760 GVariant *out_var = NULL, *param = NULL;
762 bluetooth_mesh_scan_result_t data;
763 int result = BLUETOOTH_ERROR_NONE;
765 memset(&data, 0x00, sizeof(bluetooth_mesh_scan_result_t));
767 /* Fill Network UUID */
768 _bt_mesh_util_convert_hex_to_string(
769 (uint8_t *) event->net_uuid.uuid, 16, data.net_uuid,
770 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
772 /* Fill Device UUID */
773 _bt_mesh_util_convert_hex_to_string(
774 (uint8_t *) event->result.dev_uuid.uuid, 16, data.dev_uuid,
775 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
778 data.rssi = event->result.rssi;
781 memcpy(&data.oob_info, event->result.oob_info, 2);
783 /* Fill URI Hash Info */
784 memcpy(&data.uri_hash, event->result.uri_hash, 4);
786 if (event->status != OAL_STATUS_SUCCESS)
787 result = BLUETOOTH_ERROR_INTERNAL;
790 info = g_array_new(FALSE, FALSE, sizeof(gchar));
791 g_array_append_vals(info, &data,
792 sizeof(bluetooth_mesh_scan_result_t));
794 out_var = g_variant_new_from_data((const GVariantType *)"ay",
795 info->data, info->len,
798 param = g_variant_new("(iv)", result, out_var);
799 _bt_send_event(BT_MESH_EVENT,
800 BLUETOOTH_EVENT_MESH_SCAN_RESULT,
804 static void __handle_mesh_events(int event_type,
807 BT_INFO("Mesh: Got Mesh event!!! event type [%d]", event_type);
808 if (event_type == OAL_EVENT_MESH_PROVISIONING_STARTED)
809 BT_INFO("Mesh: Provisioning started event");
811 switch (event_type) {
812 case OAL_EVENT_MESH_NETWORK_PROXY_ADDED:
813 __handle_mesh_network_proxy_added_event(
814 (event_mesh_network_proxy_added_t*)event_data);
815 BT_PERMANENT_LOG("Mesh: Network proxy added!!");
817 case OAL_EVENT_MESH_NETWORK_ATTACHED:
818 __handle_mesh_network_attached_event(
819 (event_mesh_network_attached_t*)event_data);
820 BT_PERMANENT_LOG("Mesh: Network attached!!");
822 case OAL_EVENT_MESH_NETWORK_DESTROYED:
823 __handle_mesh_network_destroyed_event(
824 (event_mesh_network_destroyed_t*)event_data);
825 BT_PERMANENT_LOG("Mesh: Network Destroyed!!");
827 case OAL_EVENT_MESH_SCAN_STARTED:
828 __handle_mesh_network_scan_started_event(
829 (event_mesh_scan_status_t*)event_data);
830 BT_PERMANENT_LOG("Mesh: Network Scan Stated!!");
832 case OAL_EVENT_MESH_SCAN_FINISHED:
833 __handle_mesh_network_scan_finished_event(
834 (event_mesh_scan_status_t*)event_data);
835 BT_PERMANENT_LOG("Mesh: Network Scan Finished!!");
837 case OAL_EVENT_MESH_SCAN_RESULT:
838 __handle_mesh_network_scan_result_event(
839 (event_mesh_scan_result_t*)event_data);
840 BT_PERMANENT_LOG("Mesh: Network Scan Result!!");
842 case OAL_EVENT_MESH_PROVISIONING_STARTED:
843 BT_INFO("Mesh: Network Provisioning Started");
844 __handle_mesh_network_provisioning_started_event(
845 (event_mesh_provisioning_status_t*)event_data);
846 BT_PERMANENT_LOG("Mesh: Network Provisioning Started");
848 case OAL_EVENT_MESH_PROVISIONING_FAILED:
849 BT_INFO("Mesh: Network Provisioning Failed!!!!");
850 __handle_mesh_network_provisioning_failed_event(
851 (event_mesh_provisioning_status_t*)event_data);
852 BT_PERMANENT_LOG("Mesh: Network Provisioning Failed");
854 case OAL_EVENT_MESH_PROVISIONING_FINISHED:
855 __handle_mesh_network_provisioning_finished_event(
856 (event_mesh_provisioning_finished_t*)event_data);
857 BT_PERMANENT_LOG("Mesh: Network Provisioning Finished");
859 case OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED:
860 __handle_mesh_network_provisioning_data_requested_event(
861 (event_mesh_provisioning_data_requested_t*)event_data);
862 BT_PERMANENT_LOG("Mesh: Network Provisioning Data Requested");
864 case OAL_EVENT_MESH_AUTHENTICATION_REQUESTED:
865 __handle_mesh_network_authentication_requested_event(
866 (event_mesh_authentication_requested_t*)event_data);
867 BT_PERMANENT_LOG("Mesh: Network Authentication Requested");
869 case OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT:
870 __handle_mesh_network_subnet_operation_event(
871 (event_mesh_netkey_operation_t*)event_data);
872 BT_PERMANENT_LOG("Mesh: Network Subnet operation event");
874 case OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT:
875 __handle_mesh_network_appkey_operation_event(
876 (event_mesh_appkey_operation_t*)event_data);
877 BT_PERMANENT_LOG("Mesh: AppKey operation event");
879 case OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED:
880 __handle_mesh_devkey_message_received_event(
881 (event_mesh_devkey_message_t*)event_data);
882 BT_PERMANENT_LOG("Mesh: DevKey Message Received event");
884 case OAL_EVENT_MESH_MODEL_MESSAGE_RECEIVED:
885 __handle_mesh_message_received_event(
886 (event_mesh_message_t*)event_data);
887 BT_PERMANENT_LOG("Mesh: Model Message Received event");
894 static int __bt_mesh_enable()
896 oal_status_t status = OAL_STATUS_SUCCESS;
897 BT_INFO("Mesh: Set dbus callbacks");
898 status = mesh_enable();
899 if (OAL_STATUS_SUCCESS != status &&
900 OAL_STATUS_ALREADY_DONE != status) {
901 BT_ERR("Mesh: Failed to enable mesh interface, status: %d",
903 return BLUETOOTH_ERROR_INTERNAL;
905 BT_INFO("Mesh: Stack Initialization Done successfully: status [%d]",
908 /* Register MESH event handler */
909 _bt_service_register_event_handler_callback(BT_MESH_MODULE,
910 __handle_mesh_events);
912 return (status == OAL_STATUS_SUCCESS ? BLUETOOTH_ERROR_NONE : \
913 BLUETOOTH_ERROR_ALREADY_INITIALIZED);
916 static gboolean __bt_mesh_launch_timer_expired_cb(gpointer data)
918 BT_INFO("Mesh: Enable Mesh dbus");
919 int ret = BLUETOOTH_ERROR_NONE;
920 ret = __bt_mesh_enable();
921 if (BLUETOOTH_ERROR_NONE != ret &&
922 BLUETOOTH_ERROR_ALREADY_INITIALIZED != ret)
923 BT_ERR("Mesh: Mesh enable failed: %d", ret);
925 /* Reset launch timer ID */
926 BT_INFO("Mesh: Timer ID after expiry [%u]", launch_timer);
932 static void __bt_mesh_init_wait_response_timeout(
933 struct l_timeout *timeout, void *user_data)
935 int result = BLUETOOTH_ERROR_TIMEOUT;
937 /* Handle DBUS Context return */
938 BT_INFO("Mesh: Handle DBUS Context return");
939 __bt_mesh_handle_pending_request_info(result,
942 l_timeout_remove(wait_timer);
945 int _bt_mesh_init(const char *sender)
947 int ret = BLUETOOTH_ERROR_NONE;
949 BT_INFO("Mesh: Total apps using Mesh: [%d]",
952 BT_INFO("Mesh: Mesh App Sender [%s]", sender);
954 BT_INFO("Mesh: Current Timer ID [%u]", launch_timer);
955 if (launch_timer > 0) {
956 BT_INFO("Mesh: BT_MESH_INIT in progress");
960 if (mesh_app_ref_count) {
961 BT_INFO("Mesh: Mesh Stack already initialized");
963 /* Save Mesh App Owner */
964 apps = g_slist_append(apps, g_strdup(sender));
966 /* Increase mesh app ref count */
967 mesh_app_ref_count++;
968 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
971 BT_INFO("Mesh: Mesh Stack init not done yet!");
972 /* Launch bluetooth-meshd */
973 ret = __bt_meshd_launch();
974 if (BLUETOOTH_ERROR_NONE != ret) {
975 BT_ERR("Mesh: Meshd launch failed: %d", ret);
979 /* wait for half a second*/
980 launch_timer = g_timeout_add(MESH_LAUNCH_DELAY,
981 (GSourceFunc)__bt_mesh_launch_timer_expired_cb,
983 BT_INFO("Mesh: Timer ID [%u]", launch_timer);
985 /* Add mesh init request timeout */
986 wait_timer = l_timeout_create(MESH_DEFAULT_RESPONSE_TIMEOUT,
987 __bt_mesh_init_wait_response_timeout, NULL, NULL);
992 static gint __bt_mesh_match_sender(gconstpointer a, gconstpointer b)
994 char *owner_a = (char*) a;
995 char *owner_b = (char*) b;
997 return g_strcmp0(owner_a, owner_b);
1000 int _bt_mesh_deinit(const char *sender)
1005 BT_INFO("Mesh: Deinit Request from App [%s]", sender);
1006 BT_INFO("Mesh: Total Apps available in list [%d]",
1007 g_slist_length(apps));
1009 /* Find & remove app entry from list */
1010 l = g_slist_find_custom(apps, sender,
1011 (GCompareFunc)__bt_mesh_match_sender);
1013 BT_ERR("Mesh: App is not Mesh App");
1014 return BLUETOOTH_ERROR_INTERNAL;
1017 BT_INFO("Mesh: Deinit Mesh: Sender Found: [%s]", sender);
1019 if (launch_timer > 0) {
1020 g_source_remove(launch_timer);
1024 BT_INFO("Mesh: Current number of applications using mesh [%d]",
1025 mesh_app_ref_count);
1027 if (mesh_app_ref_count == 1) {
1028 BT_INFO("Mesh: Only one app using Mesh Stack: Unload & reduce ref count");
1030 /* Terminate bluetooth-mesh */
1031 __bt_mesh_terminate();
1034 /* Decrease mesh app ref count */
1035 mesh_app_ref_count--;
1038 apps = g_slist_remove(apps, owner);
1041 _bt_mesh_deinitialized();
1043 return BLUETOOTH_ERROR_NONE;
1046 void _bt_mesh_handle_app_termination(const char *sender)
1048 BT_INFO("Mesh: Handle App termination: dbus app name[%s]",
1051 _bt_mesh_deinit(sender);