Mesh: Handle mesh application termination event
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / mesh / bt-service-mesh-network.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 <glib.h>
22 #include <dlog.h>
23 #include <fcntl.h>
24 #include <dirent.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <ell/ell.h>
31
32 #include "bt-service-common.h"
33 #include "bt-service-core-adapter.h"
34 #include "bt-service-event-receiver.h"
35 #include "bt-request-handler.h"
36 #include "bluetooth-api.h"
37
38 #include "bluetooth-api.h"
39 #include "bluetooth-mesh-api.h"
40 #include "bt-internal-types.h"
41 #include "bt-service-util.h"
42 #include "bt-service-common.h"
43 #include "bt-service-event.h"
44
45 #include "bt-service-mesh-network.h"
46 #include "bt-service-mesh-cdb.h"
47 #include "bt-service-mesh-main.h"
48 #include "bt-service-mesh-nodes.h"
49 #include "bt-service-mesh-keys.h"
50 #include "bt-service-mesh-util.h"
51
52 #include "bt-internal-types.h"
53
54 #include <oal-hardware.h>
55 #include <oal-manager.h>
56 #include <oal-event.h>
57 #include <oal-adapter-mgr.h>
58 #include <oal-device-mgr.h>
59 #include <oal-mesh.h>
60
61 /* Temp local node structure.
62    Create & save node temporarily till network creation */
63 typedef struct {
64         const char *app_cred;
65         const char *sender;
66         bluetooth_mesh_vendor_info_t vendor_info;
67         uint8_t node_uuid[16];
68         uint16_t num_elems;
69         uint16_t prim_unicast;
70         GSList *model_list;
71 } mesh_local_node_t;
72
73 /* List of CDB's for the created networks */
74 static GSList *cdb_list = NULL;
75
76 /* List of local ndoes to be created: Free memory once saved in DB */
77 static GSList *temp_nodes = NULL;
78
79 /* Scanning state: Unprovisioned device scan */
80 static bool bt_mesh_is_scanning = false;
81
82 /* Provisoning state */
83 static bool bt_mesh_is_provisoning = false;
84
85 static gint __mesh_compare_hex_uuid(gconstpointer data,
86                 gconstpointer user_data)
87 {
88         const mesh_local_node_t *u1 = data;
89         const uint8_t *u2 = user_data;
90
91         retv_if(NULL == u1, -1);
92         retv_if(NULL == u2, -1);
93
94         return memcmp(u1->node_uuid, u2, 16);
95 }
96
97 static gint __mesh_compare_app_network_uuid(
98         gconstpointer data, gconstpointer user_data)
99 {
100         const _bt_mesh_cdb_t *cdb = data;
101         const uint8_t *net_uuid = user_data;
102
103         retv_if(NULL == cdb, -1);
104         retv_if(NULL == net_uuid, -1);
105
106         return memcmp(net_uuid, cdb->uuid, 16);
107 }
108
109 static gint __mesh_compare_app_cdb_token(gconstpointer data,
110                 gconstpointer user_data)
111 {
112         char token_str[17];
113         const _bt_mesh_cdb_t *cdb = data;
114         const char *token = user_data;
115
116         retv_if(NULL == cdb, -1);
117         retv_if(NULL == token, -1);
118
119         _bt_mesh_util_convert_hex_to_string((uint8_t *) cdb->token,
120                         8, token_str, 17);
121
122         BT_INFO("Mesh: Match Token 1[%s] Token 2 [%s]",
123                         token_str, token);
124         return g_strcmp0(token_str, token);
125 }
126
127 static gint __mesh_compare_addr(
128                 const void *a, const void *b)
129 {
130         const _bt_mesh_group_t *grp = a;
131         uint16_t addr = GPOINTER_TO_UINT(b);
132         BT_INFO("Mesh: Network group addr [0x%2.2x]", grp->grp_addr);
133         BT_INFO("Mesh: To be matched group addr [0x%2.2x]", addr);
134
135         return (grp->grp_addr - addr);
136 }
137
138 int _bt_mesh_load_app_networks(const char *app_cred)
139 {
140         int ret = BLUETOOTH_ERROR_NONE;
141
142         /* Load Mesh Networks for the current app */
143         if (!_bt_mesh_util_is_directory_exists(MESH_CDB_DEFAULT_DIR_PATH))
144                 return BLUETOOTH_ERROR_INTERNAL;
145
146         return ret;
147 }
148
149 static void __bt_mesh_free_temp_node(mesh_local_node_t *tmp)
150 {
151         if (!tmp)
152                 return;
153         temp_nodes = g_slist_remove(temp_nodes, tmp);
154         g_free((gpointer)tmp->app_cred);
155         g_free((gpointer)tmp->sender);
156         /* Do not free tmp->model_list here
157           This memory is also being used in HAL layer
158           This memory will be freed with the call of __mesh_client_disconnected */
159         tmp->model_list = NULL;
160         g_free(tmp);
161 }
162
163 int _bt_mesh_network_request_provisioning_data_request(uint8_t net_uuid[],
164                 uint8_t count)
165 {
166         uint16_t unicast;
167         int ret = OAL_STATUS_SUCCESS;
168         oal_uuid_t uuid;
169         char uuid_string[33];
170
171         _bt_mesh_util_convert_hex_to_string(net_uuid, 16,
172                         uuid_string, sizeof(uuid_string));
173         BT_INFO("Mesh: Provisioning Data requested for network [%s]",
174                         uuid_string);
175
176         unicast = _bt_mesh_node_get_next_unicast(net_uuid,
177                         MESH_DEFAULT_START_ADDRESS,
178                         MESH_DEFAULT_MAX_ADDRESS, count);
179         BT_INFO("Mesh: Network: Got unicast [%4.4x]", unicast);
180
181         memcpy(uuid.uuid, net_uuid, 16);
182         /* Register Mesh Node */
183         ret = mesh_network_send_provisioning_data(&uuid,
184                         MESH_PRIMARY_NET_IDX, unicast);
185         if (ret != OAL_STATUS_SUCCESS) {
186                 BT_ERR("ret: %d", ret);
187                 return BLUETOOTH_ERROR_INTERNAL;
188         }
189         return BLUETOOTH_ERROR_NONE;
190 }
191
192 int _bt_mesh_network_remove_node_configuration(
193                 bluetooth_mesh_node_info_t *node)
194 {
195         GSList *l;
196         _bt_mesh_cdb_t *cdb_cfg = NULL;
197         uint8_t net_uuid[16];
198         BT_INFO("Mesh: Remove Node Configuration: Unicast [0x%2.2x]",
199                         node->primary_unicast);
200
201         _bt_mesh_util_convert_string_to_hex(node->net_uuid,
202                         strlen(node->net_uuid), net_uuid, 16);
203
204         /* Find CDB */
205         l = g_slist_find_custom(cdb_list, net_uuid,
206                         __mesh_compare_app_network_uuid);
207         if (!l) {
208                 BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
209                 return BLUETOOTH_ERROR_INVALID_PARAM;
210         }
211
212         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
213
214         if (_bt_mesh_conf_delete_node(cdb_cfg, node->primary_unicast)) {
215                 BT_INFO("Mesh: Node Entry deleted from Config DB");
216                 if (!_bt_mesh_node_del_node(cdb_cfg,  node->primary_unicast)) {
217                         BT_ERR("Mesh: Node Entry could not be unloaded from memory");
218                         return BLUETOOTH_ERROR_INTERNAL;
219                 }
220         } else {
221                 BT_ERR("Mesh: Node Entry could not be deleted from Config DB");
222                 return BLUETOOTH_ERROR_INTERNAL;
223         }
224         return BLUETOOTH_ERROR_NONE;
225 }
226
227 void _bt_check_mesh_app_termination(const char *name)
228 {
229         GSList *l;
230         _bt_mesh_cdb_t *cdb_cfg = NULL;
231         const char *app_cred = NULL;
232         BT_INFO("Mesh: App terminated [%s]", name);
233
234         /* TODO: Fetch app cred, when support is added */
235
236         for (l = cdb_list; l != NULL;) {
237                 cdb_cfg = (_bt_mesh_cdb_t*)l->data;
238                 l = g_slist_next(l);
239
240                 if (g_strcmp0(cdb_cfg->owner, name) == 0) {
241
242                         bluetooth_mesh_network_t network;
243                         memset(&network, 0x00, sizeof(bluetooth_mesh_network_t));
244
245                         _bt_mesh_util_convert_hex_to_string((uint8_t *) cdb_cfg->uuid,
246                                         16, network.uuid, sizeof(network.uuid));
247
248                         BT_INFO("Mesh: Got Network for unloading: UUID [%s]",
249                                         network.uuid);
250
251                         if (BLUETOOTH_ERROR_NONE != _bt_mesh_network_unload(app_cred, name, &network))
252                                 BT_ERR("Mesh: Network unloading failed!!");
253                         else
254                                 BT_INFO("Mesh: Network unloading Success!!");
255                 }
256         }
257         _bt_mesh_handle_app_termination(name);
258 }
259
260 void _bt_mesh_network_unload_net_configuration(_bt_mesh_cdb_t *cdb_cfg)
261 {
262         BT_INFO("Mesh: Unload Network Configuration");
263
264         /* Unload Network from Keys */
265         _bt_mesh_keys_unload_net(cdb_cfg->uuid);
266
267         /* Unload Network from Nodes */
268         _bt_mesh_node_unload_net(cdb_cfg->uuid);
269
270         cdb_list = g_slist_remove(cdb_list, cdb_cfg);
271         _bt_mesh_conf_free(cdb_cfg);
272         BT_INFO("Mesh: CDB freed from memory: Remaining Networks [%d]",
273                         g_slist_length(cdb_list));
274 }
275
276 int _bt_mesh_network_remove_net_configuration(
277                 bluetooth_mesh_network_t *net)
278 {
279         GSList *l;
280         char *file_path;
281         _bt_mesh_cdb_t *cdb_cfg = NULL;
282         uint8_t net_uuid[16];
283         BT_INFO("Mesh: Remove network Configuration");
284
285         _bt_mesh_util_convert_string_to_hex(net->uuid,
286                         strlen(net->uuid), net_uuid, 16);
287
288         /* Find CDB */
289         l = g_slist_find_custom(cdb_list, net_uuid,
290                         __mesh_compare_app_network_uuid);
291         if (!l) {
292                 BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
293                 return BLUETOOTH_ERROR_INVALID_PARAM;
294         }
295
296         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
297
298         /* Create the CDB for the network */
299         file_path = g_strdup_printf("%s.bak", cdb_cfg->cfg_fname);
300
301         BT_INFO("Mesh: CDB File path[%s]", cdb_cfg->cfg_fname);
302         BT_INFO("Mesh: CDB Backup File path[%s]", file_path);
303
304         /* Remove the config */
305         if (!_bt_mesh_util_delete_file(cdb_cfg->cfg_fname))
306                 return BLUETOOTH_ERROR_INTERNAL;
307
308         /* Remove the config backup */
309         if (!_bt_mesh_util_delete_file(file_path))
310                 return BLUETOOTH_ERROR_INTERNAL;
311         BT_INFO("Mesh: Config DB file removed!!");
312
313         cdb_list = g_slist_remove(cdb_list, cdb_cfg);
314         _bt_mesh_conf_free(cdb_cfg);
315         BT_INFO("Mesh: CDB freed from memory");
316
317         /* Cleanup */
318         g_free(file_path);
319
320         /* Unload Network from Keys */
321         _bt_mesh_keys_unload_net(net_uuid);
322
323         /* Unload Network from Nodes */
324         _bt_mesh_node_unload_net(net_uuid);
325
326         BT_INFO("Mesh: Cleanup Done!");
327         return BLUETOOTH_ERROR_NONE;
328 }
329
330 int _bt_mesh_network_create_cdb(int result,
331                 const char *sender, const char *app_creds,
332                         uint8_t uuid[16], uint8_t token[8],
333                                  const char *network)
334 {
335         char *dir_path = NULL;
336         char *file_path = NULL;
337         GSList *l;
338         mesh_local_node_t *tmp;
339         _bt_mesh_cdb_t *cdb_cfg = NULL;
340         char uuid_string[33];
341         char token_string[17];
342
343         _bt_mesh_util_convert_hex_to_string(uuid, 16,
344                         uuid_string, sizeof(uuid_string));
345         _bt_mesh_util_convert_hex_to_string(token, 8,
346                         token_string, sizeof(token_string));
347         BT_INFO("Mesh: Create CDB request for network UUID [%s] token [%s]",
348                         uuid_string, token_string);
349         BT_INFO("Mesh: Temporary node count [%d]",
350                         g_slist_length(temp_nodes));
351
352         /* Find Temp Node */
353         l = g_slist_find_custom(temp_nodes, uuid,
354                         __mesh_compare_hex_uuid);
355         if (!l) {
356                 BT_ERR("Mesh: Temp  Node not found for the UUID [%s]",
357                                 uuid_string);
358                 return BLUETOOTH_ERROR_INTERNAL;
359         }
360
361         tmp = (mesh_local_node_t*)l->data;
362
363         if (result != BLUETOOTH_ERROR_NONE) {
364                 /* Free the node structure */
365                 __bt_mesh_free_temp_node(tmp);
366                 return result;
367         }
368
369         BT_INFO("Mesh: Create CDB for the New Network [%s]",
370                         network);
371         /* Stat/Create directory for new CDB file */
372         dir_path = g_strdup_printf(MESH_CDB_DEFAULT_DIR_PATH"/%s/",
373                 "default");
374         BT_INFO("Mesh: Directory path for new Network CDB [%s]",
375                         dir_path);
376         if (!_bt_mesh_util_create_directory(dir_path)) {
377                 g_free(dir_path);
378                 __bt_mesh_free_temp_node(tmp);
379                 return BLUETOOTH_ERROR_INTERNAL;
380         }
381
382         BT_INFO("Mesh: Directory Created successfully");
383         /* Create the CDB for the network */
384         file_path = g_strdup_printf("%s%s_config.json",
385                         dir_path, uuid_string);
386         BT_INFO("Mesh: CDB File path[%s]", file_path);
387         BT_INFO("Mesh: CDB App Cred[%s]", app_creds);
388         cdb_cfg = _bt_mesh_conf_database_create(file_path, uuid,
389                         token, network, sender, app_creds);
390
391         /* Cleanup */
392         g_free(dir_path);
393         g_free(file_path);
394
395         if (!cdb_cfg) {
396                 /* Free the memory of temporary node
397                    which was created during Network creation */
398                 __bt_mesh_free_temp_node(tmp);
399                 return BLUETOOTH_ERROR_INTERNAL;
400         }
401         BT_INFO("Mesh: CDB CFG file created successfully");
402
403         _bt_mesh_conf_set_unicast_address_range(cdb_cfg,
404                         MESH_DEFAULT_START_ADDRESS,
405                                 MESH_DEFAULT_MAX_ADDRESS);
406         BT_INFO("Mesh: Address range Set for network");
407
408         /* Create new network for saving network specific Keys */
409         _bt_mesh_keys_load_net(cdb_cfg->uuid);
410         BT_INFO("Mesh: Address range Set for network");
411         _bt_mesh_keys_add_net_key(cdb_cfg->uuid,
412                         MESH_PRIMARY_NET_IDX);
413         BT_INFO("Mesh: Primary net key added to network memeory");
414         _bt_mesh_conf_insert_network_key(cdb_cfg,
415                         MESH_PRIMARY_NET_IDX,
416                                 MESH_KEY_REFRESH_PHASE_NONE);
417         BT_INFO("Mesh: Primary net key added to CDB");
418
419         /* Create new network for saving network specific nodes */
420         _bt_mesh_node_load_net(cdb_cfg->uuid);
421         BT_INFO("Mesh: local Node loaded to memory");
422         _bt_mesh_node_add_node(cdb_cfg->uuid, tmp->node_uuid,
423                         tmp->prim_unicast, tmp->num_elems,
424                                 MESH_PRIMARY_NET_IDX);
425         BT_INFO("Mesh: Added basic info (num elems, UUID, primary NetIDx)");
426
427         /* Add Primary Node as 1st entry in CDB */
428         _bt_mesh_conf_insert_node_object(cdb_cfg, /* Dev UUID */uuid,
429                         tmp->num_elems, tmp->prim_unicast,
430                                 MESH_PRIMARY_NET_IDX);
431         BT_INFO("Mesh: Added Local node's basic info  in CDB");
432
433         cdb_list = g_slist_append(cdb_list, cdb_cfg);
434         BT_INFO("Mesh: CDB added to list");
435
436         __bt_mesh_free_temp_node(tmp);
437         BT_INFO("Mesh: temp node freed");
438         return BLUETOOTH_ERROR_NONE;
439 }
440
441 int _bt_mesh_network_unload(const char *app_cred,
442                 const char *sender, bluetooth_mesh_network_t *network)
443 {
444         GSList *l;
445         oal_uuid_t net_uuid;
446         _bt_mesh_cdb_t *cdb_cfg;
447         int ret = OAL_STATUS_SUCCESS;
448
449         BT_INFO("Mesh: Unload Network Configuration");
450         /* If Scanning is going on */
451         if (_bt_mesh_is_provisioning() ||
452                         _bt_mesh_is_scanning()) {
453                 BT_ERR("Device is buzy..");
454                 return BLUETOOTH_ERROR_DEVICE_BUSY;
455         }
456
457         _bt_mesh_util_convert_string_to_hex(network->uuid,
458                         strlen(network->uuid), net_uuid.uuid, 16);
459
460         /* Release Mesh Network */
461         ret = mesh_network_release(&net_uuid);
462         if (ret != OAL_STATUS_SUCCESS) {
463                 BT_ERR("ret: %d", ret);
464                 return BLUETOOTH_ERROR_INTERNAL;
465         }
466
467         BT_INFO("Mesh: Network released");
468
469         /* Find CDB */
470         l = g_slist_find_custom(cdb_list, net_uuid.uuid,
471                         __mesh_compare_app_network_uuid);
472         if (!l) {
473                 BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
474                 return BLUETOOTH_ERROR_INVALID_PARAM;
475         }
476
477         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
478
479         _bt_mesh_network_unload_net_configuration(cdb_cfg);
480         return BLUETOOTH_ERROR_NONE;
481 }
482
483 int _bt_mesh_network_destroy(const char *app_cred,
484         const char *sender, bluetooth_mesh_network_t *network)
485 {
486         int ret = OAL_STATUS_SUCCESS;
487         oal_uuid_t net_uuid;
488
489         /* If Scanning is going on */
490         if (_bt_mesh_is_provisioning() ||
491                         _bt_mesh_is_scanning()) {
492                 BT_ERR("Device is buzy..");
493                 return BLUETOOTH_ERROR_DEVICE_BUSY;
494         }
495         _bt_mesh_util_convert_string_to_hex(network->uuid,
496                         strlen(network->uuid), net_uuid.uuid, 16);
497         /* Destroy Mesh Network */
498         ret = mesh_network_destroy(&net_uuid);
499         if (ret != OAL_STATUS_SUCCESS) {
500                 BT_ERR("ret: %d", ret);
501                 return BLUETOOTH_ERROR_INTERNAL;
502         }
503
504         return BLUETOOTH_ERROR_NONE;
505 }
506
507 int _bt_mesh_network_scan(const char *app_cred,
508         const char *sender,
509                 bluetooth_mesh_network_t *network,
510                         bluetooth_mesh_scan_param_t *param)
511 {
512         int ret = OAL_STATUS_SUCCESS;
513         oal_uuid_t net_uuid;
514
515         /* If Scanning is going on */
516         if (_bt_mesh_is_provisioning() ||
517                         _bt_mesh_is_scanning()) {
518                 BT_ERR("Device is buzy..");
519                 return BLUETOOTH_ERROR_DEVICE_BUSY;
520         }
521         _bt_mesh_util_convert_string_to_hex(network->uuid,
522                 strlen(network->uuid), net_uuid.uuid, 16);
523         /* Register Mesh Node */
524         ret = mesh_network_start_scan(&net_uuid,
525                 (oal_mesh_scan_params_t*) param);
526         if (ret != OAL_STATUS_SUCCESS) {
527                 BT_ERR("ret: %d", ret);
528                 return BLUETOOTH_ERROR_INTERNAL;
529         }
530
531         /* Set scanning state to true */
532         _bt_mesh_set_scanning_state(true);
533         return BLUETOOTH_ERROR_NONE;
534 }
535
536 int _bt_mesh_network_scan_cancel(const char *app_cred,
537         const char *sender, bluetooth_mesh_network_t *network)
538 {
539         int ret = OAL_STATUS_SUCCESS;
540         oal_uuid_t net_uuid;
541
542         if (!_bt_mesh_is_scanning()) {
543                 BT_INFO("Mesh: Scanning is not ongoing");
544                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
545         }
546         _bt_mesh_util_convert_string_to_hex(network->uuid,
547                 strlen(network->uuid), net_uuid.uuid, 16);
548
549         /* Cancel unprovisioned device scan */
550         ret = mesh_network_scan_cancel(&net_uuid);
551         if (ret != OAL_STATUS_SUCCESS) {
552                 BT_ERR("ret: %d", ret);
553                 return BLUETOOTH_ERROR_INTERNAL;
554         }
555
556         return BLUETOOTH_ERROR_NONE;
557 }
558
559 int _bt_mesh_network_set_provisioner_caps(const char *app_cred,
560                 const char *sender, bluetooth_mesh_network_t *network,
561                         bluetooth_mesh_provisioner_caps_t *caps)
562 {
563         int ret = OAL_STATUS_SUCCESS;
564         oal_uuid_t net_uuid;
565
566         _bt_mesh_util_convert_string_to_hex(network->uuid,
567                 strlen(network->uuid), net_uuid.uuid, 16);
568
569         /* Set provisioning capabilities */
570         ret = mesh_network_set_provisioning_capabilities(&net_uuid,
571                 (oal_mesh_capabilities_t*) caps);
572         if (ret != OAL_STATUS_SUCCESS) {
573                 BT_ERR("ret: %d", ret);
574                 return BLUETOOTH_ERROR_INTERNAL;
575         }
576
577         return BLUETOOTH_ERROR_NONE;
578 }
579
580 bool _bt_mesh_is_scanning(void)
581 {
582         return bt_mesh_is_scanning;
583 }
584
585 void _bt_mesh_set_scanning_state(bool state)
586 {
587         bt_mesh_is_scanning = state;
588 }
589
590 bool _bt_mesh_is_provisioning(void)
591 {
592         return bt_mesh_is_provisoning;
593 }
594
595 void _bt_mesh_set_provisioning_state(bool state)
596 {
597         bt_mesh_is_provisoning = state;
598 }
599
600 int _bt_mesh_network_provision_device(const char *app_cred,
601                 const char *sender,
602                         bluetooth_mesh_provisioning_request_t *req)
603 {
604         int ret = OAL_STATUS_SUCCESS;
605         oal_uuid_t net_uuid;
606         oal_uuid_t dev_uuid;
607
608         /* If Scanning is going on */
609         if (_bt_mesh_is_provisioning() ||
610                         _bt_mesh_is_scanning()) {
611                 BT_ERR("Device is buzy..");
612                 return BLUETOOTH_ERROR_DEVICE_BUSY;
613         }
614
615         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
616                 strlen(req->net_uuid), net_uuid.uuid, 16);
617         _bt_mesh_util_convert_string_to_hex(req->dev_uuid,
618                 strlen(req->dev_uuid), dev_uuid.uuid, 16);
619
620         ret = mesh_network_provision_device(&net_uuid, &dev_uuid);
621
622         if (ret != OAL_STATUS_SUCCESS) {
623                 BT_ERR("ret: %d", ret);
624                 return BLUETOOTH_ERROR_INTERNAL;
625         }
626
627         /* Set Provisioning state */
628         _bt_mesh_set_provisioning_state(true);
629
630         return BLUETOOTH_ERROR_NONE;
631 }
632
633 int _bt_mesh_authentication_reply(int auth_type,
634                 const char *auth_value, gboolean reply)
635 {
636         int ret = OAL_STATUS_SUCCESS;
637
638         if (!_bt_mesh_is_provisioning())
639                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
640
641         if (!auth_value)
642                 return BLUETOOTH_ERROR_INVALID_PARAM;
643
644         ret = mesh_authentication_reply(
645                         (oal_mesh_variant_authentication_e)auth_type,
646                         auth_value);
647
648         if (ret != OAL_STATUS_SUCCESS) {
649                 BT_ERR("ret: %d", ret);
650                 return BLUETOOTH_ERROR_INTERNAL;
651         }
652
653         BT_INFO("Mesh: Scheduled Prov Auth Reply!");
654         return BLUETOOTH_ERROR_NONE;
655 }
656
657 int _bt_mesh_network_get_netkeys(const char *app_cred, const char *sender,
658                 bluetooth_mesh_network_t *network,  GArray **out_param)
659 {
660         GSList *l;
661         _bt_mesh_cdb_t *cdb_cfg = NULL;
662
663         /* Find CDB */
664         l = g_slist_find_custom(cdb_list, network->token.token,
665                         __mesh_compare_app_cdb_token);
666         if (!l)
667                 return BLUETOOTH_ERROR_INVALID_PARAM;
668
669         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
670
671         if (_bt_mesh_keys_get_netkey_list(cdb_cfg->uuid, out_param))
672                 return BLUETOOTH_ERROR_NONE;
673         else
674                 return BLUETOOTH_ERROR_INTERNAL;
675 }
676
677 int _bt_mesh_network_get_appkeys(const char *app_cred, const char *sender,
678                 bluetooth_mesh_network_t *network,  uint16_t net_idx,
679                         GArray **out_param)
680 {
681         GSList *l;
682         _bt_mesh_cdb_t *cdb_cfg = NULL;
683
684         /* Find CDB */
685         l = g_slist_find_custom(cdb_list, network->token.token,
686                         __mesh_compare_app_cdb_token);
687         if (!l)
688                 return BLUETOOTH_ERROR_INVALID_PARAM;
689
690         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
691
692         if (_bt_mesh_keys_get_appkey_list(cdb_cfg->uuid,
693                                 net_idx, out_param))
694                 return BLUETOOTH_ERROR_NONE;
695         else
696                 return BLUETOOTH_ERROR_INTERNAL;
697 }
698
699 int _bt_mesh_network_node_get_netkeys(const char *app_cred,
700         bluetooth_mesh_node_discover_t *node,
701                 GArray **out_param)
702 {
703         GSList *l;
704         _bt_mesh_cdb_t *cdb_cfg = NULL;
705         uint8_t net_uuid[16];
706
707         _bt_mesh_util_convert_string_to_hex(node->net_uuid,
708                         strlen(node->net_uuid), net_uuid, 16);
709
710         /* Find CDB */
711         l = g_slist_find_custom(cdb_list, net_uuid,
712                         __mesh_compare_app_network_uuid);
713         if (!l)
714                 return BLUETOOTH_ERROR_INVALID_PARAM;
715
716         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
717
718         if (_bt_mesh_node_get_all_netkeys(cdb_cfg->uuid,
719                                 node->unicast, out_param))
720                 return BLUETOOTH_ERROR_NONE;
721         else
722                 return BLUETOOTH_ERROR_INTERNAL;
723 }
724
725 int _bt_mesh_network_node_get_appkeys(const char *app_cred,
726                 const char *sender, bluetooth_mesh_node_discover_t *node,
727                          GArray **out_param)
728 {
729         GSList *l;
730         _bt_mesh_cdb_t *cdb_cfg = NULL;
731         uint8_t net_uuid[16];
732
733         _bt_mesh_util_convert_string_to_hex(node->net_uuid,
734                         strlen(node->net_uuid), net_uuid, 16);
735
736         /* Find CDB */
737         l = g_slist_find_custom(cdb_list, net_uuid,
738                         __mesh_compare_app_network_uuid);
739         if (!l)
740                 return BLUETOOTH_ERROR_INVALID_PARAM;
741
742         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
743
744         if (_bt_mesh_node_get_all_appkeys(cdb_cfg->uuid,
745                                 node->unicast, node->netkey_idx, out_param))
746                 return BLUETOOTH_ERROR_NONE;
747         else
748                 return BLUETOOTH_ERROR_INTERNAL;
749 }
750
751 int _bt_mesh_element_get_models(const char *app_cred, const char *sender,
752                 bluetooth_mesh_network_t *network,  uint16_t unicast,
753                         int elem_idx, GArray **out_param)
754 {
755         GSList *l;
756         _bt_mesh_cdb_t *cdb_cfg = NULL;
757
758         /* Find CDB */
759         l = g_slist_find_custom(cdb_list, network->token.token,
760                         __mesh_compare_app_cdb_token);
761         if (!l)
762                 return BLUETOOTH_ERROR_INVALID_PARAM;
763
764         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
765
766         if (_bt_mesh_node_get_models(cdb_cfg->uuid, unicast,
767                                 elem_idx, out_param))
768                 return BLUETOOTH_ERROR_NONE;
769         else
770                 return BLUETOOTH_ERROR_INTERNAL;
771 }
772
773 int _bt_mesh_network_handle_netkey_added(
774                 uint8_t net_uuid[], uint16_t netkey_idx)
775 {
776         GSList *l;
777         _bt_mesh_cdb_t *cdb_cfg = NULL;
778
779         BT_INFO("Mesh: Handle Netkey Added");
780         /* Find CDB */
781         l = g_slist_find_custom(cdb_list, net_uuid,
782                         __mesh_compare_app_network_uuid);
783         if (!l)
784                 return BLUETOOTH_ERROR_INVALID_PARAM;
785
786         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
787
788         _bt_mesh_keys_add_net_key(cdb_cfg->uuid, netkey_idx);
789
790         if (!_bt_mesh_conf_insert_network_key(cdb_cfg,
791                         netkey_idx, MESH_KEY_REFRESH_PHASE_NONE))
792                 return BLUETOOTH_ERROR_INTERNAL;
793
794         return BLUETOOTH_ERROR_NONE;
795 }
796
797 int _bt_mesh_network_handle_netkey_deleted(
798         uint8_t net_uuid[], uint16_t netkey_idx)
799 {
800         GSList *l;
801         _bt_mesh_cdb_t *cdb_cfg = NULL;
802
803         BT_INFO("Mesh: Handle Netkey Deleted");
804         /* Find CDB */
805         l = g_slist_find_custom(cdb_list, net_uuid,
806                 __mesh_compare_app_network_uuid);
807         if (!l)
808                 return BLUETOOTH_ERROR_INVALID_PARAM;
809
810         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
811
812         _bt_mesh_keys_del_net_key(cdb_cfg->uuid, netkey_idx, cdb_cfg);
813
814         if (!_bt_mesh_conf_delete_network_key(cdb_cfg, netkey_idx))
815                 return BLUETOOTH_ERROR_INTERNAL;
816
817         return BLUETOOTH_ERROR_NONE;
818 }
819
820 int _bt_mesh_network_handle_netkey_updated(
821                 uint8_t net_uuid[], uint16_t netkey_idx)
822 {
823         GSList *l;
824         _bt_mesh_cdb_t *cdb_cfg = NULL;
825
826         BT_INFO("Mesh: Handle Netkey Updated");
827         /* Find CDB */
828         l = g_slist_find_custom(cdb_list, net_uuid,
829                         __mesh_compare_app_network_uuid);
830         if (!l)
831                 return BLUETOOTH_ERROR_INVALID_PARAM;
832
833         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
834
835         _bt_mesh_keys_set_net_key_phase(cdb_cfg,
836                 netkey_idx, MESH_KEY_REFRESH_PHASE_ONE, true);
837
838         return BLUETOOTH_ERROR_NONE;
839 }
840
841 int _bt_mesh_network_handle_appkey_added(uint8_t net_uuid[],
842                 uint16_t netkey_idx, uint16_t appkey_idx)
843 {
844         GSList *l;
845         _bt_mesh_cdb_t *cdb_cfg = NULL;
846
847         BT_INFO("Mesh: Handle Appkey Added");
848         /* Find CDB */
849         l = g_slist_find_custom(cdb_list, net_uuid,
850                         __mesh_compare_app_network_uuid);
851         if (!l)
852                 return BLUETOOTH_ERROR_INVALID_PARAM;
853
854         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
855
856         _bt_mesh_keys_add_app_key(cdb_cfg->uuid,
857                         netkey_idx, appkey_idx);
858
859         if (!_bt_mesh_conf_insert_application_key(cdb_cfg,
860                                 netkey_idx, appkey_idx))
861                 return BLUETOOTH_ERROR_INTERNAL;
862
863         return BLUETOOTH_ERROR_NONE;
864 }
865
866 int _bt_mesh_network_handle_appkey_deleted(uint8_t net_uuid[],
867                 uint16_t netkey_idx, uint16_t appkey_idx)
868 {
869         GSList *l;
870         _bt_mesh_cdb_t *cdb_cfg = NULL;
871
872         BT_INFO("Mesh: Handle Appkey Deleted");
873         /* Find CDB */
874         l = g_slist_find_custom(cdb_list, net_uuid,
875                 __mesh_compare_app_network_uuid);
876         if (!l)
877                 return BLUETOOTH_ERROR_INVALID_PARAM;
878
879         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
880
881         _bt_mesh_keys_del_app_key(cdb_cfg->uuid, appkey_idx);
882
883         if (!_bt_mesh_conf_delete_application_key(cdb_cfg, appkey_idx))
884                 return BLUETOOTH_ERROR_INTERNAL;
885
886         return BLUETOOTH_ERROR_NONE;
887 }
888
889 int _bt_mesh_network_set_name(const char *app_cred, const char *sender,
890         bluetooth_mesh_network_t *network)
891 {
892         GSList *l;
893         _bt_mesh_cdb_t *cdb_cfg = NULL;
894         BT_INFO("Mesh: Set network name, app_creds [%s]", app_cred);
895         BT_INFO("Mesh: UUID [%s]", network->uuid);
896         BT_INFO("Mesh: Token[%s]", network->token.token);
897         BT_INFO("Mesh: Name to be set[%s]", network->name.name);
898
899         /* Find CDB */
900         l = g_slist_find_custom(cdb_list,
901                 network->token.token, __mesh_compare_app_cdb_token);
902         if (!l)
903                 return BLUETOOTH_ERROR_INVALID_PARAM;
904
905         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
906         if (_bt_mesh_conf_set_network_friendly_name(cdb_cfg, network->name.name))
907                 return BLUETOOTH_ERROR_NONE;
908
909         return BLUETOOTH_ERROR_INTERNAL;
910 }
911
912 int _bt_mesh_network_add_netkey(const char *app_cred,
913                 const char *sender, bluetooth_mesh_network_t *network)
914 {
915         int ret = OAL_STATUS_SUCCESS;
916         GSList *l;
917         _bt_mesh_cdb_t *cdb_cfg = NULL;
918         oal_uuid_t net_uuid;
919         oal_mesh_key_op_e op = OAL_MESH_KEY_ADD;
920         uint16_t idx;
921
922         /* Find CDB */
923         l = g_slist_find_custom(cdb_list,
924                 network->token.token, __mesh_compare_app_cdb_token);
925         if (!l)
926                 return BLUETOOTH_ERROR_INVALID_PARAM;
927
928         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
929
930         if (!_bt_mesh_keys_get_new_netkey_index(cdb_cfg->uuid, &idx))
931                 return BLUETOOTH_ERROR_INVALID_PARAM;
932
933         _bt_mesh_util_convert_string_to_hex(network->uuid,
934                 strlen(network->uuid), net_uuid.uuid, 16);
935
936         BT_INFO("Mesh: netkey index to be created [%u]", idx);
937         ret = mesh_network_subnet_execute(&net_uuid, op, idx);
938
939         if (ret != OAL_STATUS_SUCCESS) {
940                 BT_ERR("ret: %d", ret);
941                 return BLUETOOTH_ERROR_INTERNAL;
942         }
943
944         return BLUETOOTH_ERROR_NONE;
945 }
946
947 int _bt_mesh_network_delete_netkey(const char *app_cred,
948         const char *sender, bluetooth_mesh_network_t *network,
949                 uint16_t index)
950 {
951         int ret = OAL_STATUS_SUCCESS;
952         GSList *l;
953         _bt_mesh_cdb_t *cdb_cfg = NULL;
954         oal_uuid_t net_uuid;
955         oal_mesh_key_op_e op = OAL_MESH_KEY_DELETE;
956
957         /* Find CDB */
958         l = g_slist_find_custom(cdb_list, network->token.token,
959                         __mesh_compare_app_cdb_token);
960         if (!l)
961                 return BLUETOOTH_ERROR_INVALID_PARAM;
962
963         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
964
965         /* Check if NetKey entry is present in local Network */
966         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, index))
967                 return BLUETOOTH_ERROR_INVALID_PARAM;
968
969         /* Check if NetKey is already added to one of the provisioned nodes */
970         if (_bt_mesh_node_is_netkey_added_in_network(cdb_cfg->uuid, index)) {
971                 BT_INFO("Mesh: NetKey index [0x%2.2x] can not be deleted", index);
972                 return BLUETOOTH_ERROR_INVALID_PARAM;
973         }
974
975         _bt_mesh_util_convert_string_to_hex(network->uuid,
976                         strlen(network->uuid), net_uuid.uuid, 16);
977
978         BT_INFO("Mesh: netkey index to be deleted [%u]", index);
979         ret = mesh_network_subnet_execute(&net_uuid, op, index);
980
981         if (ret != OAL_STATUS_SUCCESS) {
982                 BT_ERR("ret: %d", ret);
983                 return BLUETOOTH_ERROR_INTERNAL;
984         }
985
986         return BLUETOOTH_ERROR_NONE;
987 }
988
989 int _bt_mesh_network_update_netkey(const char *app_cred,
990         const char *sender, bluetooth_mesh_network_t *network,
991                 uint16_t index)
992 {
993         int ret = OAL_STATUS_SUCCESS;
994         GSList *l;
995         _bt_mesh_cdb_t *cdb_cfg = NULL;
996         oal_uuid_t net_uuid;
997         oal_mesh_key_op_e op = OAL_MESH_KEY_UPDATE;
998
999         /* Find CDB */
1000         l = g_slist_find_custom(cdb_list, network->token.token,
1001                         __mesh_compare_app_cdb_token);
1002         if (!l)
1003                 return BLUETOOTH_ERROR_INVALID_PARAM;
1004
1005         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1006
1007         /* Check if NetKey entry is present in local Network */
1008         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, index))
1009                 return BLUETOOTH_ERROR_INVALID_PARAM;
1010
1011         _bt_mesh_util_convert_string_to_hex(network->uuid,
1012                         strlen(network->uuid), net_uuid.uuid, 16);
1013
1014         BT_INFO("Mesh: netkey index to be updated [%u]", index);
1015         ret = mesh_network_subnet_execute(&net_uuid, op, index);
1016
1017         if (ret != OAL_STATUS_SUCCESS) {
1018                 BT_ERR("ret: %d", ret);
1019                 return BLUETOOTH_ERROR_INTERNAL;
1020         }
1021
1022         return BLUETOOTH_ERROR_NONE;
1023 }
1024
1025 int _bt_mesh_network_add_appkey(const char *app_cred,
1026         const char *sender, bluetooth_mesh_network_t *network,
1027                 uint16_t netkey_idx)
1028 {
1029         int ret = OAL_STATUS_SUCCESS;
1030         GSList *l;
1031         _bt_mesh_cdb_t *cdb_cfg = NULL;
1032         oal_uuid_t net_uuid;
1033         oal_mesh_key_op_e op = OAL_MESH_KEY_ADD;
1034         uint16_t idx;
1035
1036         /* Find CDB */
1037         l = g_slist_find_custom(cdb_list, network->token.token,
1038                 __mesh_compare_app_cdb_token);
1039         if (!l)
1040                 return BLUETOOTH_ERROR_INVALID_PARAM;
1041
1042         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1043
1044         /* Check if NetKey entry is present in local Network */
1045         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1046                 return BLUETOOTH_ERROR_INVALID_PARAM;
1047
1048         if (!_bt_mesh_keys_get_new_appkey_index(cdb_cfg->uuid, &idx))
1049                 return BLUETOOTH_ERROR_INVALID_PARAM;
1050
1051         _bt_mesh_util_convert_string_to_hex(network->uuid,
1052                 strlen(network->uuid), net_uuid.uuid, 16);
1053
1054         BT_INFO("Mesh: AppKey index to be created [%u]", idx);
1055         ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, idx);
1056
1057         if (ret != OAL_STATUS_SUCCESS) {
1058                 BT_ERR("ret: %d", ret);
1059                 return BLUETOOTH_ERROR_INTERNAL;
1060         }
1061
1062         return BLUETOOTH_ERROR_NONE;
1063 }
1064
1065 int _bt_mesh_network_update_appkey(const char *app_cred,
1066         const char *sender, bluetooth_mesh_network_t *network,
1067                 uint16_t netkey_idx, uint16_t appkey_idx)
1068 {
1069         int ret = OAL_STATUS_SUCCESS;
1070         GSList *l;
1071         _bt_mesh_cdb_t *cdb_cfg = NULL;
1072         oal_uuid_t net_uuid;
1073         oal_mesh_key_op_e op = OAL_MESH_KEY_UPDATE;
1074
1075         /* Find CDB */
1076         l = g_slist_find_custom(cdb_list, network->token.token,
1077                         __mesh_compare_app_cdb_token);
1078         if (!l)
1079                 return BLUETOOTH_ERROR_INVALID_PARAM;
1080
1081         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1082
1083         /* Check if NetKey entry is present in local Network */
1084         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1085                 return BLUETOOTH_ERROR_INVALID_PARAM;
1086
1087         _bt_mesh_util_convert_string_to_hex(network->uuid,
1088                         strlen(network->uuid), net_uuid.uuid, 16);
1089
1090         BT_INFO("Mesh: AppKey index to be updated [%u]", appkey_idx);
1091         ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, appkey_idx);
1092
1093         if (ret != OAL_STATUS_SUCCESS) {
1094                 BT_ERR("ret: %d", ret);
1095                 return BLUETOOTH_ERROR_INTERNAL;
1096         }
1097
1098         return BLUETOOTH_ERROR_NONE;
1099 }
1100
1101 int _bt_mesh_network_delete_appkey(const char *app_cred,
1102         const char *sender, bluetooth_mesh_network_t *network,
1103                 uint16_t netkey_idx, uint16_t appkey_idx)
1104 {
1105         int ret = OAL_STATUS_SUCCESS;
1106         GSList *l;
1107         _bt_mesh_cdb_t *cdb_cfg = NULL;
1108         oal_uuid_t net_uuid;
1109         oal_mesh_key_op_e op = OAL_MESH_KEY_DELETE;
1110
1111         /* Find CDB */
1112         l = g_slist_find_custom(cdb_list, network->token.token,
1113                         __mesh_compare_app_cdb_token);
1114         if (!l)
1115                 return BLUETOOTH_ERROR_INVALID_PARAM;
1116
1117         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1118
1119         /* Check if NetKey entry is present in local Network */
1120         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1121                 return BLUETOOTH_ERROR_INVALID_PARAM;
1122
1123         /* Check if AppKey is already added to one of the provisioned nodes */
1124         if (_bt_mesh_node_is_appkey_added_in_network(cdb_cfg->uuid, appkey_idx))
1125                 return BLUETOOTH_ERROR_INVALID_PARAM;
1126
1127         _bt_mesh_util_convert_string_to_hex(network->uuid,
1128                         strlen(network->uuid), net_uuid.uuid, 16);
1129
1130         BT_INFO("Mesh: AppKey index to be deleted [%u]", appkey_idx);
1131         ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, appkey_idx);
1132
1133         if (ret != OAL_STATUS_SUCCESS) {
1134                 BT_ERR("ret: %d", ret);
1135                 return BLUETOOTH_ERROR_INTERNAL;
1136         }
1137
1138         return BLUETOOTH_ERROR_NONE;
1139 }
1140
1141 int _bt_mesh_network_create(const char *app_cred, const char *sender,
1142                 const char *network_name, bluetooth_mesh_node_t *node,
1143                         GSList *model_list)
1144 {
1145         int ret = OAL_STATUS_SUCCESS;
1146
1147         BT_INFO("Mesh: App Credential#### [%s] sender [%s] network [%s]",
1148                         app_cred, sender, network_name);
1149
1150         /* TODO Handle Buzy status */
1151         /* Sanity Check: CDB directory creation */
1152         if (!_bt_mesh_util_is_directory_exists(MESH_CDB_DEFAULT_DIR_PATH)) {
1153                 BT_INFO("MESH: CDB directory does not exist");
1154                 if (!_bt_mesh_util_create_directory(MESH_CDB_DEFAULT_DIR_PATH)) {
1155                         BT_ERR("MESH: Fail to create Mesh CDB directory");
1156                         return BLUETOOTH_ERROR_INTERNAL;
1157                 }
1158         }
1159
1160         BT_INFO("Mesh: Send Local Network Creation Request to OAL");
1161
1162         /* Register Mesh Node */
1163         ret = mesh_register_node((oal_mesh_node_t*)node, model_list, true);
1164         if (ret != OAL_STATUS_SUCCESS) {
1165                 BT_ERR("ret: %d", ret);
1166                 return BLUETOOTH_ERROR_INTERNAL;
1167         }
1168
1169         BT_INFO("Mesh: Request Sent to Stack successfully");
1170         /* Create a temporary node & wait for Network Created event */
1171         mesh_local_node_t *temp = g_malloc0(sizeof(mesh_local_node_t));
1172         memcpy(temp->node_uuid, node->uuid, 16);
1173         temp->num_elems = node->num_elements;
1174         temp->prim_unicast = node->primary_unicast;
1175         temp->sender = g_strdup(sender);
1176         temp->app_cred = g_strdup(app_cred);
1177         temp->vendor_info = node->vendor_info;
1178         temp->model_list = model_list;
1179         temp_nodes = g_slist_append(temp_nodes, temp);
1180
1181         return BLUETOOTH_ERROR_NONE;
1182 }
1183
1184 bool _bt_mesh_network_save_remote_node_appkey(
1185                 uint8_t net_uuid[], uint16_t remote_unicast,
1186                         uint16_t netkey_idx, uint16_t appkey_idx)
1187 {
1188         GSList *l;
1189         _bt_mesh_cdb_t *cdb_cfg = NULL;
1190
1191         BT_INFO("Mesh: Add Appkey [0x%2.2x] to node", appkey_idx);
1192         /* Find CDB */
1193         l = g_slist_find_custom(cdb_list, net_uuid,
1194                         __mesh_compare_app_network_uuid);
1195         if (!l)
1196                 return false;
1197
1198         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1199
1200         if (_bt_mesh_node_is_appkey_exists(net_uuid,
1201                         remote_unicast, appkey_idx)) {
1202                 BT_INFO("Mesh: AppKey is already added to Node");
1203                 return true;
1204         }
1205         if (_bt_mesh_node_add_app_key(net_uuid,
1206                         remote_unicast, appkey_idx)) {
1207                 BT_INFO("Mesh: Add App Key Idx [0x%2.2x] in CDB", appkey_idx);
1208                 return _bt_mesh_conf_node_insert_application_key(cdb_cfg,
1209                                         remote_unicast, appkey_idx);
1210         }
1211
1212         BT_INFO("Mesh: AppKey idx [0x%2.2x] Failed to add in Node", appkey_idx);
1213         return false;
1214 }
1215
1216 bool _bt_mesh_network_delete_remote_node_appkey(
1217                 uint8_t net_uuid[], uint16_t remote_unicast,
1218                                 uint16_t netkey_idx, uint16_t appkey_idx)
1219 {
1220         GSList *l;
1221         _bt_mesh_cdb_t *cdb_cfg = NULL;
1222         bool is_deleted = false;
1223
1224         BT_INFO("Mesh: Delete Appkey Idx[0x%2.2x]from Node Unicast [0x%2.2x]",
1225                                 appkey_idx, remote_unicast);
1226         /* Find CDB */
1227         l = g_slist_find_custom(cdb_list, net_uuid,
1228                         __mesh_compare_app_network_uuid);
1229         if (!l)
1230                 return false;
1231
1232         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1233
1234         if (_bt_mesh_node_del_app_key(net_uuid,
1235                         remote_unicast, appkey_idx)) {
1236                 BT_INFO("Mesh: Removed Appkey from node");
1237                 is_deleted =  _bt_mesh_conf_node_delete_application_key(cdb_cfg,
1238                                 remote_unicast, appkey_idx);
1239                 if (is_deleted)
1240                         BT_INFO("Mesh: AppKey removed from CDB Node Entry");
1241                 else
1242                         BT_INFO("Mesh: AppKey could not be removed from CDB Node Entry");
1243         }
1244
1245         return is_deleted;
1246 }
1247
1248 bool _bt_mesh_network_save_remote_node_ttl(
1249         uint8_t net_uuid[], uint16_t remote_unicast,
1250                         uint8_t ttl)
1251 {
1252         GSList *l;
1253         _bt_mesh_cdb_t *cdb_cfg = NULL;
1254
1255         /* Find CDB */
1256         l = g_slist_find_custom(cdb_list, net_uuid,
1257                         __mesh_compare_app_network_uuid);
1258         if (!l)
1259                 return false;
1260
1261         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1262
1263         return _bt_mesh_conf_node_set_timetolive_value(cdb_cfg,
1264                                 remote_unicast, ttl);
1265 }
1266
1267 bool _bt_mesh_network_save_remote_node_netkey(
1268                 uint8_t net_uuid[], uint16_t remote_unicast,
1269                                 uint16_t netkey_idx)
1270 {
1271         GSList *l;
1272         _bt_mesh_cdb_t *cdb_cfg = NULL;
1273
1274         /* Find CDB */
1275         l = g_slist_find_custom(cdb_list, net_uuid,
1276                         __mesh_compare_app_network_uuid);
1277         if (!l)
1278                 return false;
1279
1280         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1281
1282         if (_bt_mesh_node_is_netkey_exists(net_uuid,
1283                         remote_unicast, netkey_idx)) {
1284                 BT_INFO("Mesh: NetKey is already added to Node");
1285                 return true;
1286         }
1287         if (_bt_mesh_node_add_net_key(net_uuid,
1288                         remote_unicast, netkey_idx))
1289                 return _bt_mesh_conf_node_insert_network_key(cdb_cfg,
1290                                         remote_unicast, netkey_idx);
1291
1292         return false;
1293 }
1294
1295 bool _bt_mesh_network_delete_remote_node_netkey(
1296                 uint8_t net_uuid[], uint16_t remote_unicast,
1297                         uint16_t netkey_idx)
1298 {
1299         GSList *l;
1300         _bt_mesh_cdb_t *cdb_cfg = NULL;
1301
1302         /* Find CDB */
1303         l = g_slist_find_custom(cdb_list, net_uuid,
1304                         __mesh_compare_app_network_uuid);
1305         if (!l)
1306                 return false;
1307
1308         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1309
1310         if (_bt_mesh_node_del_net_key(cdb_cfg, net_uuid,
1311                         remote_unicast, netkey_idx))
1312                 return _bt_mesh_conf_node_delete_network_key(cdb_cfg,
1313                                 remote_unicast, netkey_idx);
1314         return false;
1315 }
1316
1317 bool _bt_mesh_network_save_remote_node_composition(
1318                 uint8_t net_uuid[], uint16_t remote_unicast,
1319                                 uint8_t *data, uint16_t data_len)
1320 {
1321         GSList *l;
1322         _bt_mesh_cdb_t *cdb_cfg = NULL;
1323
1324         /* Find CDB */
1325         l = g_slist_find_custom(cdb_list, net_uuid,
1326                 __mesh_compare_app_network_uuid);
1327         if (!l)
1328                 return false;
1329
1330         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1331
1332         return _bt_mesh_conf_set_node_comp_data(cdb_cfg,
1333                         remote_unicast, data, data_len);
1334 }
1335
1336 int _bt_mesh_network_add_remote_node(uint8_t net_uuid[],
1337         uint8_t dev_uuid[], uint16_t unicast, uint8_t count)
1338 {
1339         GSList *l;
1340         _bt_mesh_cdb_t *cdb_cfg = NULL;
1341
1342         /* Find CDB */
1343         l = g_slist_find_custom(cdb_list, net_uuid,
1344                         __mesh_compare_app_network_uuid);
1345         if (!l)
1346                 return BLUETOOTH_ERROR_INVALID_PARAM;
1347
1348         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1349
1350         _bt_mesh_node_add_node(net_uuid, dev_uuid,
1351                         unicast, count, MESH_PRIMARY_NET_IDX);
1352
1353         /* Add Remote Node entry in CDB */
1354         _bt_mesh_conf_insert_node_object(cdb_cfg, /* Dev UUID */ dev_uuid,
1355                         count, unicast, MESH_PRIMARY_NET_IDX);
1356
1357         return BLUETOOTH_ERROR_NONE;
1358 }
1359
1360 bool _bt_mesh_node_get_vendor_features(uint8_t net_uuid[],
1361         uint16_t unicast, bluetooth_mesh_node_features_t *feats)
1362 {
1363         GSList *l;
1364         _bt_mesh_cdb_t *cdb_cfg = NULL;
1365         BT_INFO("Mesh: Attempt to get vendor features: unicast [0x%2.2x]", unicast);
1366         /* Find CDB */
1367         l = g_slist_find_custom(cdb_list, net_uuid,
1368                         __mesh_compare_app_network_uuid);
1369         if (!l)
1370                 return false;
1371
1372         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1373
1374         BT_INFO("Mesh: Read Vendor Features from CDB");
1375         return _bt_mesh_conf_fetch_vendor_specific_info(cdb_cfg, unicast,
1376                         &feats->vendor_info.companyid, &feats->vendor_info.vendorid,
1377                         &feats->vendor_info.versionid, &feats->vendor_info.crpl,
1378                         &feats->features.relay, &feats->features.frnd,
1379                         &feats->features.proxy, &feats->features.lpn);
1380 }
1381
1382 int _bt_mesh_network_load_cdb(int result, const char *sender,
1383                 const char *app_creds,
1384                         uint8_t uuid[16], uint8_t token[8],
1385                                          char **network)
1386 {
1387         GSList *l;
1388         char *token_str;
1389         _bt_mesh_cdb_t *cdb_cfg = NULL;
1390
1391         token_str = _bt_service_convert_hex_to_string(token, 8);
1392
1393         /* Find CDB */
1394         l = g_slist_find_custom(cdb_list, token_str,
1395                         __mesh_compare_app_cdb_token);
1396         if (!l)
1397                 return BLUETOOTH_ERROR_INTERNAL;
1398
1399         g_free(token_str);
1400         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1401
1402         if (result != BLUETOOTH_ERROR_NONE)
1403                 goto failed;
1404
1405         /* Create new network for saving network specific Keys */
1406         _bt_mesh_keys_load_net(cdb_cfg->uuid);
1407         if (!_bt_mesh_conf_load_all_keys(cdb_cfg)) {
1408                 _bt_mesh_keys_unload_net(cdb_cfg->uuid);
1409                 goto failed;
1410         }
1411
1412         /* Create new network for saving network specific nodes */
1413         _bt_mesh_node_load_net(cdb_cfg->uuid);
1414         if (!_bt_mesh_conf_load_all_nodes(cdb_cfg)) {
1415                 _bt_mesh_node_unload_net(cdb_cfg->uuid);
1416                 goto failed;
1417         }
1418
1419         /* Load Groups Created */
1420         cdb_cfg->groups = _bt_mesh_conf_load_group_info(cdb_cfg);
1421
1422         /* Fetch Network name */
1423         *network = (char*)_bt_mesh_conf_get_network_friendly_name(cdb_cfg);
1424         BT_INFO("Mesh: Attached Network [%s]", *network);
1425         return BLUETOOTH_ERROR_NONE;
1426 failed:
1427         /* Free the CDB object */
1428         _bt_mesh_conf_free(cdb_cfg);
1429         return BLUETOOTH_ERROR_INTERNAL;
1430 }
1431
1432 int _bt_mesh_network_load(const char *app_cred,
1433         const char *sender, const char *token)
1434 {
1435         int ret = OAL_STATUS_SUCCESS;
1436         GSList *l;
1437         char *dir_path = NULL;
1438         _bt_mesh_cdb_t *cdb_cfg = NULL;
1439         oal_mesh_node_t node;
1440         GSList *models = NULL;
1441
1442         /* Check CDB directory exist or not */
1443         dir_path = g_strdup_printf(MESH_CDB_DEFAULT_DIR_PATH"/%s/", "default");
1444         if (!_bt_mesh_util_is_directory_exists(dir_path)) {
1445                 BT_ERR("Mesh: CDB dir [%s]does not exist for app", dir_path);
1446                 g_free(dir_path);
1447                 return BLUETOOTH_ERROR_INTERNAL;
1448         }
1449
1450         /* Find CDB */
1451         l = g_slist_find_custom(cdb_list, token,
1452                         __mesh_compare_app_cdb_token);
1453         if (l) {
1454                 BT_INFO("Mesh: Already loaded");
1455                 g_free(dir_path);
1456                 return BLUETOOTH_ERROR_NONE;
1457         } else {
1458                 BT_INFO("Mesh: Not loaded");
1459                 /* Attempt to load CDB's present in app's
1460                    CDB directory */
1461                 const char *filename;
1462                 GDir *dir = g_dir_open(dir_path, 0, NULL);
1463                 if (!dir) {
1464                         BT_ERR("Mesh: Could not open directory");
1465                         g_free(dir_path);
1466                         return BLUETOOTH_ERROR_INTERNAL;
1467                 }
1468                 g_free(dir_path);
1469                 while ((filename = g_dir_read_name(dir)) != NULL) {
1470
1471                         if ((g_file_test(filename, G_FILE_TEST_IS_SYMLINK) == TRUE) ||
1472                                         (g_str_has_suffix(filename, ".json") == FALSE))
1473                                 continue;
1474
1475                         BT_INFO("Mesh: File name [%s]", filename);
1476                         cdb_cfg = _bt_mesh_conf_load(filename, token);
1477                         if (cdb_cfg)
1478                                 break;
1479                 }
1480         }
1481
1482         if (!cdb_cfg) {
1483                 BT_ERR("Mesh: Could not find CDB for the token!! Possibly not authorized!!");
1484                 return BLUETOOTH_ERROR_ACCESS_DENIED;
1485         }
1486
1487         /* Fill the Mesh node info  */
1488         memset(&node, 0x00, sizeof(oal_mesh_node_t));
1489         memcpy(node.uuid.uuid, cdb_cfg->uuid, sizeof(oal_uuid_t));
1490         _bt_mesh_util_convert_string_to_hex(token, strlen(token), node.token.u8, 8);
1491         if (!_bt_mesh_conf_get_element_count(cdb_cfg, &node.num_elements)) {
1492                 _bt_mesh_conf_free(cdb_cfg);
1493                 return BLUETOOTH_ERROR_INTERNAL;
1494         }
1495
1496         if (!_bt_mesh_conf_fetch_vendor_specific_info(cdb_cfg, 0x0001 /* Local Node Unicast */,
1497                                 &node.vendor_info.companyid, &node.vendor_info.vendorid,
1498                                 &node.vendor_info.versionid, &node.vendor_info.crpl,
1499                                 &node.vendor_info.relay, &node.vendor_info.frnd,
1500                                 &node.vendor_info.proxy, &node.vendor_info.lpn)) {
1501
1502                 _bt_mesh_conf_free(cdb_cfg);
1503                 return BLUETOOTH_ERROR_INTERNAL;
1504         }
1505
1506         for (int i = 0; i < node.num_elements; i++) {
1507                 int num_models;
1508                 uint16_t **model_array = _bt_mesh_conf_get_all_model_info(
1509                                 cdb_cfg, i, &num_models);
1510                 if (!model_array) {
1511                         _bt_mesh_conf_free(cdb_cfg);
1512                         return BLUETOOTH_ERROR_INTERNAL;
1513                 }
1514
1515                 for (int j = 0; j < num_models; j++) {
1516                         bluetooth_mesh_model_t *mod;
1517                         mod = g_malloc0(sizeof(bluetooth_mesh_model_t));
1518                         mod->elem_index = i;
1519                         mod->model_id = *model_array[j];
1520                         models = g_slist_append(models, mod);
1521                 }
1522                 /* Free all model(s) */
1523                 for (int j = 0; j < num_models; j++)
1524                         g_free(model_array[j]);
1525         }
1526
1527         /* Register Mesh Node */
1528         ret = mesh_register_node((oal_mesh_node_t*)&node,
1529                         models, true);
1530
1531         /* Cleanup */
1532         g_slist_free_full(models, g_free);
1533
1534         if (ret != OAL_STATUS_SUCCESS) {
1535                 BT_ERR("Mesh: Load Network Failed ret: %d", ret);
1536                 _bt_mesh_conf_free(cdb_cfg);
1537                 return BLUETOOTH_ERROR_INTERNAL;
1538         }
1539
1540         /* Save till Network attached */
1541         cdb_list = g_slist_append(cdb_list, cdb_cfg);
1542         return ret;
1543 }
1544
1545 bool _bt_mesh_network_get_label_uuid_from_sub_addr(
1546                 uint8_t net_uuid[],     uint16_t sub_addr,
1547                                 uint8_t label[])
1548 {
1549         GSList *l, *l1;
1550         _bt_mesh_cdb_t *cdb_cfg = NULL;
1551
1552         /* Find CDB */
1553         l = g_slist_find_custom(cdb_list, net_uuid,
1554                         __mesh_compare_app_network_uuid);
1555         if (!l)
1556                 return false;
1557
1558         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1559
1560         l1 = g_slist_find_custom(cdb_cfg->groups,
1561                         GUINT_TO_POINTER(sub_addr), __mesh_compare_addr);
1562
1563         if (!l1)
1564                 return false;
1565         else {
1566                 _bt_mesh_group_t *grp = l1->data;
1567                 memcpy(label, grp->label_uuid, 16);
1568         }
1569         return true;
1570 }
1571
1572 int _bt_mesh_network_remove_group(const char *app_cred,
1573         const char *sender, bluetooth_mesh_network_t *net,
1574                         bluetooth_mesh_network_group_info_t *req)
1575 {
1576         GSList *l, *l1;
1577         _bt_mesh_cdb_t *cdb_cfg = NULL;
1578         _bt_mesh_group_t *grp;
1579         uint8_t net_uuid[16];
1580
1581         _bt_mesh_util_convert_string_to_hex(net->uuid,
1582                         strlen(net->uuid), net_uuid, 16);
1583         /* Find CDB */
1584         l = g_slist_find_custom(cdb_list, net_uuid,
1585                         __mesh_compare_app_network_uuid);
1586         if (!l)
1587                 return BLUETOOTH_ERROR_INVALID_PARAM;
1588
1589         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1590         BT_INFO("Mesh: Total groups stored in network [%d]",
1591                         g_slist_length(cdb_cfg->groups));
1592
1593         l1 = g_slist_find_custom(cdb_cfg->groups,
1594                         GUINT_TO_POINTER(req->group_addr), __mesh_compare_addr);
1595
1596         if (!l1) {
1597                 BT_ERR("Mesh: To be Removed Group: [0x%2.2x] Not Found!", req->group_addr);
1598                 return BLUETOOTH_ERROR_INVALID_PARAM;
1599         }
1600         grp = (_bt_mesh_group_t*)l1->data;
1601
1602         BT_INFO("Mesh: To be Removed Group: [0x%2.2x]", req->group_addr);
1603         if (!_bt_mesh_conf_delete_group_entry(cdb_cfg, req->group_addr)) {
1604                 BT_ERR("Mesh: Failed to remove Group: [0x%2.2x]", req->group_addr);
1605                 return BLUETOOTH_ERROR_INTERNAL;
1606         }
1607
1608         BT_INFO("Mesh: Successfully removed Group: [0x%2.2x]", req->group_addr);
1609         cdb_cfg->groups = g_slist_remove(cdb_cfg->groups, grp);
1610         BT_INFO("Mesh: Total groups after update [%d]",
1611                         g_slist_length(cdb_cfg->groups));
1612
1613         return BLUETOOTH_ERROR_NONE;
1614 }
1615
1616 int _bt_mesh_network_create_group(const char *app_cred,
1617         const char *sender, bluetooth_mesh_network_t *net,
1618                 bool is_virtual, uint16_t addr,
1619                         bluetooth_mesh_network_group_info_t *req)
1620 {
1621         GSList *l, *l1, *l2;
1622         _bt_mesh_cdb_t *cdb_cfg = NULL;
1623         uint8_t net_uuid[16];
1624
1625         _bt_mesh_util_convert_string_to_hex(net->uuid,
1626                         strlen(net->uuid), net_uuid, 16);
1627         /* Find CDB */
1628         l = g_slist_find_custom(cdb_list, net_uuid,
1629                         __mesh_compare_app_network_uuid);
1630         if (!l)
1631                 return BLUETOOTH_ERROR_INVALID_PARAM;
1632
1633         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1634         BT_INFO("Mesh: Total Groups present in Network already [%d]",
1635                         g_slist_length(cdb_cfg->groups));
1636
1637         if (is_virtual) {
1638                 uint8_t max_tries = 5;
1639                 _bt_mesh_group_t *grp = NULL;
1640                 grp = g_malloc0(sizeof(_bt_mesh_group_t));
1641                 BT_INFO("Mesh: Network Create Virtual group");
1642 retry:
1643                 l_getrandom(grp->label_uuid, 16);
1644                 _bt_mesh_util_crypto_create_virtual_address(
1645                                 grp->label_uuid, &grp->grp_addr);
1646
1647                 /* For simplicity sake, avoid labels that map to the same hash */
1648                 l1 = g_slist_find_custom(cdb_cfg->groups,
1649                                 GUINT_TO_POINTER(grp->grp_addr), __mesh_compare_addr);
1650
1651                 if (!l1) {
1652                         if (!_bt_mesh_conf_insert_group_info(cdb_cfg, grp)) {
1653                                 BT_ERR("Mesh: unable to save group in Conf DB!!");
1654                                 g_free(grp);
1655                                 return BLUETOOTH_ERROR_INTERNAL;
1656                         }
1657                         req->is_virtual = true;
1658                         req->group_addr = grp->grp_addr;
1659                         _bt_mesh_util_convert_hex_to_string(
1660                                         (uint8_t *) grp->label_uuid, 16, req->label_uuid,
1661                                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1662
1663                         cdb_cfg->groups = g_slist_append(cdb_cfg->groups, grp);
1664                         BT_INFO("Mesh: Virtual Group[0x%2.2x] inserted in List",
1665                                         grp->grp_addr);
1666                         BT_INFO("Mesh: Total groups present in Network after update [%d]",
1667                                         g_slist_length(cdb_cfg->groups));
1668                         return BLUETOOTH_ERROR_NONE;
1669                 }
1670
1671                 max_tries--;
1672                 if (max_tries)
1673                         goto retry;
1674
1675                 g_free(grp);
1676                 /* Failed to create a unique hash */
1677                 return BLUETOOTH_ERROR_INTERNAL;
1678         } else {
1679                 BT_INFO("Mesh: Network Create group Addr: [0x%2.2x]", addr);
1680
1681                 if (!MESH_IS_GROUP(addr)) {
1682                         BT_ERR("Mesh: Group Address [0x%2.2x] is not valid!", addr);
1683                         return BLUETOOTH_ERROR_INVALID_PARAM;
1684                 }
1685
1686                 l2 = g_slist_find_custom(cdb_cfg->groups,
1687                                 GUINT_TO_POINTER(addr), __mesh_compare_addr);
1688
1689                 if (l2) {
1690                         _bt_mesh_group_t *grp = l2->data;
1691                         req->is_virtual = false;
1692                         req->group_addr = grp->grp_addr;
1693                         BT_INFO("Mesh: Group already found: addr [0x%2.2x]", grp->grp_addr);
1694                 } else {
1695                         /* Group is not present */
1696                         _bt_mesh_group_t *grp = g_malloc0(sizeof(_bt_mesh_group_t));
1697                         grp->grp_addr = addr;
1698                         if (!_bt_mesh_conf_insert_group_info(cdb_cfg, grp)) {
1699                                 BT_ERR("Mesh: unable to save group in Conf DB!!");
1700                                 g_free(grp);
1701                                 return BLUETOOTH_ERROR_INTERNAL;
1702                         }
1703                         cdb_cfg->groups = g_slist_append(cdb_cfg->groups, grp);
1704                         req->is_virtual = false;
1705                         req->group_addr = grp->grp_addr;
1706                         BT_INFO("Mesh: Group[0x%2.2x] inserted in List",
1707                                 grp->grp_addr);
1708                 }
1709                 BT_INFO("Mesh: Total groups present in Network after update [%d]",
1710                                 g_slist_length(cdb_cfg->groups));
1711
1712         }
1713         return BLUETOOTH_ERROR_NONE;
1714 }
1715
1716 int _bt_mesh_network_get_groups(const char *app_cred, const char *sender,
1717                 bluetooth_mesh_network_t *network,
1718                         GArray **out_param)
1719 {
1720         GSList *l;
1721         _bt_mesh_cdb_t *cdb_cfg = NULL;
1722         uint8_t net_uuid[16];
1723
1724         BT_INFO("Mesh: Get All groups from Network [%s]", network->uuid);
1725         _bt_mesh_util_convert_string_to_hex(network->uuid,
1726                         strlen(network->uuid), net_uuid, 16);
1727         /* Find CDB */
1728         l = g_slist_find_custom(cdb_list, net_uuid,
1729                         __mesh_compare_app_network_uuid);
1730         if (!l)
1731                 return BLUETOOTH_ERROR_INVALID_PARAM;
1732
1733         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1734         BT_INFO("Mesh: Got CDB");
1735
1736         BT_INFO("Mesh: Total groups present in Network [%d]",
1737                         g_slist_length(cdb_cfg->groups));
1738
1739         for (l = cdb_cfg->groups; l; l = l->next) {
1740                 bluetooth_mesh_network_group_info_t grp;
1741                 _bt_mesh_group_t *group = l->data;
1742                 memset(&grp, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
1743                 g_strlcpy(grp.net_uuid, network->uuid, sizeof(grp.net_uuid));
1744                 if (MESH_IS_GROUP(group->grp_addr) && !MESH_IS_VIRTUAL(group->grp_addr)) {
1745                         grp.is_virtual = false;
1746                         grp.group_addr = group->grp_addr;
1747                         BT_INFO("Mesh: Found Non-Virtual group, addr[0x%2.2x]", group->grp_addr);
1748                 } else if (MESH_IS_VIRTUAL(group->grp_addr)) {
1749                         grp.is_virtual = true;
1750                         grp.group_addr = group->grp_addr;
1751                         _bt_mesh_util_convert_hex_to_string((uint8_t *) group->label_uuid,
1752                                         16, grp.label_uuid, sizeof(grp.label_uuid));
1753                         BT_INFO("Mesh: Found Virtual group, addr[0x%2.2x]", group->grp_addr);
1754                         BT_INFO("Mesh: Label UUID[%s]", grp.label_uuid);
1755                 }
1756
1757                 g_array_append_vals(*out_param,
1758                                 &grp, sizeof(bluetooth_mesh_network_group_info_t));
1759         }
1760
1761         return BLUETOOTH_ERROR_NONE;
1762 }
1763
1764 int _bt_mesh_network_get_nodes(const char *app_cred,
1765                 const char *sender, bluetooth_mesh_network_t *network,
1766                         GArray **out_param)
1767 {
1768         GSList *l;
1769         _bt_mesh_cdb_t *cdb_cfg = NULL;
1770
1771         /* Find CDB */
1772         l = g_slist_find_custom(cdb_list, network->token.token,
1773                         __mesh_compare_app_cdb_token);
1774         if (!l)
1775                 return BLUETOOTH_ERROR_INVALID_PARAM;
1776
1777         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1778
1779         if (_bt_mesh_node_get_all(cdb_cfg->uuid, out_param))
1780                 return BLUETOOTH_ERROR_NONE;
1781         else
1782                 return BLUETOOTH_ERROR_INTERNAL;
1783 }