Mesh: Handle Multi-application init & deinit logic
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / mesh / bt-service-mesh-main.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
5  *
6  * @author: Anupam Roy <anupam.r@samsung.com>
7  *
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
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21 #include <dirent.h>
22 #include <ftw.h>
23 #include <unistd.h>
24 #include <stdio.h>
25
26 #include <glib.h>
27 #include <dlog.h>
28 #include <limits.h>
29 #include <time.h>
30 #include <sys/time.h>
31 #include <ell/ell.h>
32 #include <actd/unit_control.h>
33
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"
40
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
47 #include <oal-mesh.h>
48
49 #define MESH_SYSTEMD_SERVICE_NAME "bluetooth-mesh.service"
50 #define MESH_LAUNCH_DELAY 500
51
52 static guint launch_timer = 0;
53 static guint mesh_app_ref_count;
54
55 /* Event handlers */
56 static void __bt_mesh_handle_pending_request_info(int result,
57                 int service_function, void *param,
58                         unsigned int size)
59 {
60         GSList *l;
61         GArray *out_param;
62         invocation_info_t *req_info = NULL;
63
64         for (l = _bt_get_invocation_list(); l != NULL; ) {
65                 req_info = l->data;
66                 l = g_slist_next(l);
67                 if (req_info == NULL ||
68                         req_info->service_function != service_function)
69                         continue;
70
71                 switch (service_function) {
72                 case BT_MESH_INIT: {
73                         BT_INFO("Mesh: Request: BT_MESH_INIT Sender: [%s] result[%d]",
74                                         req_info->sender, result);
75
76                         if (result == BLUETOOTH_ERROR_NONE)
77                                 /* Increase mesh app ref count */
78                                 mesh_app_ref_count++;
79
80                         out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
81                         _bt_service_method_return(req_info->context,
82                                 out_param, result);
83                         _bt_free_info_from_invocation_list(req_info);
84                         break;
85                 }
86                 case BT_MESH_NETWORK_CREATE: {
87                         char uuid_str[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
88                         bluetooth_mesh_node_t *node;
89                         bluetooth_mesh_network_t *network;
90                         ret_if(param == NULL);
91                         BT_INFO("Mesh: Request: BT_MESH_NETWORK_CREATE Sender: [%s] result[%d]",
92                                         req_info->sender, result);
93
94                         node = (bluetooth_mesh_node_t*) param;
95                         network = (bluetooth_mesh_network_t*)req_info->user_data;
96
97                         _bt_mesh_util_convert_hex_to_string(
98                                 (uint8_t *) node->uuid, 16, uuid_str,
99                                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
100
101                         BT_INFO("Mesh: Network UUID from event [%s] Netw UUID from req [%s]",
102                                         uuid_str, network->uuid);
103
104                         if (!g_strcmp0(network->uuid, uuid_str)) {
105                                 BT_INFO("Mesh: BT_MESH_NETWORK_CREATE Request found uuid [%s]",
106                                         network->uuid);
107                                 if (BLUETOOTH_ERROR_NONE != _bt_mesh_network_create_cdb(
108                                         result, req_info->sender,
109                                         network->app_cred, node->uuid,
110                                                 node->token.u8, network->name.name)) {
111                                         result = BLUETOOTH_ERROR_INTERNAL;
112                                         BT_ERR("!!Mesh: BT_MESH_NETWORK_CREATE Failed!!");
113                                 }
114
115                                 _bt_mesh_util_convert_hex_to_string(
116                                         (uint8_t *) node->token.u8, 8,
117                                                 network->token.token,
118                                                 BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
119
120                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
121                                 g_array_append_vals(out_param, network,
122                                         sizeof(bluetooth_mesh_network_t));
123                                 _bt_service_method_return(req_info->context,
124                                         out_param, result);
125                                 _bt_free_info_from_invocation_list(req_info);
126                                 g_array_free(out_param, TRUE);
127                         }
128                         break;
129                 }
130                 case BT_MESH_NETWORK_DESTROY: {
131                         bluetooth_mesh_network_t *event;
132                         bluetooth_mesh_network_t *network;
133                         ret_if(param == NULL);
134                         BT_INFO("Mesh: Request: BT_MESH_NETWORK_DESTROY Sender: [%s] result[%d]",
135                                         req_info->sender, result);
136
137                         event = (bluetooth_mesh_network_t*) param;
138                         network = (bluetooth_mesh_network_t*)req_info->user_data;
139
140                         BT_INFO("Mesh: Network UUID from event [%s] Net UUID from req [%s]",
141                                         event->uuid, network->uuid);
142
143                         if (!g_strcmp0(network->uuid, event->uuid)) {
144                                 BT_INFO("Mesh: BT_MESH_NETWORK_DESTROY Request found uuid [%s]",
145                                         network->uuid);
146
147                                 result = _bt_mesh_network_remove_net_configuration(network);
148
149                                 BT_INFO("Mesh: Return Invocation for BT_MESH_NETWORK_DESTROY");
150                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
151                                 g_array_append_vals(out_param, network,
152                                         sizeof(bluetooth_mesh_network_t));
153                                 _bt_service_method_return(req_info->context,
154                                         out_param, result);
155                                 _bt_free_info_from_invocation_list(req_info);
156                                 g_array_free(out_param, TRUE);
157                         }
158                         break;
159                 }
160                 case BT_MESH_NETWORK_LOAD: {
161                         char token_str[BLUETOOTH_MESH_NETWORK_TOKEN_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_LOAD Sender: [%s]",
166                                 req_info->sender);
167
168                         node = (bluetooth_mesh_node_t*) param;
169                         network = (bluetooth_mesh_network_t*)req_info->user_data;
170
171                         _bt_mesh_util_convert_hex_to_string(
172                                 (uint8_t *) node->token.u8, 8, token_str,
173                                         BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
174
175                         if (!g_strcmp0(network->token.token, token_str)) {
176                                 char *network_name = NULL;
177                                 BT_INFO("Mesh: BT_MESH_NETWORK_LOAD Request found Token [%s]",
178                                         token_str);
179
180                                 /* Send request to mesh-network to load keys and Nodes for the network */
181                                 if (BLUETOOTH_ERROR_NONE == _bt_mesh_network_load_cdb(
182                                                 result, req_info->sender, network->app_cred,
183                                                         node->uuid, node->token.u8, &network_name)) {
184                                         g_strlcpy(network->name.name, network_name, strlen(network_name));
185                                 } else
186                                         BT_ERR("!!Mesh: BT_MESH_NETWORK_LOAD Failed!!");
187
188                                 _bt_mesh_util_convert_hex_to_string((uint8_t *) node->uuid, 16, network->uuid,
189                                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
190
191                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
192                                 g_array_append_vals(out_param, network, sizeof(bluetooth_mesh_network_t));
193                                 _bt_service_method_return(req_info->context, out_param, result);
194                                 _bt_free_info_from_invocation_list(req_info);
195                                 g_array_free(out_param, TRUE);
196                         }
197                         break;
198                 }
199                 case BT_MESH_NETWORK_SCAN: {
200                         bluetooth_mesh_network_t *network;
201                         event_mesh_scan_status_t *event;
202                         char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
203
204                         event = (event_mesh_scan_status_t*) param;
205                         network = (bluetooth_mesh_network_t*)req_info->user_data;
206                         _bt_mesh_util_convert_hex_to_string(
207                                 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
208                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
209
210                         BT_DBG("Request Sender: [%s]", req_info->sender);
211                         if (!g_strcmp0(network->uuid, net_uuid)) {
212                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
213                                 g_array_append_vals(out_param,
214                                         network, sizeof(bluetooth_mesh_network_t));
215                                 _bt_service_method_return(req_info->context,
216                                         out_param, result);
217                                 _bt_free_info_from_invocation_list(req_info);
218                                 g_array_free(out_param, TRUE);
219                         }
220                         break;
221                 }
222                 case BT_MESH_NETWORK_PROVISION_DEVICE: {
223                         bluetooth_mesh_provisioning_request_t *req_data;
224                         bluetooth_mesh_provisioning_request_t status_data;
225                         event_mesh_provisioning_status_t *event;
226                         memset(&status_data,
227                                 0x00, sizeof(bluetooth_mesh_provisioning_request_t));
228
229                         event = (event_mesh_provisioning_status_t*) param;
230                         req_data = (bluetooth_mesh_provisioning_request_t*) req_info->user_data;
231
232                         _bt_mesh_util_convert_hex_to_string(
233                                 (uint8_t *) event->net_uuid.uuid, 16, status_data.net_uuid,
234                                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
235
236                         _bt_mesh_util_convert_hex_to_string(
237                                 (uint8_t *) event->dev_uuid.uuid, 16, status_data.dev_uuid,
238                                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
239                         BT_INFO("Mesh: Provision Status: Device UUID [%s]", status_data.dev_uuid);
240                         BT_INFO("Mesh: Provision Status: Net UUID [%s]", status_data.net_uuid);
241                         BT_INFO("Mesh: Provision Status: Result [%d]", event->status);
242                         if (event->status == OAL_STATUS_SUCCESS)
243                                 BT_INFO("Mesh: Provisioning status : SUCCESS");
244                         else
245                                 BT_INFO("Mesh: Provisioning status : FAIL");
246
247                         BT_DBG("Request Sender: [%s]", req_info->sender);
248                         if (!g_strcmp0(req_data->net_uuid, status_data.net_uuid)) {
249                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
250                                 g_array_append_vals(out_param, &status_data,
251                                         sizeof(bluetooth_mesh_provisioning_request_t));
252                                 _bt_service_method_return(req_info->context, out_param, result);
253                                 _bt_free_info_from_invocation_list(req_info);
254                                 g_array_free(out_param, TRUE);
255                         }
256                         break;
257                 }
258                 /* Fall through */
259                 case BT_MESH_NETWORK_DELETE_NETKEY:
260                 case BT_MESH_NETWORK_UPDATE_NETKEY:
261                 case BT_MESH_NETWORK_ADD_NETKEY: {
262                         bluetooth_mesh_network_t *network;
263                         event_mesh_netkey_operation_t *event;
264                         char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
265
266                         event = (event_mesh_netkey_operation_t*) param;
267                         network = (bluetooth_mesh_network_t*)req_info->user_data;
268                         _bt_mesh_util_convert_hex_to_string(
269                                 (uint8_t *) event->net_uuid.uuid, 16, net_uuid,
270                                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
271
272                         BT_DBG("Request Sender: [%s]", req_info->sender);
273                         if (!g_strcmp0(network->uuid, net_uuid)) {
274                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
275                                 g_array_append_vals(out_param, &event->key_idx, sizeof(guint16));
276                                 _bt_service_method_return(req_info->context, out_param, result);
277                                 _bt_free_info_from_invocation_list(req_info);
278                                 g_array_free(out_param, TRUE);
279                         }
280                         break;
281                 }
282                 /* Fall through */
283                 case BT_MESH_NETWORK_DELETE_APPKEY:
284                 case BT_MESH_NETWORK_UPDATE_APPKEY:
285                 case BT_MESH_NETWORK_ADD_APPKEY: {
286                         bluetooth_mesh_network_t *network;
287                         event_mesh_appkey_operation_t *event;
288                         char net_uuid[BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1];
289
290                         event = (event_mesh_appkey_operation_t*) param;
291                         network = (bluetooth_mesh_network_t*)req_info->user_data;
292                         _bt_mesh_util_convert_hex_to_string((uint8_t *) event->net_uuid.uuid, 16, net_uuid,
293                                 BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
294
295                         BT_DBG("Request Sender: [%s]", req_info->sender);
296                         if (!g_strcmp0(network->uuid, net_uuid)) {
297                                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
298                                 g_array_append_vals(out_param, &event->app_idx, sizeof(guint16));
299                                 _bt_service_method_return(req_info->context, out_param, result);
300                                 _bt_free_info_from_invocation_list(req_info);
301                                 g_array_free(out_param, TRUE);
302                         }
303                         break;
304                 }
305                 default:
306                         BT_DBG("Unknown function(%d)", service_function);
307                         break;
308                 }
309         }
310 }
311
312 static void __handle_mesh_network_subnet_operation_event(
313                 event_mesh_netkey_operation_t *event)
314 {
315         int result = BLUETOOTH_ERROR_NONE;
316
317         if (event->status != OAL_STATUS_SUCCESS)
318                 result = BLUETOOTH_ERROR_INTERNAL;
319
320         /* Handle DBUS Context return */
321         if (event->op == OAL_MESH_KEY_ADD) {
322                 if (result == BLUETOOTH_ERROR_NONE)
323                         _bt_mesh_network_handle_netkey_added(event->net_uuid.uuid, event->key_idx);
324
325                 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_ADD_NETKEY,
326                                 event, sizeof(event_mesh_netkey_operation_t));
327         } else if (event->op == OAL_MESH_KEY_DELETE) {
328                 if (result == BLUETOOTH_ERROR_NONE)
329                         _bt_mesh_network_handle_netkey_deleted(event->net_uuid.uuid, event->key_idx);
330
331                 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_DELETE_NETKEY,
332                                 event, sizeof(event_mesh_netkey_operation_t));
333         } else if (event->op == OAL_MESH_KEY_UPDATE) {
334                 _bt_mesh_network_handle_netkey_updated(event->net_uuid.uuid, event->key_idx);
335
336                 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_UPDATE_NETKEY,
337                                 event, sizeof(event_mesh_netkey_operation_t));
338         }
339 }
340
341 static void __handle_mesh_network_appkey_operation_event(
342                         event_mesh_appkey_operation_t *event)
343 {
344         int result = BLUETOOTH_ERROR_NONE;
345
346         if (event->status != OAL_STATUS_SUCCESS)
347                 result = BLUETOOTH_ERROR_INTERNAL;
348         /* Handle DBUS Context return */
349         if (event->op == OAL_MESH_KEY_ADD) {
350                 BT_INFO("Mesh: Appkey Add event");
351                 if (result == BLUETOOTH_ERROR_NONE)
352                         _bt_mesh_network_handle_appkey_added(
353                                         event->net_uuid.uuid, event->net_idx, event->app_idx);
354
355                 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_ADD_APPKEY,
356                                 event, sizeof(event_mesh_netkey_operation_t));
357         } else if (event->op == OAL_MESH_KEY_DELETE) {
358                 BT_INFO("Mesh: Appkey Delete event");
359                 if (result == BLUETOOTH_ERROR_NONE)
360                         _bt_mesh_network_handle_appkey_deleted(
361                                         event->net_uuid.uuid, event->net_idx, event->app_idx);
362
363                 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_DELETE_APPKEY,
364                                 event, sizeof(event_mesh_netkey_operation_t));
365         } else if (event->op == OAL_MESH_KEY_UPDATE) {
366                 BT_INFO("Mesh: Appkey Update event");
367                 __bt_mesh_handle_pending_request_info(result, BT_MESH_NETWORK_UPDATE_APPKEY,
368                                 event, sizeof(event_mesh_netkey_operation_t));
369         }
370 }
371
372 static void  __handle_mesh_devkey_message_received_event(
373                 event_mesh_devkey_message_t *event)
374 {
375         _bt_mesh_config_client_devkey_msg_handler(event);
376 }
377
378 static void  __handle_mesh_message_received_event(
379                 event_mesh_message_t *event)
380 {
381         _bt_mesh_msg_handler(event);
382 }
383
384 static void __handle_mesh_network_attached_event(
385                 event_mesh_network_attached_t *event)
386 {
387         int result = BLUETOOTH_ERROR_NONE;
388         bluetooth_mesh_node_t node;
389
390         if (event->status != OAL_STATUS_SUCCESS)
391                 result = BLUETOOTH_ERROR_INTERNAL;
392
393         memset(&node, 0x00, sizeof(bluetooth_mesh_node_t));
394
395         memcpy(node.uuid, event->uuid.uuid, 16);
396         memcpy(node.token.u8, event->token, 8);
397
398         __bt_mesh_handle_pending_request_info(result,
399                         BT_MESH_NETWORK_CREATE,
400                         &node, sizeof(bluetooth_mesh_node_t));
401         __bt_mesh_handle_pending_request_info(result,
402                         BT_MESH_NETWORK_LOAD,
403                         &node, sizeof(bluetooth_mesh_node_t));
404 }
405
406 static void __handle_mesh_network_destroyed_event(
407                 event_mesh_network_destroyed_t *event)
408 {
409         int result = BLUETOOTH_ERROR_NONE;
410         bluetooth_mesh_network_t network;
411
412         if (event->status != OAL_STATUS_SUCCESS) {
413                 BT_INFO("Mesh: Network Destroyed Event: result is Failed!");
414                 result = BLUETOOTH_ERROR_INTERNAL;
415         } else {
416                 BT_INFO("Mesh: Network Destroyed Event: result is Success!");
417         }
418
419         memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
420         _bt_mesh_util_convert_hex_to_string(
421                         (uint8_t *) event->uuid.uuid, 16, network.uuid,
422                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
423         _bt_mesh_util_convert_hex_to_string(
424                         (uint8_t *) event->token, 8, network.token.token,
425                         BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
426
427         __bt_mesh_handle_pending_request_info(result,
428                         BT_MESH_NETWORK_DESTROY,
429                         &network, sizeof(bluetooth_mesh_network_t));
430 }
431
432 static void __handle_mesh_network_scan_started_event(
433         event_mesh_scan_status_t *event)
434 {
435         GVariant *out_var = NULL, *param = NULL;
436         GArray *info = NULL;
437         bluetooth_mesh_network_t network;
438
439         int result = BLUETOOTH_ERROR_NONE;
440         if (event->status != OAL_STATUS_SUCCESS) {
441                 result = BLUETOOTH_ERROR_INTERNAL;
442                 _bt_mesh_set_scanning_state(false);
443         } else
444                 _bt_mesh_set_scanning_state(true);
445
446         /* Handle DBUS Context return */
447         __bt_mesh_handle_pending_request_info(result,
448                         BT_MESH_NETWORK_SCAN,
449                         event, sizeof(event_mesh_scan_status_t));
450
451         /* Handle Scan started event */
452         if (result == BLUETOOTH_ERROR_NONE) {
453                 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
454                 _bt_mesh_util_convert_hex_to_string(
455                         (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
456                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
457
458                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
459                 g_array_append_vals(info, &network,
460                         sizeof(bluetooth_mesh_network_t));
461
462                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
463                         info->data, info->len,
464                         TRUE, NULL, NULL);
465
466                 param = g_variant_new("(iv)", result, out_var);
467                 _bt_send_event(BT_MESH_EVENT,
468                         BLUETOOTH_EVENT_MESH_SCAN_STARTED,
469                         param);
470         }
471 }
472
473 static void __handle_mesh_network_scan_finished_event(
474         event_mesh_scan_status_t *event)
475 {
476         GVariant *out_var = NULL, *param = NULL;
477         GArray *info = NULL;
478         bluetooth_mesh_network_t network;
479         int result = BLUETOOTH_ERROR_NONE;
480         if (event->status != OAL_STATUS_SUCCESS) {
481                 BT_INFO("Mesh: Scan Finished: status:: FAILED!");
482                 result = BLUETOOTH_ERROR_INTERNAL;
483         } else
484                 BT_INFO("Mesh: Scan Finished: status:: SUCCESS!");
485
486         /* Handle Scan finsihed event */
487         if (result == BLUETOOTH_ERROR_NONE) {
488                 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
489                 _bt_mesh_util_convert_hex_to_string(
490                         (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
491                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
492
493                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
494                 g_array_append_vals(info, &network,
495                         sizeof(bluetooth_mesh_network_t));
496
497                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
498                         info->data, info->len,
499                         TRUE, NULL, NULL);
500
501                 param = g_variant_new("(iv)", result, out_var);
502                 _bt_send_event(BT_MESH_EVENT,
503                         BLUETOOTH_EVENT_MESH_SCAN_FINISHED,
504                         param);
505                 _bt_mesh_set_scanning_state(false);
506         }
507 }
508
509 static void __handle_mesh_network_provisioning_started_event(
510                 event_mesh_provisioning_status_t *status)
511 {
512         int result = BLUETOOTH_ERROR_NONE;
513         BT_INFO("Mesh: Provisioning started");
514
515         __bt_mesh_handle_pending_request_info(result,
516                         BT_MESH_NETWORK_PROVISION_DEVICE,
517                         status, sizeof(event_mesh_provisioning_status_t));
518
519         _bt_mesh_set_provisioning_state(true);
520 }
521
522 static void __handle_mesh_network_provisioning_failed_event(
523                 event_mesh_provisioning_status_t *status)
524 {
525         int result = BLUETOOTH_ERROR_INTERNAL;
526         BT_INFO("Mesh: Provisioning failed!!");
527         __bt_mesh_handle_pending_request_info(result,
528                         BT_MESH_NETWORK_PROVISION_DEVICE,
529                         status, sizeof(event_mesh_provisioning_status_t));
530
531         _bt_mesh_set_provisioning_state(false);
532 }
533
534 static void __handle_mesh_network_provisioning_finished_event(
535                 event_mesh_provisioning_finished_t *event)
536 {
537         GVariant *out_var = NULL, *param = NULL;
538         GArray *info = NULL;
539         bluetooth_mesh_provisioning_result_t prov_result;
540         BT_INFO("Mesh: Provisioning Finished!");
541
542         memset(&prov_result, 0x00,
543                         sizeof(bluetooth_mesh_provisioning_result_t));
544
545         if (event->status != OAL_STATUS_SUCCESS)
546                 prov_result.result = BLUETOOTH_ERROR_INTERNAL;
547         else
548                 prov_result.result = BLUETOOTH_ERROR_NONE;
549
550         prov_result.reason = event->reason;
551         prov_result.unicast = event->unicast;
552         prov_result.count = event->count;
553
554         _bt_mesh_util_convert_hex_to_string(
555                         (uint8_t *) event->net_uuid.uuid, 16, prov_result.net_uuid,
556                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
557
558         _bt_mesh_util_convert_hex_to_string(
559                         (uint8_t *) event->dev_uuid.uuid, 16, prov_result.dev_uuid,
560                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
561
562         info = g_array_new(FALSE, FALSE, sizeof(gchar));
563         g_array_append_vals(info, &prov_result,
564                         sizeof(bluetooth_mesh_provisioning_result_t));
565
566         out_var = g_variant_new_from_data((const GVariantType *)"ay",
567                         info->data, info->len,
568                         TRUE, NULL, NULL);
569
570         param = g_variant_new("(iv)", prov_result.result, out_var);
571         _bt_send_event(BT_MESH_EVENT,
572                         BLUETOOTH_EVENT_MESH_PROVISIONING_FINISHED,
573                         param);
574
575         /* Add Remote Node entry in Local CDB */
576         if (event->status == OAL_STATUS_SUCCESS) {
577                 BT_INFO("Mesh: Provisioning done, add node to Network");
578                 BT_INFO("Mesh: Node UUID [%s]", prov_result.dev_uuid);
579                 BT_INFO("Mesh: Node Unicast[0x%2.2x] Element Count [%d]",
580                         event->unicast, event->count);
581
582                 _bt_mesh_network_add_remote_node(
583                         event->net_uuid.uuid, event->dev_uuid.uuid,
584                                 event->unicast, event->count);
585         }
586         /* Unset provisioning state */
587         _bt_mesh_set_provisioning_state(false);
588 }
589
590 static void __handle_mesh_network_provisioning_data_requested_event(
591         event_mesh_provisioning_data_requested_t *event)
592 {
593         _bt_mesh_network_request_provisioning_data_request(
594                         event->net_uuid.uuid, event->count);
595 }
596
597 static void __handle_mesh_network_authentication_requested_event(
598                 event_mesh_authentication_requested_t *event)
599 {
600         GVariant *out_var = NULL, *param = NULL;
601         GArray *info = NULL;
602         bluetooth_mesh_authentication_request_t auth_req;
603
604         memset(&auth_req, 0x00,
605                         sizeof(bluetooth_mesh_authentication_request_t));
606
607         auth_req.auth_type = event->auth_type;
608         g_strlcpy(auth_req.auth_value, event->auth_value,
609                         sizeof(auth_req.auth_value));
610
611         _bt_mesh_util_convert_hex_to_string(
612                         (uint8_t *) event->net_uuid.uuid, 16, auth_req.net_uuid,
613                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
614
615         BT_INFO("Mesh: Authentication Requested by Device: Network [%s]",
616                 auth_req.net_uuid);
617         info = g_array_new(FALSE, FALSE, sizeof(gchar));
618         g_array_append_vals(info, &auth_req,
619                         sizeof(bluetooth_mesh_authentication_request_t));
620
621         out_var = g_variant_new_from_data((const GVariantType *)"ay",
622                         info->data, info->len,
623                         TRUE, NULL, NULL);
624
625         param = g_variant_new("(iv)", BLUETOOTH_ERROR_NONE, out_var);
626         _bt_send_event(BT_MESH_EVENT,
627                         BLUETOOTH_EVENT_MESH_AUTHENTICATION_REQUEST,
628                         param);
629 }
630
631 static void __handle_mesh_network_scan_result_event(
632                 event_mesh_scan_result_t *event)
633 {
634         GVariant *out_var = NULL, *param = NULL;
635         GArray *info = NULL;
636         bluetooth_mesh_scan_result_t data;
637         int result = BLUETOOTH_ERROR_NONE;
638
639         memset(&data, 0x00, sizeof(bluetooth_mesh_scan_result_t));
640
641         /* Fill Network UUID */
642         _bt_mesh_util_convert_hex_to_string(
643                 (uint8_t *) event->net_uuid.uuid, 16, data.net_uuid,
644                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
645
646         /* Fill Device UUID */
647         _bt_mesh_util_convert_hex_to_string(
648                 (uint8_t *) event->result.dev_uuid.uuid, 16, data.dev_uuid,
649                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
650
651         /* Fill RSSI */
652         data.rssi = event->result.rssi;
653
654         /* Fill OOB Info */
655         memcpy(&data.oob_info, event->result.oob_info, 2);
656
657         /* Fill URI Hash Info */
658         memcpy(&data.uri_hash, event->result.uri_hash, 4);
659
660         if (event->status != OAL_STATUS_SUCCESS)
661                 result = BLUETOOTH_ERROR_INTERNAL;
662
663         /* Fill Data */
664         info = g_array_new(FALSE, FALSE, sizeof(gchar));
665         g_array_append_vals(info, &data,
666                 sizeof(bluetooth_mesh_scan_result_t));
667
668         out_var = g_variant_new_from_data((const GVariantType *)"ay",
669                         info->data, info->len,
670                         TRUE, NULL, NULL);
671
672         param = g_variant_new("(iv)", result, out_var);
673         _bt_send_event(BT_MESH_EVENT,
674                         BLUETOOTH_EVENT_MESH_SCAN_RESULT,
675                         param);
676 }
677
678 static void __handle_mesh_events(int event_type,
679                 gpointer event_data)
680 {
681         BT_INFO("Mesh: Got Mesh event!!! event type [%d]", event_type);
682         if (event_type == OAL_EVENT_MESH_PROVISIONING_STARTED)
683                 BT_INFO("Mesh: Provisioning started event");
684
685         switch (event_type) {
686         case OAL_EVENT_MESH_NETWORK_ATTACHED:
687                 __handle_mesh_network_attached_event(
688                         (event_mesh_network_attached_t*)event_data);
689                 BT_PERMANENT_LOG("Mesh: Network attached!!");
690                 break;
691         case OAL_EVENT_MESH_NETWORK_DESTROYED:
692                 __handle_mesh_network_destroyed_event(
693                         (event_mesh_network_destroyed_t*)event_data);
694                 BT_PERMANENT_LOG("Mesh: Network Destroyed!!");
695                 break;
696         case OAL_EVENT_MESH_SCAN_STARTED:
697                 __handle_mesh_network_scan_started_event(
698                         (event_mesh_scan_status_t*)event_data);
699                 BT_PERMANENT_LOG("Mesh: Network Scan Stated!!");
700                 break;
701         case OAL_EVENT_MESH_SCAN_FINISHED:
702                 __handle_mesh_network_scan_finished_event(
703                         (event_mesh_scan_status_t*)event_data);
704                 BT_PERMANENT_LOG("Mesh: Network Scan Finished!!");
705                 break;
706         case OAL_EVENT_MESH_SCAN_RESULT:
707                 __handle_mesh_network_scan_result_event(
708                         (event_mesh_scan_result_t*)event_data);
709                 BT_PERMANENT_LOG("Mesh: Network Scan Result!!");
710                 break;
711         case OAL_EVENT_MESH_PROVISIONING_STARTED:
712                 BT_INFO("Mesh: Network Provisioning Started");
713                 __handle_mesh_network_provisioning_started_event(
714                         (event_mesh_provisioning_status_t*)event_data);
715                 BT_PERMANENT_LOG("Mesh: Network Provisioning Started");
716                 break;
717         case OAL_EVENT_MESH_PROVISIONING_FAILED:
718                 BT_INFO("Mesh: Network Provisioning Failed!!!!");
719                 __handle_mesh_network_provisioning_failed_event(
720                         (event_mesh_provisioning_status_t*)event_data);
721                 BT_PERMANENT_LOG("Mesh: Network Provisioning Failed");
722                 break;
723         case OAL_EVENT_MESH_PROVISIONING_FINISHED:
724                 __handle_mesh_network_provisioning_finished_event(
725                         (event_mesh_provisioning_finished_t*)event_data);
726                 BT_PERMANENT_LOG("Mesh: Network Provisioning Finished");
727                 break;
728         case OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED:
729                 __handle_mesh_network_provisioning_data_requested_event(
730                         (event_mesh_provisioning_data_requested_t*)event_data);
731                 BT_PERMANENT_LOG("Mesh: Network Provisioning Data Requested");
732                 break;
733         case OAL_EVENT_MESH_AUTHENTICATION_REQUESTED:
734                 __handle_mesh_network_authentication_requested_event(
735                         (event_mesh_authentication_requested_t*)event_data);
736                 BT_PERMANENT_LOG("Mesh: Network Authentication Requested");
737                 break;
738         case OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT:
739                 __handle_mesh_network_subnet_operation_event(
740                         (event_mesh_netkey_operation_t*)event_data);
741                 BT_PERMANENT_LOG("Mesh: Network Subnet operation event");
742                 break;
743         case OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT:
744                  __handle_mesh_network_appkey_operation_event(
745                         (event_mesh_appkey_operation_t*)event_data);
746                 BT_PERMANENT_LOG("Mesh: AppKey operation event");
747                 break;
748         case OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED:
749                 __handle_mesh_devkey_message_received_event(
750                         (event_mesh_devkey_message_t*)event_data);
751                 BT_PERMANENT_LOG("Mesh: DevKey Message Received event");
752                 break;
753         case OAL_EVENT_MESH_MODEL_MESSAGE_RECEIVED:
754                 __handle_mesh_message_received_event(
755                         (event_mesh_message_t*)event_data);
756                 BT_PERMANENT_LOG("Mesh: Model Message Received event");
757                 break;
758         default:
759         break;
760         }
761 }
762
763 static int __bt_meshd_launch()
764 {
765         int ret = UNIT_CONTROL_OK;
766         BT_INFO("Mesh: Launch Meshd");
767         ret = actd_start_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
768                                 MESH_SYSTEMD_SERVICE_NAME, 5000);
769
770         if (ret != UNIT_CONTROL_OK) {
771                 BT_ERR("Failed to call systemact service: %d", ret);
772                 return BLUETOOTH_ERROR_INTERNAL;
773         }
774         BT_INFO("Mesh: Launch Meshd successful");
775
776         return BLUETOOTH_ERROR_NONE;
777 }
778
779 static int __bt_mesh_enable()
780 {
781         oal_status_t status = OAL_STATUS_SUCCESS;
782         BT_INFO("Mesh: Set dbus callbacks");
783         status = mesh_enable();
784         if (OAL_STATUS_SUCCESS != status &&
785                         OAL_STATUS_ALREADY_DONE != status) {
786                 BT_ERR("Mesh: Failed to enable mesh interface, status: %d",
787                                 status);
788                 return BLUETOOTH_ERROR_INTERNAL;
789         }
790         BT_INFO("Mesh: Stack Initialization Done successfully: status [%d]",
791                         status);
792
793         /* Register MESH event handler */
794         _bt_service_register_event_handler_callback(BT_MESH_MODULE,
795                         __handle_mesh_events);
796
797         return (status == OAL_STATUS_SUCCESS ? BLUETOOTH_ERROR_NONE : \
798                         BLUETOOTH_ERROR_ALREADY_INITIALIZED);
799 }
800
801 static gboolean __bt_mesh_launch_timer_expired_cb(gpointer data)
802 {
803         BT_INFO("Mesh: Enable Mesh dbus");
804         int ret = BLUETOOTH_ERROR_NONE;
805         ret = __bt_mesh_enable();
806         if (BLUETOOTH_ERROR_NONE != ret &&
807                 BLUETOOTH_ERROR_ALREADY_INITIALIZED != ret)
808                 BT_ERR("Mesh: Mesh enable failed: %d", ret);
809
810         /* Handle DBUS Context return */
811         BT_INFO("Mesh: Handle DBUS Context return");
812         __bt_mesh_handle_pending_request_info(ret,
813                         BT_MESH_INIT,
814                         NULL, 0);
815
816         /* Reset launch timer ID */
817         BT_INFO("Mesh: Timer ID after expiry [%u]", launch_timer);
818         launch_timer = 0;
819
820         return FALSE;
821 }
822
823 int _bt_mesh_init(void)
824 {
825         int ret = BLUETOOTH_ERROR_NONE;
826
827         BT_INFO("Mesh: Total apps using Mesh: [%d]",
828                 mesh_app_ref_count);
829
830         BT_INFO("Mesh: Current Timer ID [%u]", launch_timer);
831         if (launch_timer > 0) {
832                 BT_INFO("Mesh: BT_MESH_INIT in progress");
833                 return ret;
834         }
835
836         if (mesh_app_ref_count) {
837                 BT_INFO("Mesh: Mesh Stack already initialized");
838                 /* Increase mesh app ref count */
839                 mesh_app_ref_count++;
840                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
841         }
842
843         BT_INFO("Mesh: Mesh Stack init not done yet!");
844         /* Launch bluetooth-meshd */
845         ret = __bt_meshd_launch();
846         if (BLUETOOTH_ERROR_NONE != ret) {
847                 BT_ERR("Mesh: Meshd launch failed: %d", ret);
848                 return ret;
849         }
850
851         /* wait for half a second*/
852         launch_timer = g_timeout_add(MESH_LAUNCH_DELAY,
853                                 (GSourceFunc)__bt_mesh_launch_timer_expired_cb,
854                                                                         NULL);
855
856         BT_INFO("Mesh: Timer ID [%u]", launch_timer);
857         return ret;
858 }
859
860 int _bt_mesh_deinit(void)
861 {
862         oal_status_t status = OAL_STATUS_SUCCESS;
863         int ret = UNIT_CONTROL_OK;
864
865         if (launch_timer > 0) {
866                 g_source_remove(launch_timer);
867                 launch_timer = 0;
868         }
869
870         BT_INFO("Mesh: Current number of applications using mesh [%d]",
871                         mesh_app_ref_count);
872
873         if (mesh_app_ref_count == 1) {
874                 BT_INFO("Mesh: Only one app using Mesh Stack: Unload & reduce ref count");
875                 /* Terminate bluetooth-meshd */
876                 ret = actd_stop_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
877                                 MESH_SYSTEMD_SERVICE_NAME, 5000);
878
879                 if (ret != UNIT_CONTROL_OK)
880                         BT_ERR("Failed to call systemact service: %d", ret);
881
882                 status = mesh_disable();
883                 if (OAL_STATUS_SUCCESS != status) {
884                         BT_ERR("Mesh: Failed to de-initialize Mesh profile, status: %d",
885                                         status);
886                         return BLUETOOTH_ERROR_INTERNAL;
887                 }
888
889                 /* Un-Register Mesh event handler */
890                 _bt_service_unregister_event_handler_callback(BT_MESH_MODULE);
891         }
892
893         /* Decrease mesh app ref count */
894         mesh_app_ref_count--;
895
896         return BLUETOOTH_ERROR_NONE;
897 }