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