Mesh: Handle mesh application termination event
[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_attached_event(
395                 event_mesh_network_attached_t *event)
396 {
397         int result = BLUETOOTH_ERROR_NONE;
398         bluetooth_mesh_node_t node;
399
400         if (event->status != OAL_STATUS_SUCCESS)
401                 result = BLUETOOTH_ERROR_INTERNAL;
402
403         memset(&node, 0x00, sizeof(bluetooth_mesh_node_t));
404
405         memcpy(node.uuid, event->uuid.uuid, 16);
406         memcpy(node.token.u8, event->token, 8);
407
408         __bt_mesh_handle_pending_request_info(result,
409                         BT_MESH_NETWORK_CREATE,
410                         &node, sizeof(bluetooth_mesh_node_t));
411         __bt_mesh_handle_pending_request_info(result,
412                         BT_MESH_NETWORK_LOAD,
413                         &node, sizeof(bluetooth_mesh_node_t));
414 }
415
416 static void __handle_mesh_network_destroyed_event(
417                 event_mesh_network_destroyed_t *event)
418 {
419         int result = BLUETOOTH_ERROR_NONE;
420         bluetooth_mesh_network_t network;
421
422         if (event->status != OAL_STATUS_SUCCESS) {
423                 BT_INFO("Mesh: Network Destroyed Event: result is Failed!");
424                 result = BLUETOOTH_ERROR_INTERNAL;
425         } else {
426                 BT_INFO("Mesh: Network Destroyed Event: result is Success!");
427         }
428
429         memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
430         _bt_mesh_util_convert_hex_to_string(
431                         (uint8_t *) event->uuid.uuid, 16, network.uuid,
432                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
433         _bt_mesh_util_convert_hex_to_string(
434                         (uint8_t *) event->token, 8, network.token.token,
435                         BLUETOOTH_MESH_NETWORK_TOKEN_STRING_LENGTH + 1);
436
437         __bt_mesh_handle_pending_request_info(result,
438                         BT_MESH_NETWORK_DESTROY,
439                         &network, sizeof(bluetooth_mesh_network_t));
440 }
441
442 static void __handle_mesh_network_scan_started_event(
443         event_mesh_scan_status_t *event)
444 {
445         GVariant *out_var = NULL, *param = NULL;
446         GArray *info = NULL;
447         bluetooth_mesh_network_t network;
448
449         int result = BLUETOOTH_ERROR_NONE;
450         if (event->status != OAL_STATUS_SUCCESS) {
451                 result = BLUETOOTH_ERROR_INTERNAL;
452                 _bt_mesh_set_scanning_state(false);
453         } else
454                 _bt_mesh_set_scanning_state(true);
455
456         /* Handle DBUS Context return */
457         __bt_mesh_handle_pending_request_info(result,
458                         BT_MESH_NETWORK_SCAN,
459                         event, sizeof(event_mesh_scan_status_t));
460
461         /* Handle Scan started event */
462         if (result == BLUETOOTH_ERROR_NONE) {
463                 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
464                 _bt_mesh_util_convert_hex_to_string(
465                         (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
466                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
467
468                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
469                 g_array_append_vals(info, &network,
470                         sizeof(bluetooth_mesh_network_t));
471
472                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
473                         info->data, info->len,
474                         TRUE, NULL, NULL);
475
476                 param = g_variant_new("(iv)", result, out_var);
477                 _bt_send_event(BT_MESH_EVENT,
478                         BLUETOOTH_EVENT_MESH_SCAN_STARTED,
479                         param);
480         }
481 }
482
483 static void __handle_mesh_network_scan_finished_event(
484         event_mesh_scan_status_t *event)
485 {
486         GVariant *out_var = NULL, *param = NULL;
487         GArray *info = NULL;
488         bluetooth_mesh_network_t network;
489         int result = BLUETOOTH_ERROR_NONE;
490         if (event->status != OAL_STATUS_SUCCESS) {
491                 BT_INFO("Mesh: Scan Finished: status:: FAILED!");
492                 result = BLUETOOTH_ERROR_INTERNAL;
493         } else
494                 BT_INFO("Mesh: Scan Finished: status:: SUCCESS!");
495
496         /* Handle Scan finsihed event */
497         if (result == BLUETOOTH_ERROR_NONE) {
498                 memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
499                 _bt_mesh_util_convert_hex_to_string(
500                         (uint8_t *) event->net_uuid.uuid, 16, network.uuid,
501                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
502
503                 info = g_array_new(FALSE, FALSE, sizeof(gchar));
504                 g_array_append_vals(info, &network,
505                         sizeof(bluetooth_mesh_network_t));
506
507                 out_var = g_variant_new_from_data((const GVariantType *)"ay",
508                         info->data, info->len,
509                         TRUE, NULL, NULL);
510
511                 param = g_variant_new("(iv)", result, out_var);
512                 _bt_send_event(BT_MESH_EVENT,
513                         BLUETOOTH_EVENT_MESH_SCAN_FINISHED,
514                         param);
515                 _bt_mesh_set_scanning_state(false);
516         }
517 }
518
519 static void __handle_mesh_network_provisioning_started_event(
520                 event_mesh_provisioning_status_t *status)
521 {
522         int result = BLUETOOTH_ERROR_NONE;
523         BT_INFO("Mesh: Provisioning started");
524
525         __bt_mesh_handle_pending_request_info(result,
526                         BT_MESH_NETWORK_PROVISION_DEVICE,
527                         status, sizeof(event_mesh_provisioning_status_t));
528
529         _bt_mesh_set_provisioning_state(true);
530 }
531
532 static void __handle_mesh_network_provisioning_failed_event(
533                 event_mesh_provisioning_status_t *status)
534 {
535         int result = BLUETOOTH_ERROR_INTERNAL;
536         BT_INFO("Mesh: Provisioning failed!!");
537         __bt_mesh_handle_pending_request_info(result,
538                         BT_MESH_NETWORK_PROVISION_DEVICE,
539                         status, sizeof(event_mesh_provisioning_status_t));
540
541         _bt_mesh_set_provisioning_state(false);
542 }
543
544 static void __handle_mesh_network_provisioning_finished_event(
545                 event_mesh_provisioning_finished_t *event)
546 {
547         GVariant *out_var = NULL, *param = NULL;
548         GArray *info = NULL;
549         bluetooth_mesh_provisioning_result_t prov_result;
550         BT_INFO("Mesh: Provisioning Finished!");
551
552         memset(&prov_result, 0x00,
553                         sizeof(bluetooth_mesh_provisioning_result_t));
554
555         if (event->status != OAL_STATUS_SUCCESS)
556                 prov_result.result = BLUETOOTH_ERROR_INTERNAL;
557         else
558                 prov_result.result = BLUETOOTH_ERROR_NONE;
559
560         prov_result.reason = event->reason;
561         prov_result.unicast = event->unicast;
562         prov_result.count = event->count;
563
564         _bt_mesh_util_convert_hex_to_string(
565                         (uint8_t *) event->net_uuid.uuid, 16, prov_result.net_uuid,
566                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
567
568         _bt_mesh_util_convert_hex_to_string(
569                         (uint8_t *) event->dev_uuid.uuid, 16, prov_result.dev_uuid,
570                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
571
572         info = g_array_new(FALSE, FALSE, sizeof(gchar));
573         g_array_append_vals(info, &prov_result,
574                         sizeof(bluetooth_mesh_provisioning_result_t));
575
576         out_var = g_variant_new_from_data((const GVariantType *)"ay",
577                         info->data, info->len,
578                         TRUE, NULL, NULL);
579
580         param = g_variant_new("(iv)", prov_result.result, out_var);
581         _bt_send_event(BT_MESH_EVENT,
582                         BLUETOOTH_EVENT_MESH_PROVISIONING_FINISHED,
583                         param);
584
585         /* Add Remote Node entry in Local CDB */
586         if (event->status == OAL_STATUS_SUCCESS) {
587                 BT_INFO("Mesh: Provisioning done, add node to Network");
588                 BT_INFO("Mesh: Node UUID [%s]", prov_result.dev_uuid);
589                 BT_INFO("Mesh: Node Unicast[0x%2.2x] Element Count [%d]",
590                         event->unicast, event->count);
591
592                 _bt_mesh_network_add_remote_node(
593                         event->net_uuid.uuid, event->dev_uuid.uuid,
594                                 event->unicast, event->count);
595         }
596         /* Unset provisioning state */
597         _bt_mesh_set_provisioning_state(false);
598 }
599
600 static void __handle_mesh_network_provisioning_data_requested_event(
601         event_mesh_provisioning_data_requested_t *event)
602 {
603         _bt_mesh_network_request_provisioning_data_request(
604                         event->net_uuid.uuid, event->count);
605 }
606
607 static void __handle_mesh_network_authentication_requested_event(
608                 event_mesh_authentication_requested_t *event)
609 {
610         GVariant *out_var = NULL, *param = NULL;
611         GArray *info = NULL;
612         bluetooth_mesh_authentication_request_t auth_req;
613
614         memset(&auth_req, 0x00,
615                         sizeof(bluetooth_mesh_authentication_request_t));
616
617         auth_req.auth_type = event->auth_type;
618         g_strlcpy(auth_req.auth_value, event->auth_value,
619                         sizeof(auth_req.auth_value));
620
621         _bt_mesh_util_convert_hex_to_string(
622                         (uint8_t *) event->net_uuid.uuid, 16, auth_req.net_uuid,
623                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
624
625         BT_INFO("Mesh: Authentication Requested by Device: Network [%s]",
626                 auth_req.net_uuid);
627         info = g_array_new(FALSE, FALSE, sizeof(gchar));
628         g_array_append_vals(info, &auth_req,
629                         sizeof(bluetooth_mesh_authentication_request_t));
630
631         out_var = g_variant_new_from_data((const GVariantType *)"ay",
632                         info->data, info->len,
633                         TRUE, NULL, NULL);
634
635         param = g_variant_new("(iv)", BLUETOOTH_ERROR_NONE, out_var);
636         _bt_send_event(BT_MESH_EVENT,
637                         BLUETOOTH_EVENT_MESH_AUTHENTICATION_REQUEST,
638                         param);
639 }
640
641 static void __handle_mesh_network_scan_result_event(
642                 event_mesh_scan_result_t *event)
643 {
644         GVariant *out_var = NULL, *param = NULL;
645         GArray *info = NULL;
646         bluetooth_mesh_scan_result_t data;
647         int result = BLUETOOTH_ERROR_NONE;
648
649         memset(&data, 0x00, sizeof(bluetooth_mesh_scan_result_t));
650
651         /* Fill Network UUID */
652         _bt_mesh_util_convert_hex_to_string(
653                 (uint8_t *) event->net_uuid.uuid, 16, data.net_uuid,
654                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
655
656         /* Fill Device UUID */
657         _bt_mesh_util_convert_hex_to_string(
658                 (uint8_t *) event->result.dev_uuid.uuid, 16, data.dev_uuid,
659                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
660
661         /* Fill RSSI */
662         data.rssi = event->result.rssi;
663
664         /* Fill OOB Info */
665         memcpy(&data.oob_info, event->result.oob_info, 2);
666
667         /* Fill URI Hash Info */
668         memcpy(&data.uri_hash, event->result.uri_hash, 4);
669
670         if (event->status != OAL_STATUS_SUCCESS)
671                 result = BLUETOOTH_ERROR_INTERNAL;
672
673         /* Fill Data */
674         info = g_array_new(FALSE, FALSE, sizeof(gchar));
675         g_array_append_vals(info, &data,
676                 sizeof(bluetooth_mesh_scan_result_t));
677
678         out_var = g_variant_new_from_data((const GVariantType *)"ay",
679                         info->data, info->len,
680                         TRUE, NULL, NULL);
681
682         param = g_variant_new("(iv)", result, out_var);
683         _bt_send_event(BT_MESH_EVENT,
684                         BLUETOOTH_EVENT_MESH_SCAN_RESULT,
685                         param);
686 }
687
688 static void __handle_mesh_events(int event_type,
689                 gpointer event_data)
690 {
691         BT_INFO("Mesh: Got Mesh event!!! event type [%d]", event_type);
692         if (event_type == OAL_EVENT_MESH_PROVISIONING_STARTED)
693                 BT_INFO("Mesh: Provisioning started event");
694
695         switch (event_type) {
696         case OAL_EVENT_MESH_NETWORK_ATTACHED:
697                 __handle_mesh_network_attached_event(
698                         (event_mesh_network_attached_t*)event_data);
699                 BT_PERMANENT_LOG("Mesh: Network attached!!");
700                 break;
701         case OAL_EVENT_MESH_NETWORK_DESTROYED:
702                 __handle_mesh_network_destroyed_event(
703                         (event_mesh_network_destroyed_t*)event_data);
704                 BT_PERMANENT_LOG("Mesh: Network Destroyed!!");
705                 break;
706         case OAL_EVENT_MESH_SCAN_STARTED:
707                 __handle_mesh_network_scan_started_event(
708                         (event_mesh_scan_status_t*)event_data);
709                 BT_PERMANENT_LOG("Mesh: Network Scan Stated!!");
710                 break;
711         case OAL_EVENT_MESH_SCAN_FINISHED:
712                 __handle_mesh_network_scan_finished_event(
713                         (event_mesh_scan_status_t*)event_data);
714                 BT_PERMANENT_LOG("Mesh: Network Scan Finished!!");
715                 break;
716         case OAL_EVENT_MESH_SCAN_RESULT:
717                 __handle_mesh_network_scan_result_event(
718                         (event_mesh_scan_result_t*)event_data);
719                 BT_PERMANENT_LOG("Mesh: Network Scan Result!!");
720                 break;
721         case OAL_EVENT_MESH_PROVISIONING_STARTED:
722                 BT_INFO("Mesh: Network Provisioning Started");
723                 __handle_mesh_network_provisioning_started_event(
724                         (event_mesh_provisioning_status_t*)event_data);
725                 BT_PERMANENT_LOG("Mesh: Network Provisioning Started");
726                 break;
727         case OAL_EVENT_MESH_PROVISIONING_FAILED:
728                 BT_INFO("Mesh: Network Provisioning Failed!!!!");
729                 __handle_mesh_network_provisioning_failed_event(
730                         (event_mesh_provisioning_status_t*)event_data);
731                 BT_PERMANENT_LOG("Mesh: Network Provisioning Failed");
732                 break;
733         case OAL_EVENT_MESH_PROVISIONING_FINISHED:
734                 __handle_mesh_network_provisioning_finished_event(
735                         (event_mesh_provisioning_finished_t*)event_data);
736                 BT_PERMANENT_LOG("Mesh: Network Provisioning Finished");
737                 break;
738         case OAL_EVENT_MESH_PROVISIONING_DATA_REQUESTED:
739                 __handle_mesh_network_provisioning_data_requested_event(
740                         (event_mesh_provisioning_data_requested_t*)event_data);
741                 BT_PERMANENT_LOG("Mesh: Network Provisioning Data Requested");
742                 break;
743         case OAL_EVENT_MESH_AUTHENTICATION_REQUESTED:
744                 __handle_mesh_network_authentication_requested_event(
745                         (event_mesh_authentication_requested_t*)event_data);
746                 BT_PERMANENT_LOG("Mesh: Network Authentication Requested");
747                 break;
748         case OAL_EVENT_MESH_NETKEY_EXECUTE_EVENT:
749                 __handle_mesh_network_subnet_operation_event(
750                         (event_mesh_netkey_operation_t*)event_data);
751                 BT_PERMANENT_LOG("Mesh: Network Subnet operation event");
752                 break;
753         case OAL_EVENT_MESH_APPKEY_EXECUTE_EVENT:
754                  __handle_mesh_network_appkey_operation_event(
755                         (event_mesh_appkey_operation_t*)event_data);
756                 BT_PERMANENT_LOG("Mesh: AppKey operation event");
757                 break;
758         case OAL_EVENT_MESH_DEVKEY_MESSAGE_RECEIVED:
759                 __handle_mesh_devkey_message_received_event(
760                         (event_mesh_devkey_message_t*)event_data);
761                 BT_PERMANENT_LOG("Mesh: DevKey Message Received event");
762                 break;
763         case OAL_EVENT_MESH_MODEL_MESSAGE_RECEIVED:
764                 __handle_mesh_message_received_event(
765                         (event_mesh_message_t*)event_data);
766                 BT_PERMANENT_LOG("Mesh: Model Message Received event");
767                 break;
768         default:
769         break;
770         }
771 }
772
773 static int __bt_meshd_launch()
774 {
775         int ret = UNIT_CONTROL_OK;
776         BT_INFO("Mesh: Launch Meshd");
777         ret = actd_start_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
778                                 MESH_SYSTEMD_SERVICE_NAME, 5000);
779
780         if (ret != UNIT_CONTROL_OK) {
781                 BT_ERR("Failed to call systemact service: %d", ret);
782                 return BLUETOOTH_ERROR_INTERNAL;
783         }
784         BT_INFO("Mesh: Launch Meshd successful");
785
786         return BLUETOOTH_ERROR_NONE;
787 }
788
789 static int __bt_mesh_enable()
790 {
791         oal_status_t status = OAL_STATUS_SUCCESS;
792         BT_INFO("Mesh: Set dbus callbacks");
793         status = mesh_enable();
794         if (OAL_STATUS_SUCCESS != status &&
795                         OAL_STATUS_ALREADY_DONE != status) {
796                 BT_ERR("Mesh: Failed to enable mesh interface, status: %d",
797                                 status);
798                 return BLUETOOTH_ERROR_INTERNAL;
799         }
800         BT_INFO("Mesh: Stack Initialization Done successfully: status [%d]",
801                         status);
802
803         /* Register MESH event handler */
804         _bt_service_register_event_handler_callback(BT_MESH_MODULE,
805                         __handle_mesh_events);
806
807         return (status == OAL_STATUS_SUCCESS ? BLUETOOTH_ERROR_NONE : \
808                         BLUETOOTH_ERROR_ALREADY_INITIALIZED);
809 }
810
811 static gboolean __bt_mesh_launch_timer_expired_cb(gpointer data)
812 {
813         BT_INFO("Mesh: Enable Mesh dbus");
814         int ret = BLUETOOTH_ERROR_NONE;
815         ret = __bt_mesh_enable();
816         if (BLUETOOTH_ERROR_NONE != ret &&
817                 BLUETOOTH_ERROR_ALREADY_INITIALIZED != ret)
818                 BT_ERR("Mesh: Mesh enable failed: %d", ret);
819
820         /* Handle DBUS Context return */
821         BT_INFO("Mesh: Handle DBUS Context return");
822         __bt_mesh_handle_pending_request_info(ret,
823                         BT_MESH_INIT,
824                         NULL, 0);
825
826         /* Reset launch timer ID */
827         BT_INFO("Mesh: Timer ID after expiry [%u]", launch_timer);
828         launch_timer = 0;
829
830         return FALSE;
831 }
832
833 int _bt_mesh_init(const char *sender)
834 {
835         int ret = BLUETOOTH_ERROR_NONE;
836
837         BT_INFO("Mesh: Total apps using Mesh: [%d]",
838                 mesh_app_ref_count);
839
840         BT_INFO("Mesh: Mesh App Sender [%s]", sender);
841
842         BT_INFO("Mesh: Current Timer ID [%u]", launch_timer);
843         if (launch_timer > 0) {
844                 BT_INFO("Mesh: BT_MESH_INIT in progress");
845                 return ret;
846         }
847
848         if (mesh_app_ref_count) {
849                 BT_INFO("Mesh: Mesh Stack already initialized");
850
851                 /* Save Mesh App Owner */
852                 apps = g_slist_append(apps, g_strdup(sender));
853
854                 /* Increase mesh app ref count */
855                 mesh_app_ref_count++;
856                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
857         }
858
859         BT_INFO("Mesh: Mesh Stack init not done yet!");
860         /* Launch bluetooth-meshd */
861         ret = __bt_meshd_launch();
862         if (BLUETOOTH_ERROR_NONE != ret) {
863                 BT_ERR("Mesh: Meshd launch failed: %d", ret);
864                 return ret;
865         }
866
867         /* wait for half a second*/
868         launch_timer = g_timeout_add(MESH_LAUNCH_DELAY,
869                                 (GSourceFunc)__bt_mesh_launch_timer_expired_cb,
870                                                                         NULL);
871
872         BT_INFO("Mesh: Timer ID [%u]", launch_timer);
873         return ret;
874 }
875
876 static gint __bt_mesh_match_sender(gconstpointer a, gconstpointer b)
877 {
878         char *owner_a = (char*) a;
879         char *owner_b = (char*) b;
880
881         return g_strcmp0(owner_a, owner_b);
882 }
883
884 int _bt_mesh_deinit(const char *sender)
885 {
886         GSList *l = NULL;
887         char *owner = NULL;
888         oal_status_t status = OAL_STATUS_SUCCESS;
889         int ret = UNIT_CONTROL_OK;
890
891         BT_INFO("Mesh: Deinit Request from App [%s]", sender);
892         BT_INFO("Mesh: Total Apps available in list [%d]",
893                         g_slist_length(apps));
894
895         /* Find & remove app entry from list */
896         l = g_slist_find_custom(apps, sender,
897                         (GCompareFunc)__bt_mesh_match_sender);
898         if (!l) {
899                 BT_ERR("Mesh: App is not Mesh App");
900                 return BLUETOOTH_ERROR_INTERNAL;
901         }
902
903         BT_INFO("Mesh: Deinit Mesh: Sender Found: [%s]", sender);
904
905         if (launch_timer > 0) {
906                 g_source_remove(launch_timer);
907                 launch_timer = 0;
908         }
909
910         BT_INFO("Mesh: Current number of applications using mesh [%d]",
911                         mesh_app_ref_count);
912
913         if (mesh_app_ref_count == 1) {
914                 BT_INFO("Mesh: Only one app using Mesh Stack: Unload & reduce ref count");
915                 /* Terminate bluetooth-meshd */
916                 ret = actd_stop_unit(UNIT_CONTROL_BUS_TYPE_SYSTEM,
917                                 MESH_SYSTEMD_SERVICE_NAME, 5000);
918
919                 if (ret != UNIT_CONTROL_OK)
920                         BT_ERR("Failed to call systemact service: %d", ret);
921
922                 status = mesh_disable();
923                 if (OAL_STATUS_SUCCESS != status) {
924                         BT_ERR("Mesh: Failed to de-initialize Mesh profile, status: %d",
925                                         status);
926                         return BLUETOOTH_ERROR_INTERNAL;
927                 }
928
929                 /* Un-Register Mesh event handler */
930                 _bt_service_unregister_event_handler_callback(BT_MESH_MODULE);
931         }
932
933         /* Decrease mesh app ref count */
934         mesh_app_ref_count--;
935
936         owner = l->data;
937         apps = g_slist_remove(apps, owner);
938         g_free(owner);
939
940         return BLUETOOTH_ERROR_NONE;
941 }
942
943 void _bt_mesh_handle_app_termination(const char *sender)
944 {
945         BT_INFO("Mesh: Handle App termination: dbus app name[%s]",
946                         sender);
947
948         _bt_mesh_deinit(sender);
949 }