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