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