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