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