800a26aa35e169456b9bd61cb579ae5e65febc73
[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         _bt_mesh_conf_set_vendor_info(cdb_cfg, 0x0001, tmp->vendor_info.crpl,
434                 tmp->vendor_info.companyid, tmp->vendor_info.versionid,
435                         tmp->vendor_info.vendorid, tmp->vendor_info.proxy,
436                                 tmp->vendor_info.relay, tmp->vendor_info.lpn,
437                                         tmp->vendor_info.frnd);
438
439         BT_INFO("Mesh: Vendor Info set successfully");
440         _bt_mesh_conf_set_model_info(cdb_cfg, 0x0001, tmp->model_list);
441
442         cdb_list = g_slist_append(cdb_list, cdb_cfg);
443         BT_INFO("Mesh: CDB added to list");
444
445         __bt_mesh_free_temp_node(tmp);
446         BT_INFO("Mesh: temp node freed");
447         return BLUETOOTH_ERROR_NONE;
448 }
449
450 int _bt_mesh_network_unload(const char *app_cred,
451                 const char *sender, bluetooth_mesh_network_t *network)
452 {
453         GSList *l;
454         oal_uuid_t net_uuid;
455         _bt_mesh_cdb_t *cdb_cfg;
456         int ret = OAL_STATUS_SUCCESS;
457
458         BT_INFO("Mesh: Unload Network Configuration");
459         /* If Scanning is going on */
460         if (_bt_mesh_is_provisioning() ||
461                         _bt_mesh_is_scanning()) {
462                 BT_ERR("Device is buzy..");
463                 return BLUETOOTH_ERROR_DEVICE_BUSY;
464         }
465
466         _bt_mesh_util_convert_string_to_hex(network->uuid,
467                         strlen(network->uuid), net_uuid.uuid, 16);
468
469         /* Release Mesh Network */
470         ret = mesh_network_release(&net_uuid);
471         if (ret != OAL_STATUS_SUCCESS) {
472                 BT_ERR("ret: %d", ret);
473                 return BLUETOOTH_ERROR_INTERNAL;
474         }
475
476         BT_INFO("Mesh: Network released");
477
478         /* Find CDB */
479         l = g_slist_find_custom(cdb_list, net_uuid.uuid,
480                         __mesh_compare_app_network_uuid);
481         if (!l) {
482                 BT_ERR("Mesh: Could not find Network Entry: unexpected!!");
483                 return BLUETOOTH_ERROR_INVALID_PARAM;
484         }
485
486         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
487
488         _bt_mesh_network_unload_net_configuration(cdb_cfg);
489         return BLUETOOTH_ERROR_NONE;
490 }
491
492 int _bt_mesh_network_destroy(const char *app_cred,
493         const char *sender, bluetooth_mesh_network_t *network)
494 {
495         int ret = OAL_STATUS_SUCCESS;
496         oal_uuid_t net_uuid;
497
498         /* If Scanning is going on */
499         if (_bt_mesh_is_provisioning() ||
500                         _bt_mesh_is_scanning()) {
501                 BT_ERR("Device is buzy..");
502                 return BLUETOOTH_ERROR_DEVICE_BUSY;
503         }
504         _bt_mesh_util_convert_string_to_hex(network->uuid,
505                         strlen(network->uuid), net_uuid.uuid, 16);
506         /* Destroy Mesh Network */
507         ret = mesh_network_destroy(&net_uuid);
508         if (ret != OAL_STATUS_SUCCESS) {
509                 BT_ERR("ret: %d", ret);
510                 return BLUETOOTH_ERROR_INTERNAL;
511         }
512
513         return BLUETOOTH_ERROR_NONE;
514 }
515
516 int _bt_mesh_network_scan(const char *app_cred,
517         const char *sender,
518                 bluetooth_mesh_network_t *network,
519                         bluetooth_mesh_scan_param_t *param)
520 {
521         int ret = OAL_STATUS_SUCCESS;
522         oal_uuid_t net_uuid;
523
524         /* If Scanning is going on */
525         if (_bt_mesh_is_provisioning() ||
526                         _bt_mesh_is_scanning()) {
527                 BT_ERR("Device is buzy..");
528                 return BLUETOOTH_ERROR_DEVICE_BUSY;
529         }
530         _bt_mesh_util_convert_string_to_hex(network->uuid,
531                 strlen(network->uuid), net_uuid.uuid, 16);
532         /* Register Mesh Node */
533         ret = mesh_network_start_scan(&net_uuid,
534                 (oal_mesh_scan_params_t*) param);
535         if (ret != OAL_STATUS_SUCCESS) {
536                 BT_ERR("ret: %d", ret);
537                 return BLUETOOTH_ERROR_INTERNAL;
538         }
539
540         /* Set scanning state to true */
541         _bt_mesh_set_scanning_state(true);
542         return BLUETOOTH_ERROR_NONE;
543 }
544
545 int _bt_mesh_network_scan_cancel(const char *app_cred,
546         const char *sender, bluetooth_mesh_network_t *network)
547 {
548         int ret = OAL_STATUS_SUCCESS;
549         oal_uuid_t net_uuid;
550
551         if (!_bt_mesh_is_scanning()) {
552                 BT_INFO("Mesh: Scanning is not ongoing");
553                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
554         }
555         _bt_mesh_util_convert_string_to_hex(network->uuid,
556                 strlen(network->uuid), net_uuid.uuid, 16);
557
558         /* Cancel unprovisioned device scan */
559         ret = mesh_network_scan_cancel(&net_uuid);
560         if (ret != OAL_STATUS_SUCCESS) {
561                 BT_ERR("ret: %d", ret);
562                 return BLUETOOTH_ERROR_INTERNAL;
563         }
564
565         return BLUETOOTH_ERROR_NONE;
566 }
567
568 int _bt_mesh_network_set_provisioner_caps(const char *app_cred,
569                 const char *sender, bluetooth_mesh_network_t *network,
570                         bluetooth_mesh_provisioner_caps_t *caps)
571 {
572         int ret = OAL_STATUS_SUCCESS;
573         oal_uuid_t net_uuid;
574
575         _bt_mesh_util_convert_string_to_hex(network->uuid,
576                 strlen(network->uuid), net_uuid.uuid, 16);
577
578         /* Set provisioning capabilities */
579         ret = mesh_network_set_provisioning_capabilities(&net_uuid,
580                 (oal_mesh_capabilities_t*) caps);
581         if (ret != OAL_STATUS_SUCCESS) {
582                 BT_ERR("ret: %d", ret);
583                 return BLUETOOTH_ERROR_INTERNAL;
584         }
585
586         return BLUETOOTH_ERROR_NONE;
587 }
588
589 bool _bt_mesh_is_scanning(void)
590 {
591         return bt_mesh_is_scanning;
592 }
593
594 void _bt_mesh_set_scanning_state(bool state)
595 {
596         bt_mesh_is_scanning = state;
597 }
598
599 bool _bt_mesh_is_provisioning(void)
600 {
601         return bt_mesh_is_provisoning;
602 }
603
604 void _bt_mesh_set_provisioning_state(bool state)
605 {
606         bt_mesh_is_provisoning = state;
607 }
608
609 int _bt_mesh_network_provision_device(const char *app_cred,
610                 const char *sender,
611                         bluetooth_mesh_provisioning_request_t *req)
612 {
613         int ret = OAL_STATUS_SUCCESS;
614         oal_uuid_t net_uuid;
615         oal_uuid_t dev_uuid;
616
617         /* If Scanning is going on */
618         if (_bt_mesh_is_provisioning() ||
619                         _bt_mesh_is_scanning()) {
620                 BT_ERR("Device is buzy..");
621                 return BLUETOOTH_ERROR_DEVICE_BUSY;
622         }
623
624         _bt_mesh_util_convert_string_to_hex(req->net_uuid,
625                 strlen(req->net_uuid), net_uuid.uuid, 16);
626         _bt_mesh_util_convert_string_to_hex(req->dev_uuid,
627                 strlen(req->dev_uuid), dev_uuid.uuid, 16);
628
629         ret = mesh_network_provision_device(&net_uuid, &dev_uuid);
630
631         if (ret != OAL_STATUS_SUCCESS) {
632                 BT_ERR("ret: %d", ret);
633                 return BLUETOOTH_ERROR_INTERNAL;
634         }
635
636         /* Set Provisioning state */
637         _bt_mesh_set_provisioning_state(true);
638
639         return BLUETOOTH_ERROR_NONE;
640 }
641
642 int _bt_mesh_authentication_reply(int auth_type,
643                 const char *auth_value, gboolean reply)
644 {
645         int ret = OAL_STATUS_SUCCESS;
646
647         if (!_bt_mesh_is_provisioning())
648                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
649
650         if (!auth_value)
651                 return BLUETOOTH_ERROR_INVALID_PARAM;
652
653         ret = mesh_authentication_reply(
654                         (oal_mesh_variant_authentication_e)auth_type,
655                         auth_value);
656
657         if (ret != OAL_STATUS_SUCCESS) {
658                 BT_ERR("ret: %d", ret);
659                 return BLUETOOTH_ERROR_INTERNAL;
660         }
661
662         BT_INFO("Mesh: Scheduled Prov Auth Reply!");
663         return BLUETOOTH_ERROR_NONE;
664 }
665
666 int _bt_mesh_network_get_netkeys(const char *app_cred, const char *sender,
667                 bluetooth_mesh_network_t *network,  GArray **out_param)
668 {
669         GSList *l;
670         _bt_mesh_cdb_t *cdb_cfg = NULL;
671
672         /* Find CDB */
673         l = g_slist_find_custom(cdb_list, network->token.token,
674                         __mesh_compare_app_cdb_token);
675         if (!l)
676                 return BLUETOOTH_ERROR_INVALID_PARAM;
677
678         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
679
680         if (_bt_mesh_keys_get_netkey_list(cdb_cfg->uuid, out_param))
681                 return BLUETOOTH_ERROR_NONE;
682         else
683                 return BLUETOOTH_ERROR_INTERNAL;
684 }
685
686 int _bt_mesh_network_get_appkeys(const char *app_cred, const char *sender,
687                 bluetooth_mesh_network_t *network,  uint16_t net_idx,
688                         GArray **out_param)
689 {
690         GSList *l;
691         _bt_mesh_cdb_t *cdb_cfg = NULL;
692
693         /* Find CDB */
694         l = g_slist_find_custom(cdb_list, network->token.token,
695                         __mesh_compare_app_cdb_token);
696         if (!l)
697                 return BLUETOOTH_ERROR_INVALID_PARAM;
698
699         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
700
701         if (_bt_mesh_keys_get_appkey_list(cdb_cfg->uuid,
702                                 net_idx, out_param))
703                 return BLUETOOTH_ERROR_NONE;
704         else
705                 return BLUETOOTH_ERROR_INTERNAL;
706 }
707
708 int _bt_mesh_network_node_get_netkeys(const char *app_cred,
709         bluetooth_mesh_node_discover_t *node,
710                 GArray **out_param)
711 {
712         GSList *l;
713         _bt_mesh_cdb_t *cdb_cfg = NULL;
714         uint8_t net_uuid[16];
715
716         _bt_mesh_util_convert_string_to_hex(node->net_uuid,
717                         strlen(node->net_uuid), net_uuid, 16);
718
719         /* Find CDB */
720         l = g_slist_find_custom(cdb_list, net_uuid,
721                         __mesh_compare_app_network_uuid);
722         if (!l)
723                 return BLUETOOTH_ERROR_INVALID_PARAM;
724
725         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
726
727         if (_bt_mesh_node_get_all_netkeys(cdb_cfg->uuid,
728                                 node->unicast, out_param))
729                 return BLUETOOTH_ERROR_NONE;
730         else
731                 return BLUETOOTH_ERROR_INTERNAL;
732 }
733
734 int _bt_mesh_network_node_get_appkeys(const char *app_cred,
735                 const char *sender, bluetooth_mesh_node_discover_t *node,
736                          GArray **out_param)
737 {
738         GSList *l;
739         _bt_mesh_cdb_t *cdb_cfg = NULL;
740         uint8_t net_uuid[16];
741
742         _bt_mesh_util_convert_string_to_hex(node->net_uuid,
743                         strlen(node->net_uuid), net_uuid, 16);
744
745         /* Find CDB */
746         l = g_slist_find_custom(cdb_list, net_uuid,
747                         __mesh_compare_app_network_uuid);
748         if (!l)
749                 return BLUETOOTH_ERROR_INVALID_PARAM;
750
751         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
752
753         if (_bt_mesh_node_get_all_appkeys(cdb_cfg->uuid,
754                                 node->unicast, node->netkey_idx, out_param))
755                 return BLUETOOTH_ERROR_NONE;
756         else
757                 return BLUETOOTH_ERROR_INTERNAL;
758 }
759
760 int _bt_mesh_element_get_models(const char *app_cred, const char *sender,
761                 bluetooth_mesh_network_t *network,  uint16_t unicast,
762                         int elem_idx, GArray **out_param)
763 {
764         GSList *l;
765         _bt_mesh_cdb_t *cdb_cfg = NULL;
766
767         /* Find CDB */
768         l = g_slist_find_custom(cdb_list, network->token.token,
769                         __mesh_compare_app_cdb_token);
770         if (!l)
771                 return BLUETOOTH_ERROR_INVALID_PARAM;
772
773         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
774
775         if (_bt_mesh_node_get_models(cdb_cfg->uuid, unicast,
776                                 elem_idx, out_param))
777                 return BLUETOOTH_ERROR_NONE;
778         else
779                 return BLUETOOTH_ERROR_INTERNAL;
780 }
781
782 int _bt_mesh_network_handle_netkey_added(
783                 uint8_t net_uuid[], uint16_t netkey_idx)
784 {
785         GSList *l;
786         _bt_mesh_cdb_t *cdb_cfg = NULL;
787
788         BT_INFO("Mesh: Handle Netkey Added");
789         /* Find CDB */
790         l = g_slist_find_custom(cdb_list, net_uuid,
791                         __mesh_compare_app_network_uuid);
792         if (!l)
793                 return BLUETOOTH_ERROR_INVALID_PARAM;
794
795         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
796
797         _bt_mesh_keys_add_net_key(cdb_cfg->uuid, netkey_idx);
798
799         if (!_bt_mesh_conf_insert_network_key(cdb_cfg,
800                         netkey_idx, MESH_KEY_REFRESH_PHASE_NONE))
801                 return BLUETOOTH_ERROR_INTERNAL;
802
803         return BLUETOOTH_ERROR_NONE;
804 }
805
806 int _bt_mesh_network_handle_netkey_deleted(
807         uint8_t net_uuid[], uint16_t netkey_idx)
808 {
809         GSList *l;
810         _bt_mesh_cdb_t *cdb_cfg = NULL;
811
812         BT_INFO("Mesh: Handle Netkey Deleted");
813         /* Find CDB */
814         l = g_slist_find_custom(cdb_list, net_uuid,
815                 __mesh_compare_app_network_uuid);
816         if (!l)
817                 return BLUETOOTH_ERROR_INVALID_PARAM;
818
819         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
820
821         _bt_mesh_keys_del_net_key(cdb_cfg->uuid, netkey_idx, cdb_cfg);
822
823         if (!_bt_mesh_conf_delete_network_key(cdb_cfg, netkey_idx))
824                 return BLUETOOTH_ERROR_INTERNAL;
825
826         return BLUETOOTH_ERROR_NONE;
827 }
828
829 int _bt_mesh_network_handle_netkey_updated(
830                 uint8_t net_uuid[], uint16_t netkey_idx)
831 {
832         GSList *l;
833         _bt_mesh_cdb_t *cdb_cfg = NULL;
834
835         BT_INFO("Mesh: Handle Netkey Updated");
836         /* Find CDB */
837         l = g_slist_find_custom(cdb_list, net_uuid,
838                         __mesh_compare_app_network_uuid);
839         if (!l)
840                 return BLUETOOTH_ERROR_INVALID_PARAM;
841
842         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
843
844         _bt_mesh_keys_set_net_key_phase(cdb_cfg,
845                 netkey_idx, MESH_KEY_REFRESH_PHASE_ONE, true);
846
847         return BLUETOOTH_ERROR_NONE;
848 }
849
850 int _bt_mesh_network_handle_appkey_added(uint8_t net_uuid[],
851                 uint16_t netkey_idx, uint16_t appkey_idx)
852 {
853         GSList *l;
854         _bt_mesh_cdb_t *cdb_cfg = NULL;
855
856         BT_INFO("Mesh: Handle Appkey Added");
857         /* Find CDB */
858         l = g_slist_find_custom(cdb_list, net_uuid,
859                         __mesh_compare_app_network_uuid);
860         if (!l)
861                 return BLUETOOTH_ERROR_INVALID_PARAM;
862
863         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
864
865         _bt_mesh_keys_add_app_key(cdb_cfg->uuid,
866                         netkey_idx, appkey_idx);
867
868         if (!_bt_mesh_conf_insert_application_key(cdb_cfg,
869                                 netkey_idx, appkey_idx))
870                 return BLUETOOTH_ERROR_INTERNAL;
871
872         return BLUETOOTH_ERROR_NONE;
873 }
874
875 int _bt_mesh_network_handle_appkey_deleted(uint8_t net_uuid[],
876                 uint16_t netkey_idx, uint16_t appkey_idx)
877 {
878         GSList *l;
879         _bt_mesh_cdb_t *cdb_cfg = NULL;
880
881         BT_INFO("Mesh: Handle Appkey Deleted");
882         /* Find CDB */
883         l = g_slist_find_custom(cdb_list, net_uuid,
884                 __mesh_compare_app_network_uuid);
885         if (!l)
886                 return BLUETOOTH_ERROR_INVALID_PARAM;
887
888         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
889
890         _bt_mesh_keys_del_app_key(cdb_cfg->uuid, appkey_idx);
891
892         if (!_bt_mesh_conf_delete_application_key(cdb_cfg, appkey_idx))
893                 return BLUETOOTH_ERROR_INTERNAL;
894
895         return BLUETOOTH_ERROR_NONE;
896 }
897
898 int _bt_mesh_network_set_name(const char *app_cred, const char *sender,
899         bluetooth_mesh_network_t *network)
900 {
901         GSList *l;
902         _bt_mesh_cdb_t *cdb_cfg = NULL;
903         BT_INFO("Mesh: Set network name, app_creds [%s]", app_cred);
904         BT_INFO("Mesh: UUID [%s]", network->uuid);
905         BT_INFO("Mesh: Token[%s]", network->token.token);
906         BT_INFO("Mesh: Name to be set[%s]", network->name.name);
907
908         /* Find CDB */
909         l = g_slist_find_custom(cdb_list,
910                 network->token.token, __mesh_compare_app_cdb_token);
911         if (!l)
912                 return BLUETOOTH_ERROR_INVALID_PARAM;
913
914         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
915         if (_bt_mesh_conf_set_network_friendly_name(cdb_cfg, network->name.name))
916                 return BLUETOOTH_ERROR_NONE;
917
918         return BLUETOOTH_ERROR_INTERNAL;
919 }
920
921 int _bt_mesh_network_add_netkey(const char *app_cred,
922                 const char *sender, bluetooth_mesh_network_t *network)
923 {
924         int ret = OAL_STATUS_SUCCESS;
925         GSList *l;
926         _bt_mesh_cdb_t *cdb_cfg = NULL;
927         oal_uuid_t net_uuid;
928         oal_mesh_key_op_e op = OAL_MESH_KEY_ADD;
929         uint16_t idx;
930
931         /* Find CDB */
932         l = g_slist_find_custom(cdb_list,
933                 network->token.token, __mesh_compare_app_cdb_token);
934         if (!l)
935                 return BLUETOOTH_ERROR_INVALID_PARAM;
936
937         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
938
939         if (!_bt_mesh_keys_get_new_netkey_index(cdb_cfg->uuid, &idx))
940                 return BLUETOOTH_ERROR_INVALID_PARAM;
941
942         _bt_mesh_util_convert_string_to_hex(network->uuid,
943                 strlen(network->uuid), net_uuid.uuid, 16);
944
945         BT_INFO("Mesh: netkey index to be created [%u]", idx);
946         ret = mesh_network_subnet_execute(&net_uuid, op, idx);
947
948         if (ret != OAL_STATUS_SUCCESS) {
949                 BT_ERR("ret: %d", ret);
950                 return BLUETOOTH_ERROR_INTERNAL;
951         }
952
953         return BLUETOOTH_ERROR_NONE;
954 }
955
956 int _bt_mesh_network_delete_netkey(const char *app_cred,
957         const char *sender, bluetooth_mesh_network_t *network,
958                 uint16_t index)
959 {
960         int ret = OAL_STATUS_SUCCESS;
961         GSList *l;
962         _bt_mesh_cdb_t *cdb_cfg = NULL;
963         oal_uuid_t net_uuid;
964         oal_mesh_key_op_e op = OAL_MESH_KEY_DELETE;
965
966         /* Find CDB */
967         l = g_slist_find_custom(cdb_list, network->token.token,
968                         __mesh_compare_app_cdb_token);
969         if (!l)
970                 return BLUETOOTH_ERROR_INVALID_PARAM;
971
972         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
973
974         /* Check if NetKey entry is present in local Network */
975         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, index))
976                 return BLUETOOTH_ERROR_INVALID_PARAM;
977
978         /* Check if NetKey is already added to one of the provisioned nodes */
979         if (_bt_mesh_node_is_netkey_added_in_network(cdb_cfg->uuid, index)) {
980                 BT_INFO("Mesh: NetKey index [0x%2.2x] can not be deleted", index);
981                 return BLUETOOTH_ERROR_INVALID_PARAM;
982         }
983
984         _bt_mesh_util_convert_string_to_hex(network->uuid,
985                         strlen(network->uuid), net_uuid.uuid, 16);
986
987         BT_INFO("Mesh: netkey index to be deleted [%u]", index);
988         ret = mesh_network_subnet_execute(&net_uuid, op, index);
989
990         if (ret != OAL_STATUS_SUCCESS) {
991                 BT_ERR("ret: %d", ret);
992                 return BLUETOOTH_ERROR_INTERNAL;
993         }
994
995         return BLUETOOTH_ERROR_NONE;
996 }
997
998 int _bt_mesh_network_update_netkey(const char *app_cred,
999         const char *sender, bluetooth_mesh_network_t *network,
1000                 uint16_t index)
1001 {
1002         int ret = OAL_STATUS_SUCCESS;
1003         GSList *l;
1004         _bt_mesh_cdb_t *cdb_cfg = NULL;
1005         oal_uuid_t net_uuid;
1006         oal_mesh_key_op_e op = OAL_MESH_KEY_UPDATE;
1007
1008         /* Find CDB */
1009         l = g_slist_find_custom(cdb_list, network->token.token,
1010                         __mesh_compare_app_cdb_token);
1011         if (!l)
1012                 return BLUETOOTH_ERROR_INVALID_PARAM;
1013
1014         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1015
1016         /* Check if NetKey entry is present in local Network */
1017         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, index))
1018                 return BLUETOOTH_ERROR_INVALID_PARAM;
1019
1020         _bt_mesh_util_convert_string_to_hex(network->uuid,
1021                         strlen(network->uuid), net_uuid.uuid, 16);
1022
1023         BT_INFO("Mesh: netkey index to be updated [%u]", index);
1024         ret = mesh_network_subnet_execute(&net_uuid, op, index);
1025
1026         if (ret != OAL_STATUS_SUCCESS) {
1027                 BT_ERR("ret: %d", ret);
1028                 return BLUETOOTH_ERROR_INTERNAL;
1029         }
1030
1031         return BLUETOOTH_ERROR_NONE;
1032 }
1033
1034 int _bt_mesh_network_add_appkey(const char *app_cred,
1035         const char *sender, bluetooth_mesh_network_t *network,
1036                 uint16_t netkey_idx)
1037 {
1038         int ret = OAL_STATUS_SUCCESS;
1039         GSList *l;
1040         _bt_mesh_cdb_t *cdb_cfg = NULL;
1041         oal_uuid_t net_uuid;
1042         oal_mesh_key_op_e op = OAL_MESH_KEY_ADD;
1043         uint16_t idx;
1044
1045         /* Find CDB */
1046         l = g_slist_find_custom(cdb_list, network->token.token,
1047                 __mesh_compare_app_cdb_token);
1048         if (!l)
1049                 return BLUETOOTH_ERROR_INVALID_PARAM;
1050
1051         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1052
1053         /* Check if NetKey entry is present in local Network */
1054         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1055                 return BLUETOOTH_ERROR_INVALID_PARAM;
1056
1057         if (!_bt_mesh_keys_get_new_appkey_index(cdb_cfg->uuid, &idx))
1058                 return BLUETOOTH_ERROR_INVALID_PARAM;
1059
1060         _bt_mesh_util_convert_string_to_hex(network->uuid,
1061                 strlen(network->uuid), net_uuid.uuid, 16);
1062
1063         BT_INFO("Mesh: AppKey index to be created [%u]", idx);
1064         ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, idx);
1065
1066         if (ret != OAL_STATUS_SUCCESS) {
1067                 BT_ERR("ret: %d", ret);
1068                 return BLUETOOTH_ERROR_INTERNAL;
1069         }
1070
1071         return BLUETOOTH_ERROR_NONE;
1072 }
1073
1074 int _bt_mesh_network_update_appkey(const char *app_cred,
1075         const char *sender, bluetooth_mesh_network_t *network,
1076                 uint16_t netkey_idx, uint16_t appkey_idx)
1077 {
1078         int ret = OAL_STATUS_SUCCESS;
1079         GSList *l;
1080         _bt_mesh_cdb_t *cdb_cfg = NULL;
1081         oal_uuid_t net_uuid;
1082         oal_mesh_key_op_e op = OAL_MESH_KEY_UPDATE;
1083
1084         /* Find CDB */
1085         l = g_slist_find_custom(cdb_list, network->token.token,
1086                         __mesh_compare_app_cdb_token);
1087         if (!l)
1088                 return BLUETOOTH_ERROR_INVALID_PARAM;
1089
1090         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1091
1092         /* Check if NetKey entry is present in local Network */
1093         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1094                 return BLUETOOTH_ERROR_INVALID_PARAM;
1095
1096         _bt_mesh_util_convert_string_to_hex(network->uuid,
1097                         strlen(network->uuid), net_uuid.uuid, 16);
1098
1099         BT_INFO("Mesh: AppKey index to be updated [%u]", appkey_idx);
1100         ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, appkey_idx);
1101
1102         if (ret != OAL_STATUS_SUCCESS) {
1103                 BT_ERR("ret: %d", ret);
1104                 return BLUETOOTH_ERROR_INTERNAL;
1105         }
1106
1107         return BLUETOOTH_ERROR_NONE;
1108 }
1109
1110 int _bt_mesh_network_delete_appkey(const char *app_cred,
1111         const char *sender, bluetooth_mesh_network_t *network,
1112                 uint16_t netkey_idx, uint16_t appkey_idx)
1113 {
1114         int ret = OAL_STATUS_SUCCESS;
1115         GSList *l;
1116         _bt_mesh_cdb_t *cdb_cfg = NULL;
1117         oal_uuid_t net_uuid;
1118         oal_mesh_key_op_e op = OAL_MESH_KEY_DELETE;
1119
1120         /* Find CDB */
1121         l = g_slist_find_custom(cdb_list, network->token.token,
1122                         __mesh_compare_app_cdb_token);
1123         if (!l)
1124                 return BLUETOOTH_ERROR_INVALID_PARAM;
1125
1126         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1127
1128         /* Check if NetKey entry is present in local Network */
1129         if (!_bt_mesh_keys_is_netkey_present(cdb_cfg->uuid, netkey_idx))
1130                 return BLUETOOTH_ERROR_INVALID_PARAM;
1131
1132         /* Check if AppKey is already added to one of the provisioned nodes */
1133         if (_bt_mesh_node_is_appkey_added_in_network(cdb_cfg->uuid, appkey_idx))
1134                 return BLUETOOTH_ERROR_INVALID_PARAM;
1135
1136         _bt_mesh_util_convert_string_to_hex(network->uuid,
1137                         strlen(network->uuid), net_uuid.uuid, 16);
1138
1139         BT_INFO("Mesh: AppKey index to be deleted [%u]", appkey_idx);
1140         ret = mesh_network_appkey_execute(&net_uuid, op, netkey_idx, appkey_idx);
1141
1142         if (ret != OAL_STATUS_SUCCESS) {
1143                 BT_ERR("ret: %d", ret);
1144                 return BLUETOOTH_ERROR_INTERNAL;
1145         }
1146
1147         return BLUETOOTH_ERROR_NONE;
1148 }
1149
1150 int _bt_mesh_network_create(const char *app_cred, const char *sender,
1151                 const char *network_name, bluetooth_mesh_node_t *node,
1152                         GSList *model_list)
1153 {
1154         int ret = OAL_STATUS_SUCCESS;
1155
1156         BT_INFO("Mesh: App Credential#### [%s] sender [%s] network [%s]",
1157                         app_cred, sender, network_name);
1158
1159         /* TODO Handle Buzy status */
1160         /* Sanity Check: CDB directory creation */
1161         if (!_bt_mesh_util_is_directory_exists(MESH_CDB_DEFAULT_DIR_PATH)) {
1162                 BT_INFO("MESH: CDB directory does not exist");
1163                 if (!_bt_mesh_util_create_directory(MESH_CDB_DEFAULT_DIR_PATH)) {
1164                         BT_ERR("MESH: Fail to create Mesh CDB directory");
1165                         return BLUETOOTH_ERROR_INTERNAL;
1166                 }
1167         }
1168
1169         BT_INFO("Mesh: Send Local Network Creation Request to OAL");
1170
1171         /* Register Mesh Node */
1172         ret = mesh_register_node((oal_mesh_node_t*)node, model_list, true);
1173         if (ret != OAL_STATUS_SUCCESS) {
1174                 BT_ERR("ret: %d", ret);
1175                 return BLUETOOTH_ERROR_INTERNAL;
1176         }
1177
1178         BT_INFO("Mesh: Request Sent to Stack successfully");
1179         /* Create a temporary node & wait for Network Created event */
1180         mesh_local_node_t *temp = g_malloc0(sizeof(mesh_local_node_t));
1181         memcpy(temp->node_uuid, node->uuid, 16);
1182         temp->num_elems = node->num_elements;
1183         temp->prim_unicast = node->primary_unicast;
1184         temp->sender = g_strdup(sender);
1185         temp->app_cred = g_strdup(app_cred);
1186         temp->vendor_info = node->vendor_info;
1187         temp->model_list = model_list;
1188         temp_nodes = g_slist_append(temp_nodes, temp);
1189
1190         return BLUETOOTH_ERROR_NONE;
1191 }
1192
1193 bool _bt_mesh_network_save_remote_node_appkey(
1194                 uint8_t net_uuid[], uint16_t remote_unicast,
1195                         uint16_t netkey_idx, uint16_t appkey_idx)
1196 {
1197         GSList *l;
1198         _bt_mesh_cdb_t *cdb_cfg = NULL;
1199
1200         BT_INFO("Mesh: Add Appkey [0x%2.2x] to node", appkey_idx);
1201         /* Find CDB */
1202         l = g_slist_find_custom(cdb_list, net_uuid,
1203                         __mesh_compare_app_network_uuid);
1204         if (!l)
1205                 return false;
1206
1207         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1208
1209         if (_bt_mesh_node_is_appkey_exists(net_uuid,
1210                         remote_unicast, appkey_idx)) {
1211                 BT_INFO("Mesh: AppKey is already added to Node");
1212                 return true;
1213         }
1214         if (_bt_mesh_node_add_app_key(net_uuid,
1215                         remote_unicast, appkey_idx)) {
1216                 BT_INFO("Mesh: Add App Key Idx [0x%2.2x] in CDB", appkey_idx);
1217                 return _bt_mesh_conf_node_insert_application_key(cdb_cfg,
1218                                         remote_unicast, appkey_idx);
1219         }
1220
1221         BT_INFO("Mesh: AppKey idx [0x%2.2x] Failed to add in Node", appkey_idx);
1222         return false;
1223 }
1224
1225 bool _bt_mesh_network_delete_remote_node_appkey(
1226                 uint8_t net_uuid[], uint16_t remote_unicast,
1227                                 uint16_t netkey_idx, uint16_t appkey_idx)
1228 {
1229         GSList *l;
1230         _bt_mesh_cdb_t *cdb_cfg = NULL;
1231         bool is_deleted = false;
1232
1233         BT_INFO("Mesh: Delete Appkey Idx[0x%2.2x]from Node Unicast [0x%2.2x]",
1234                                 appkey_idx, remote_unicast);
1235         /* Find CDB */
1236         l = g_slist_find_custom(cdb_list, net_uuid,
1237                         __mesh_compare_app_network_uuid);
1238         if (!l)
1239                 return false;
1240
1241         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1242
1243         if (_bt_mesh_node_del_app_key(net_uuid,
1244                         remote_unicast, appkey_idx)) {
1245                 BT_INFO("Mesh: Removed Appkey from node");
1246                 is_deleted =  _bt_mesh_conf_node_delete_application_key(cdb_cfg,
1247                                 remote_unicast, appkey_idx);
1248                 if (is_deleted)
1249                         BT_INFO("Mesh: AppKey removed from CDB Node Entry");
1250                 else
1251                         BT_INFO("Mesh: AppKey could not be removed from CDB Node Entry");
1252         }
1253
1254         return is_deleted;
1255 }
1256
1257 bool _bt_mesh_network_save_remote_node_ttl(
1258         uint8_t net_uuid[], uint16_t remote_unicast,
1259                         uint8_t ttl)
1260 {
1261         GSList *l;
1262         _bt_mesh_cdb_t *cdb_cfg = NULL;
1263
1264         /* Find CDB */
1265         l = g_slist_find_custom(cdb_list, net_uuid,
1266                         __mesh_compare_app_network_uuid);
1267         if (!l)
1268                 return false;
1269
1270         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1271
1272         return _bt_mesh_conf_node_set_timetolive_value(cdb_cfg,
1273                                 remote_unicast, ttl);
1274 }
1275
1276 bool _bt_mesh_network_save_remote_node_netkey(
1277                 uint8_t net_uuid[], uint16_t remote_unicast,
1278                                 uint16_t netkey_idx)
1279 {
1280         GSList *l;
1281         _bt_mesh_cdb_t *cdb_cfg = NULL;
1282
1283         /* Find CDB */
1284         l = g_slist_find_custom(cdb_list, net_uuid,
1285                         __mesh_compare_app_network_uuid);
1286         if (!l)
1287                 return false;
1288
1289         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1290
1291         if (_bt_mesh_node_is_netkey_exists(net_uuid,
1292                         remote_unicast, netkey_idx)) {
1293                 BT_INFO("Mesh: NetKey is already added to Node");
1294                 return true;
1295         }
1296         if (_bt_mesh_node_add_net_key(net_uuid,
1297                         remote_unicast, netkey_idx))
1298                 return _bt_mesh_conf_node_insert_network_key(cdb_cfg,
1299                                         remote_unicast, netkey_idx);
1300
1301         return false;
1302 }
1303
1304 bool _bt_mesh_network_delete_remote_node_netkey(
1305                 uint8_t net_uuid[], uint16_t remote_unicast,
1306                         uint16_t netkey_idx)
1307 {
1308         GSList *l;
1309         _bt_mesh_cdb_t *cdb_cfg = NULL;
1310
1311         /* Find CDB */
1312         l = g_slist_find_custom(cdb_list, net_uuid,
1313                         __mesh_compare_app_network_uuid);
1314         if (!l)
1315                 return false;
1316
1317         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1318
1319         if (_bt_mesh_node_del_net_key(cdb_cfg, net_uuid,
1320                         remote_unicast, netkey_idx))
1321                 return _bt_mesh_conf_node_delete_network_key(cdb_cfg,
1322                                 remote_unicast, netkey_idx);
1323         return false;
1324 }
1325
1326 bool _bt_mesh_network_add_model_subscription(
1327                 uint8_t net_uuid[], uint16_t remote_unicast,
1328                 int ele_idx, uint32_t mod_id, uint16_t group_addr)
1329 {
1330         GSList *l;
1331         _bt_mesh_cdb_t *cdb_cfg = NULL;
1332
1333         /* Find CDB */
1334         l = g_slist_find_custom(cdb_list, net_uuid,
1335                 __mesh_compare_app_network_uuid);
1336         if (!l)
1337                 return false;
1338
1339         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1340
1341         return _bt_mesh_conf_add_model_config_data(cdb_cfg,
1342                         remote_unicast, ele_idx, mod_id, group_addr);
1343 }
1344
1345 bool _bt_mesh_network_delete_model_subscription(
1346                 uint8_t net_uuid[], uint16_t remote_unicast,
1347                 int ele_idx, uint32_t mod_id, uint16_t group_addr)
1348 {
1349         GSList *l;
1350         _bt_mesh_cdb_t *cdb_cfg = NULL;
1351
1352         /* Find CDB */
1353         l = g_slist_find_custom(cdb_list, net_uuid,
1354                 __mesh_compare_app_network_uuid);
1355         if (!l)
1356                 return false;
1357
1358         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1359
1360         return _bt_mesh_conf_delete_model_config_data(cdb_cfg,
1361                         remote_unicast, ele_idx, mod_id, group_addr);
1362 }
1363
1364 bool _bt_mesh_network_delete_all_model_subscription(
1365                 uint8_t net_uuid[], uint16_t remote_unicast,
1366                 int ele_idx, uint32_t mod_id)
1367 {
1368         GSList *l;
1369         _bt_mesh_cdb_t *cdb_cfg = NULL;
1370
1371         /* Find CDB */
1372         l = g_slist_find_custom(cdb_list, net_uuid,
1373                 __mesh_compare_app_network_uuid);
1374         if (!l)
1375                 return false;
1376
1377         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1378
1379         return _bt_mesh_conf_delete_all_model_config_data(cdb_cfg,
1380                         remote_unicast, ele_idx, mod_id);
1381 }
1382
1383 bool _bt_mesh_network_overwrite_model_subscription(
1384                 uint8_t net_uuid[], uint16_t remote_unicast,
1385                 int ele_idx, uint32_t mod_id, uint16_t group_addr)
1386 {
1387         GSList *l;
1388         _bt_mesh_cdb_t *cdb_cfg = NULL;
1389
1390         /* Find CDB */
1391         l = g_slist_find_custom(cdb_list, net_uuid,
1392                 __mesh_compare_app_network_uuid);
1393         if (!l)
1394                 return false;
1395
1396         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1397
1398         return _bt_mesh_conf_overwrite_model_config_data(cdb_cfg,
1399                         remote_unicast, ele_idx, mod_id, group_addr);
1400 }
1401
1402 bool _bt_mesh_network_save_remote_node_composition(
1403                 uint8_t net_uuid[], uint16_t remote_unicast,
1404                                 uint8_t *data, uint16_t data_len)
1405 {
1406         GSList *l;
1407         _bt_mesh_cdb_t *cdb_cfg = NULL;
1408
1409         /* Find CDB */
1410         l = g_slist_find_custom(cdb_list, net_uuid,
1411                 __mesh_compare_app_network_uuid);
1412         if (!l)
1413                 return false;
1414
1415         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1416
1417         return _bt_mesh_conf_set_node_comp_data(cdb_cfg,
1418                         remote_unicast, data, data_len);
1419 }
1420
1421 int _bt_mesh_network_add_remote_node(uint8_t net_uuid[],
1422         uint8_t dev_uuid[], uint16_t unicast, uint8_t count)
1423 {
1424         GSList *l;
1425         _bt_mesh_cdb_t *cdb_cfg = NULL;
1426
1427         /* Find CDB */
1428         l = g_slist_find_custom(cdb_list, net_uuid,
1429                         __mesh_compare_app_network_uuid);
1430         if (!l)
1431                 return BLUETOOTH_ERROR_INVALID_PARAM;
1432
1433         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1434
1435         _bt_mesh_node_add_node(net_uuid, dev_uuid,
1436                         unicast, count, MESH_PRIMARY_NET_IDX);
1437
1438         /* Add Remote Node entry in CDB */
1439         _bt_mesh_conf_insert_node_object(cdb_cfg, /* Dev UUID */ dev_uuid,
1440                         count, unicast, MESH_PRIMARY_NET_IDX);
1441
1442         return BLUETOOTH_ERROR_NONE;
1443 }
1444
1445 bool _bt_mesh_node_get_vendor_features(uint8_t net_uuid[],
1446         uint16_t unicast, bluetooth_mesh_node_features_t *feats)
1447 {
1448         GSList *l;
1449         _bt_mesh_cdb_t *cdb_cfg = NULL;
1450         BT_INFO("Mesh: Attempt to get vendor features: unicast [0x%2.2x]", unicast);
1451         /* Find CDB */
1452         l = g_slist_find_custom(cdb_list, net_uuid,
1453                         __mesh_compare_app_network_uuid);
1454         if (!l)
1455                 return false;
1456
1457         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1458
1459         BT_INFO("Mesh: Read Vendor Features from CDB");
1460         return _bt_mesh_conf_fetch_vendor_specific_info(cdb_cfg, unicast,
1461                         &feats->vendor_info.companyid, &feats->vendor_info.vendorid,
1462                         &feats->vendor_info.versionid, &feats->vendor_info.crpl,
1463                         &feats->features.relay, &feats->features.frnd,
1464                         &feats->features.proxy, &feats->features.lpn);
1465 }
1466
1467 int _bt_mesh_network_load_cdb(int result, const char *sender,
1468                 const char *app_creds,
1469                         uint8_t uuid[16], uint8_t token[8],
1470                                          char **network)
1471 {
1472         GSList *l;
1473         char token_str[17];
1474         _bt_mesh_cdb_t *cdb_cfg = NULL;
1475
1476         _bt_mesh_util_convert_hex_to_string(token, 8,
1477                         token_str, 17);
1478
1479         /* Find CDB */
1480         l = g_slist_find_custom(cdb_list, token_str,
1481                         __mesh_compare_app_cdb_token);
1482         if (!l)
1483                 return BLUETOOTH_ERROR_INTERNAL;
1484
1485         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1486
1487         if (result != BLUETOOTH_ERROR_NONE)
1488                 goto failed;
1489
1490         /* Create new network for saving network specific Keys */
1491         _bt_mesh_keys_load_net(cdb_cfg->uuid);
1492         if (!_bt_mesh_conf_load_all_keys(cdb_cfg)) {
1493                 _bt_mesh_keys_unload_net(cdb_cfg->uuid);
1494                 goto failed;
1495         }
1496
1497         /* Create new network for saving network specific nodes */
1498         _bt_mesh_node_load_net(cdb_cfg->uuid);
1499         if (!_bt_mesh_conf_load_all_nodes(cdb_cfg)) {
1500                 _bt_mesh_node_unload_net(cdb_cfg->uuid);
1501                 goto failed;
1502         }
1503
1504         /* Load Groups Created */
1505         cdb_cfg->groups = _bt_mesh_conf_load_group_info(cdb_cfg);
1506
1507         /* Fetch Network name */
1508         *network = (char*)_bt_mesh_conf_get_network_friendly_name(cdb_cfg);
1509         BT_INFO("Mesh: Attached Network [%s]", *network);
1510         return BLUETOOTH_ERROR_NONE;
1511 failed:
1512         /* Free the CDB object */
1513         _bt_mesh_conf_free(cdb_cfg);
1514         return BLUETOOTH_ERROR_INTERNAL;
1515 }
1516
1517 int _bt_mesh_network_load(const char *app_cred,
1518         const char *sender, const char *token)
1519 {
1520         int ret = OAL_STATUS_SUCCESS;
1521         GSList *l;
1522         char *dir_path = NULL;
1523         char *file_path = NULL;
1524         _bt_mesh_cdb_t *cdb_cfg = NULL;
1525         oal_mesh_node_t node;
1526         GSList *models = NULL;
1527
1528         /* Check CDB directory exist or not */
1529         dir_path = g_strdup_printf(MESH_CDB_DEFAULT_DIR_PATH"/%s/", "default");
1530         if (!_bt_mesh_util_is_directory_exists(dir_path)) {
1531                 BT_ERR("Mesh: CDB dir [%s]does not exist for app", dir_path);
1532                 g_free(dir_path);
1533                 return BLUETOOTH_ERROR_INTERNAL;
1534         }
1535
1536         /* Find CDB */
1537         l = g_slist_find_custom(cdb_list, token,
1538                         __mesh_compare_app_cdb_token);
1539         if (l) {
1540                 BT_INFO("Mesh: Already loaded");
1541                 g_free(dir_path);
1542                 return BLUETOOTH_ERROR_NONE;
1543         } else {
1544                 BT_INFO("Mesh: Not loaded");
1545                 /* Attempt to load CDB's present in app's
1546                    CDB directory */
1547                 const char *filename;
1548                 GDir *dir = g_dir_open(dir_path, 0, NULL);
1549                 if (!dir) {
1550                         BT_ERR("Mesh: Could not open directory");
1551                         g_free(dir_path);
1552                         return BLUETOOTH_ERROR_INTERNAL;
1553                 }
1554                 while ((filename = g_dir_read_name(dir)) != NULL) {
1555
1556                         if ((g_file_test(filename, G_FILE_TEST_IS_SYMLINK) == TRUE) ||
1557                                         (g_str_has_suffix(filename, ".json") == FALSE))
1558                                 continue;
1559
1560                         file_path = g_strdup_printf("%s%s",
1561                                         dir_path, filename);
1562                         BT_INFO("Mesh: Token [%s]", token);
1563                         BT_INFO("Mesh: File name [%s]", filename);
1564                         BT_INFO("Mesh: File Absolute Path [%s]", file_path);
1565
1566                         cdb_cfg = _bt_mesh_conf_load(file_path, token);
1567                         if (cdb_cfg)
1568                                 break;
1569                 }
1570         }
1571
1572         g_free(file_path);
1573         g_free(dir_path);
1574
1575         if (!cdb_cfg) {
1576                 BT_ERR("Mesh: Could not find CDB for the token!! Possibly not authorized!!");
1577                 return BLUETOOTH_ERROR_ACCESS_DENIED;
1578         }
1579
1580         /* Fill the Mesh node info  */
1581         memset(&node, 0x00, sizeof(oal_mesh_node_t));
1582         memcpy(node.uuid.uuid, cdb_cfg->uuid, sizeof(oal_uuid_t));
1583         _bt_mesh_util_convert_string_to_hex(token, strlen(token), node.token.u8, 8);
1584         if (!_bt_mesh_conf_get_element_count(cdb_cfg, &node.num_elements)) {
1585                 _bt_mesh_conf_free(cdb_cfg);
1586                 return BLUETOOTH_ERROR_INTERNAL;
1587         }
1588         BT_INFO("Mesh: toatl number of elements [%d]", node.num_elements);
1589
1590         BT_INFO("Mesh:Fetch Vendor specific info");
1591         if (!_bt_mesh_conf_fetch_vendor_specific_info(cdb_cfg, 0x0001 /* Local Node Unicast */,
1592                                 &node.vendor_info.companyid, &node.vendor_info.vendorid,
1593                                 &node.vendor_info.versionid, &node.vendor_info.crpl,
1594                                 &node.vendor_info.relay, &node.vendor_info.frnd,
1595                                 &node.vendor_info.proxy, &node.vendor_info.lpn)) {
1596
1597                 _bt_mesh_conf_free(cdb_cfg);
1598                 return BLUETOOTH_ERROR_INTERNAL;
1599         }
1600
1601         BT_INFO("Mesh: Fill Model informations");
1602         for (int i = 0; i < node.num_elements; i++) {
1603                 int num_models;
1604                 uint16_t **model_array = _bt_mesh_conf_get_all_model_info(
1605                                 cdb_cfg, i, &num_models);
1606                 if (!model_array) {
1607                         _bt_mesh_conf_free(cdb_cfg);
1608                         return BLUETOOTH_ERROR_INTERNAL;
1609                 }
1610
1611                 for (int j = 0; j < num_models; j++) {
1612                         bluetooth_mesh_model_t *mod;
1613                         mod = g_malloc0(sizeof(bluetooth_mesh_model_t));
1614                         mod->elem_index = i;
1615                         mod->model_id = *model_array[j];
1616                         models = g_slist_append(models, mod);
1617                 }
1618                 /* Free all model(s) */
1619                 for (int j = 0; j < num_models; j++)
1620                         g_free(model_array[j]);
1621                 g_free(model_array);
1622         }
1623
1624         BT_INFO("Mesh: Node formation done:: Register it!");
1625         /* Register Mesh Node */
1626         ret = mesh_register_node((oal_mesh_node_t*)&node,
1627                         models, true);
1628
1629         /* Cleanup */
1630         //g_slist_free_full(models, g_free);
1631
1632         if (ret != OAL_STATUS_SUCCESS) {
1633                 BT_ERR("Mesh: Load Network Failed ret: %d", ret);
1634                 _bt_mesh_conf_free(cdb_cfg);
1635                 return BLUETOOTH_ERROR_INTERNAL;
1636         }
1637
1638         /* Save till Network attached */
1639         cdb_list = g_slist_append(cdb_list, cdb_cfg);
1640         return BLUETOOTH_ERROR_NONE;
1641 }
1642
1643 bool _bt_mesh_network_get_label_uuid_from_sub_addr(
1644                 uint8_t net_uuid[],     uint16_t sub_addr,
1645                                 uint8_t label[])
1646 {
1647         GSList *l, *l1;
1648         _bt_mesh_cdb_t *cdb_cfg = NULL;
1649
1650         /* Find CDB */
1651         l = g_slist_find_custom(cdb_list, net_uuid,
1652                         __mesh_compare_app_network_uuid);
1653         if (!l)
1654                 return false;
1655
1656         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1657
1658         l1 = g_slist_find_custom(cdb_cfg->groups,
1659                         GUINT_TO_POINTER(sub_addr), __mesh_compare_addr);
1660
1661         if (!l1)
1662                 return false;
1663         else {
1664                 _bt_mesh_group_t *grp = l1->data;
1665                 memcpy(label, grp->label_uuid, 16);
1666         }
1667         return true;
1668 }
1669
1670 int _bt_mesh_network_remove_group(const char *app_cred,
1671         const char *sender, bluetooth_mesh_network_t *net,
1672                         bluetooth_mesh_network_group_info_t *req)
1673 {
1674         GSList *l, *l1;
1675         _bt_mesh_cdb_t *cdb_cfg = NULL;
1676         _bt_mesh_group_t *grp;
1677         uint8_t net_uuid[16];
1678
1679         _bt_mesh_util_convert_string_to_hex(net->uuid,
1680                         strlen(net->uuid), net_uuid, 16);
1681         /* Find CDB */
1682         l = g_slist_find_custom(cdb_list, net_uuid,
1683                         __mesh_compare_app_network_uuid);
1684         if (!l)
1685                 return BLUETOOTH_ERROR_INVALID_PARAM;
1686
1687         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1688         BT_INFO("Mesh: Total groups stored in network [%d]",
1689                         g_slist_length(cdb_cfg->groups));
1690
1691         l1 = g_slist_find_custom(cdb_cfg->groups,
1692                         GUINT_TO_POINTER(req->group_addr), __mesh_compare_addr);
1693
1694         if (!l1) {
1695                 BT_ERR("Mesh: To be Removed Group: [0x%2.2x] Not Found!", req->group_addr);
1696                 return BLUETOOTH_ERROR_INVALID_PARAM;
1697         }
1698         grp = (_bt_mesh_group_t*)l1->data;
1699
1700         /* Do not delete group if a model is subscribed to this */
1701         if (_bt_mesh_is_group_subscribed(cdb_cfg, req->group_addr)) {
1702                 BT_ERR("Mesh: Failed to remove Group: [0x%2.2x]", req->group_addr);
1703                 return BLUETOOTH_ERROR_AUTHENTICATION_REJECTED;
1704         }
1705
1706         BT_INFO("Mesh: To be Removed Group: [0x%2.2x]", req->group_addr);
1707         if (!_bt_mesh_conf_delete_group_entry(cdb_cfg, req->group_addr)) {
1708                 BT_ERR("Mesh: Failed to remove Group: [0x%2.2x]", req->group_addr);
1709                 return BLUETOOTH_ERROR_INTERNAL;
1710         }
1711
1712         BT_INFO("Mesh: Successfully removed Group: [0x%2.2x]", req->group_addr);
1713         cdb_cfg->groups = g_slist_remove(cdb_cfg->groups, grp);
1714         BT_INFO("Mesh: Total groups after update [%d]",
1715                         g_slist_length(cdb_cfg->groups));
1716
1717         return BLUETOOTH_ERROR_NONE;
1718 }
1719
1720 int _bt_mesh_network_create_group(const char *app_cred,
1721         const char *sender, bluetooth_mesh_network_t *net,
1722                 bool is_virtual, uint16_t addr,
1723                         bluetooth_mesh_network_group_info_t *req)
1724 {
1725         GSList *l, *l1, *l2;
1726         _bt_mesh_cdb_t *cdb_cfg = NULL;
1727         uint8_t net_uuid[16];
1728
1729         _bt_mesh_util_convert_string_to_hex(net->uuid,
1730                         strlen(net->uuid), net_uuid, 16);
1731         /* Find CDB */
1732         l = g_slist_find_custom(cdb_list, net_uuid,
1733                         __mesh_compare_app_network_uuid);
1734         if (!l)
1735                 return BLUETOOTH_ERROR_INVALID_PARAM;
1736
1737         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1738         BT_INFO("Mesh: Total Groups present in Network already [%d]",
1739                         g_slist_length(cdb_cfg->groups));
1740
1741         if (is_virtual) {
1742                 uint8_t max_tries = 5;
1743                 _bt_mesh_group_t *grp = NULL;
1744                 grp = g_malloc0(sizeof(_bt_mesh_group_t));
1745                 BT_INFO("Mesh: Network Create Virtual group");
1746 retry:
1747                 l_getrandom(grp->label_uuid, 16);
1748                 _bt_mesh_util_crypto_create_virtual_address(
1749                                 grp->label_uuid, &grp->grp_addr);
1750
1751                 /* For simplicity sake, avoid labels that map to the same hash */
1752                 l1 = g_slist_find_custom(cdb_cfg->groups,
1753                                 GUINT_TO_POINTER(grp->grp_addr), __mesh_compare_addr);
1754
1755                 if (!l1) {
1756                         if (!_bt_mesh_conf_insert_group_info(cdb_cfg, grp)) {
1757                                 BT_ERR("Mesh: unable to save group in Conf DB!!");
1758                                 g_free(grp);
1759                                 return BLUETOOTH_ERROR_INTERNAL;
1760                         }
1761                         req->is_virtual = true;
1762                         req->group_addr = grp->grp_addr;
1763                         _bt_mesh_util_convert_hex_to_string(
1764                                         (uint8_t *) grp->label_uuid, 16, req->label_uuid,
1765                                         BLUETOOTH_MESH_NETWORK_UUID_STRING_LENGTH + 1);
1766
1767                         cdb_cfg->groups = g_slist_append(cdb_cfg->groups, grp);
1768                         BT_INFO("Mesh: Virtual Group[0x%2.2x] inserted in List",
1769                                         grp->grp_addr);
1770                         BT_INFO("Mesh: Total groups present in Network after update [%d]",
1771                                         g_slist_length(cdb_cfg->groups));
1772                         return BLUETOOTH_ERROR_NONE;
1773                 }
1774
1775                 max_tries--;
1776                 if (max_tries)
1777                         goto retry;
1778
1779                 g_free(grp);
1780                 /* Failed to create a unique hash */
1781                 return BLUETOOTH_ERROR_INTERNAL;
1782         } else {
1783                 BT_INFO("Mesh: Network Create group Addr: [0x%2.2x]", addr);
1784
1785                 if (!MESH_IS_GROUP(addr)) {
1786                         BT_ERR("Mesh: Group Address [0x%2.2x] is not valid!", addr);
1787                         return BLUETOOTH_ERROR_INVALID_PARAM;
1788                 }
1789
1790                 l2 = g_slist_find_custom(cdb_cfg->groups,
1791                                 GUINT_TO_POINTER(addr), __mesh_compare_addr);
1792
1793                 if (l2) {
1794                         _bt_mesh_group_t *grp = l2->data;
1795                         req->is_virtual = false;
1796                         req->group_addr = grp->grp_addr;
1797                         BT_INFO("Mesh: Group already found: addr [0x%2.2x]", grp->grp_addr);
1798                 } else {
1799                         /* Group is not present */
1800                         _bt_mesh_group_t *grp = g_malloc0(sizeof(_bt_mesh_group_t));
1801                         grp->grp_addr = addr;
1802                         if (!_bt_mesh_conf_insert_group_info(cdb_cfg, grp)) {
1803                                 BT_ERR("Mesh: unable to save group in Conf DB!!");
1804                                 g_free(grp);
1805                                 return BLUETOOTH_ERROR_INTERNAL;
1806                         }
1807                         cdb_cfg->groups = g_slist_append(cdb_cfg->groups, grp);
1808                         req->is_virtual = false;
1809                         req->group_addr = grp->grp_addr;
1810                         BT_INFO("Mesh: Group[0x%2.2x] inserted in List",
1811                                 grp->grp_addr);
1812                 }
1813                 BT_INFO("Mesh: Total groups present in Network after update [%d]",
1814                                 g_slist_length(cdb_cfg->groups));
1815
1816         }
1817         return BLUETOOTH_ERROR_NONE;
1818 }
1819
1820 int _bt_mesh_network_get_groups(const char *app_cred, const char *sender,
1821                 bluetooth_mesh_network_t *network,
1822                         GArray **out_param)
1823 {
1824         GSList *l;
1825         _bt_mesh_cdb_t *cdb_cfg = NULL;
1826         uint8_t net_uuid[16];
1827
1828         BT_INFO("Mesh: Get All groups from Network [%s]", network->uuid);
1829         _bt_mesh_util_convert_string_to_hex(network->uuid,
1830                         strlen(network->uuid), net_uuid, 16);
1831         /* Find CDB */
1832         l = g_slist_find_custom(cdb_list, net_uuid,
1833                         __mesh_compare_app_network_uuid);
1834         if (!l)
1835                 return BLUETOOTH_ERROR_INVALID_PARAM;
1836
1837         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1838         BT_INFO("Mesh: Got CDB");
1839
1840         BT_INFO("Mesh: Total groups present in Network [%d]",
1841                         g_slist_length(cdb_cfg->groups));
1842
1843         for (l = cdb_cfg->groups; l; l = l->next) {
1844                 bluetooth_mesh_network_group_info_t grp;
1845                 _bt_mesh_group_t *group = l->data;
1846                 memset(&grp, 0x00, sizeof(bluetooth_mesh_network_group_info_t));
1847                 g_strlcpy(grp.net_uuid, network->uuid, sizeof(grp.net_uuid));
1848                 if (MESH_IS_GROUP(group->grp_addr) && !MESH_IS_VIRTUAL(group->grp_addr)) {
1849                         grp.is_virtual = false;
1850                         grp.group_addr = group->grp_addr;
1851                         BT_INFO("Mesh: Found Non-Virtual group, addr[0x%2.2x]", group->grp_addr);
1852                 } else if (MESH_IS_VIRTUAL(group->grp_addr)) {
1853                         grp.is_virtual = true;
1854                         grp.group_addr = group->grp_addr;
1855                         _bt_mesh_util_convert_hex_to_string((uint8_t *) group->label_uuid,
1856                                         16, grp.label_uuid, sizeof(grp.label_uuid));
1857                         BT_INFO("Mesh: Found Virtual group, addr[0x%2.2x]", group->grp_addr);
1858                         BT_INFO("Mesh: Label UUID[%s]", grp.label_uuid);
1859                 }
1860
1861                 g_array_append_vals(*out_param,
1862                                 &grp, sizeof(bluetooth_mesh_network_group_info_t));
1863         }
1864
1865         return BLUETOOTH_ERROR_NONE;
1866 }
1867
1868 int _bt_mesh_network_get_nodes(const char *app_cred,
1869                 const char *sender, bluetooth_mesh_network_t *network,
1870                         GArray **out_param)
1871 {
1872         GSList *l;
1873         _bt_mesh_cdb_t *cdb_cfg = NULL;
1874
1875         /* Find CDB */
1876         l = g_slist_find_custom(cdb_list, network->token.token,
1877                         __mesh_compare_app_cdb_token);
1878         if (!l)
1879                 return BLUETOOTH_ERROR_INVALID_PARAM;
1880
1881         cdb_cfg = (_bt_mesh_cdb_t*)l->data;
1882
1883         if (_bt_mesh_node_get_all(cdb_cfg->uuid, out_param))
1884                 return BLUETOOTH_ERROR_NONE;
1885         else
1886                 return BLUETOOTH_ERROR_INTERNAL;
1887 }