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