Fix the coverity issues
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / mesh / bt-service-mesh-cdb.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
22 #include <glib.h>
23 #include <dlog.h>
24 #include "bt-service-common.h"
25 #include "bt-service-core-adapter.h"
26 #include "bt-service-event-receiver.h"
27 #include "bt-request-handler.h"
28 #include "bluetooth-api.h"
29
30 #include "bluetooth-api.h"
31 #include "bluetooth-mesh-api.h"
32 #include "bt-internal-types.h"
33 #include "bt-service-util.h"
34 #include "bt-service-common.h"
35 #include "bt-service-event.h"
36 #include "bt-service-mesh-cdb.h"
37 #include "bt-service-mesh-nodes.h"
38 #include "bt-service-mesh-keys.h"
39 #include "bt-service-mesh-util.h"
40
41 #include "bt-internal-types.h"
42
43 #include <dirent.h>
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <ftw.h>
47 #include <libgen.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <unistd.h>
51 #include <sys/time.h>
52 #include <ell/ell.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-gatt.h>
60
61 static const char *bak_ext = ".bak";
62 static const char *tmp_ext = ".tmp";
63
64 static bool __bt_mesh_save_cdb(
65                 _bt_mesh_cdb_t *cfg, const char *fname)
66 {
67         FILE *outfile;
68         const char *str;
69         bool result = false;
70
71         outfile = fopen(fname, "w");
72         if (!outfile) {
73                 BT_ERR("Failed to save configuration to %s",
74                                 cfg->cfg_fname);
75                 return false;
76         }
77
78         str = json_object_to_json_string_ext(cfg->jcfg,
79                         JSON_C_TO_STRING_PRETTY);
80
81         if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
82                 BT_ERR("Incomplete write of mesh configuration");
83         else
84                 result = true;
85
86         fclose(outfile);
87
88         return result;
89 }
90
91 static bool __bt_mesh_save_configruation_file(_bt_mesh_cdb_t *cfg)
92 {
93         char *fname_tmp, *fname_bak, *fname_cfg;
94         bool result = false;
95
96         fname_cfg = cfg->cfg_fname;
97         fname_tmp = g_strdup_printf("%s%s", fname_cfg, tmp_ext);
98         fname_bak = g_strdup_printf("%s%s", fname_cfg, bak_ext);
99         remove(fname_tmp);
100
101         result = __bt_mesh_save_cdb(cfg, fname_tmp);
102
103         if (result) {
104                 remove(fname_bak);
105                 rename(fname_cfg, fname_bak);
106                 rename(fname_tmp, fname_cfg);
107         }
108
109         remove(fname_tmp);
110
111         g_free(fname_tmp);
112         g_free(fname_bak);
113
114         gettimeofday(&cfg->write_time, NULL);
115
116         return result;
117 }
118
119 static bool __mesh_get_int(json_object *jobj,
120                 const char *keyword, int *value)
121 {
122         json_object *jvalue;
123
124         if (!json_object_object_get_ex(jobj, keyword, &jvalue))
125                 return false;
126
127         *value = json_object_get_int(jvalue);
128         if (errno == EINVAL) {
129                 BT_ERR("MESH:Error: %s should contain an integer value\n",
130                                 keyword);
131                 return false;
132         }
133
134         return true;
135 }
136
137 static uint16_t __mesh_node_parse_key(json_object *jarray, int i)
138 {
139         json_object *jkey;
140         int idx;
141
142         jkey = json_object_array_get_idx(jarray, i);
143         if (!jkey)
144                 return MESH_KEY_IDX_INVALID;
145
146         if (!__mesh_get_int(jkey, "index", &idx))
147                 return MESH_KEY_IDX_INVALID;
148
149         return (uint16_t)idx;
150 }
151
152 static bool __mesh_write_int(json_object *jobj,
153                 const char *keyword, int val)
154 {
155         json_object *jval;
156
157         json_object_object_del(jobj, keyword);
158
159         jval = json_object_new_int(val);
160         if (!jval)
161                 return false;
162
163         json_object_object_add(jobj, keyword, jval);
164         return true;
165 }
166
167 static bool __mesh_write_uint32_hex(json_object *jobj,
168                 const char *desc, uint32_t val)
169 {
170         json_object *jstring;
171         char buf[9];
172
173         snprintf(buf, 9, "%8.8x", val);
174         jstring = json_object_new_string(buf);
175         if (!jstring)
176                 return false;
177
178         /* Overwrite old value if present */
179         json_object_object_del(jobj, desc);
180
181         json_object_object_add(jobj, desc, jstring);
182         return true;
183 }
184
185 static bool __mesh_write_uint16_hex(json_object *jobj,
186                 const char *desc, uint16_t value)
187 {
188         json_object *jstring;
189         char buf[5];
190
191         snprintf(buf, 5, "%4.4x", value);
192         jstring = json_object_new_string(buf);
193         if (!jstring)
194                 return false;
195
196         json_object_object_add(jobj, desc, jstring);
197         return true;
198 }
199
200 static json_object *__mesh_init_model(uint16_t mod_id)
201 {
202         json_object *jmod;
203
204         jmod = json_object_new_object();
205
206         if (!__mesh_write_uint16_hex(jmod, "modelId", mod_id)) {
207                 json_object_put(jmod);
208                 return NULL;
209         }
210
211         return jmod;
212 }
213
214 static json_object *__mesh_init_vendor_model(uint32_t mod_id)
215 {
216         json_object *jmod;
217
218         jmod = json_object_new_object();
219
220         if (!__mesh_write_uint32_hex(jmod, "modelId", mod_id)) {
221                 json_object_put(jmod);
222                 return NULL;
223         }
224
225         return jmod;
226 }
227
228 static json_object *__mesh_init_elements(uint8_t num_els)
229 {
230         json_object *jelements;
231         uint8_t i;
232
233         jelements = json_object_new_array();
234
235         for (i = 0; i < num_els; ++i) {
236                 json_object *jelement, *jmods;
237
238                 jelement = json_object_new_object();
239
240                 __mesh_write_int(jelement, "index", i);
241                 __mesh_write_uint16_hex(jelement, "location", MESH_DEFAULT_LOCATION);
242                 jmods = json_object_new_array();
243                 json_object_object_add(jelement, "models", jmods);
244
245                 json_object_array_add(jelements, jelement);
246         }
247
248         return jelements;
249 }
250 static bool __mesh_add_app_key(json_object *jobj,
251                 uint16_t net_idx, uint16_t app_idx)
252 {
253         json_object *jkey, *jarray;
254
255         json_object_object_get_ex(jobj, "appKeys", &jarray);
256         if (!jarray || json_object_get_type(jarray) != json_type_array)
257                 return false;
258
259         jkey = json_object_new_object();
260
261         if (!__mesh_write_int(jkey, "boundNetKey", (int)net_idx))
262                 goto fail;
263
264         if (!__mesh_write_int(jkey, "index", (int)app_idx))
265                 goto fail;
266
267         json_object_array_add(jarray, jkey);
268
269         return true;
270 fail:
271         json_object_put(jkey);
272         return false;
273 }
274
275 static bool __mesh_add_node_key(_bt_mesh_cdb_t *cfg,
276                 json_object *jobj, const char *desc, uint16_t idx)
277 {
278         json_object *jkey, *jarray;
279
280         json_object_object_get_ex(jobj, desc, &jarray);
281         if (!jarray || json_object_get_type(jarray) != json_type_array)
282                 return false;
283
284         jkey = json_object_new_object();
285
286         if (!__mesh_write_int(jkey, "index", (int)idx)) {
287                 json_object_put(jkey);
288                 return false;
289         }
290
291         json_object_array_add(jarray, jkey);
292
293         return __bt_mesh_save_configruation_file(cfg);
294 }
295
296 static json_object *__mesh_get_node_by_unicast(_bt_mesh_cdb_t *cfg,
297                 uint16_t unicast)
298 {
299         json_object *jarray;
300         int i, sz;
301
302         if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jarray))
303                 return NULL;
304
305         if (!jarray || json_object_get_type(jarray) != json_type_array)
306                 return NULL;
307
308         sz = json_object_array_length(jarray);
309
310         for (i = 0; i < sz; ++i) {
311                 json_object *jentry, *jval;
312                 uint16_t addr;
313                 const char *str;
314
315                 jentry = json_object_array_get_idx(jarray, i);
316                 if (!json_object_object_get_ex(jentry, "unicastAddress",
317                                         &jval))
318                         return NULL;
319
320                 str = json_object_get_string(jval);
321                 if (sscanf(str, "%04hx", &addr) != 1)
322                         continue;
323
324                 if (addr == unicast)
325                         return jentry;
326         }
327
328         return NULL;
329 }
330
331 static json_object *__mesh_get_node_by_uuid(json_object *jcfg,
332                 uint8_t uuid[16])
333 {
334         json_object *jarray = NULL;
335         char buf[33];
336         int i, sz;
337
338         _bt_mesh_util_convert_hex_to_string(uuid, 16, buf, sizeof(buf));
339         BT_INFO("Mesh: Find Node with UUID [%s]", buf);
340
341         json_object_object_get_ex(jcfg, "nodes", &jarray);
342         if (!jarray || json_object_get_type(jarray) != json_type_array)
343                 return NULL;
344
345         sz = json_object_array_length(jarray);
346         BT_INFO("Mesh: Total nodes present in CDB [%d]", sz);
347
348         for (i = 0; i < sz; ++i) {
349                 json_object *jentry, *jval;
350                 const char *str;
351
352                 jentry = json_object_array_get_idx(jarray, i);
353                 if (!json_object_object_get_ex(jentry, "uuid", &jval))
354                         return NULL;
355
356                 str = json_object_get_string(jval);
357                 if (strlen(str) != 32)
358                         continue;
359                 BT_INFO("Mesh: Got one node with UUID [%s]", str);
360                 BT_INFO("Mesh: Match with uuid [%s]", buf);
361
362                 if (!g_strcmp0(buf, str))
363                         return jentry;
364         }
365
366         return NULL;
367 }
368
369 static json_object *__mesh_get_key_object(json_object *jarray,
370                 uint16_t idx)
371 {
372         int i, sz = json_object_array_length(jarray);
373
374         for (i = 0; i < sz; ++i) {
375                 json_object *jentry;
376                 int jidx;
377
378                 jentry = json_object_array_get_idx(jarray, i);
379                 if (!__mesh_get_int(jentry, "index", &jidx))
380                         return NULL;
381
382                 if (jidx == idx)
383                         return jentry;
384         }
385
386         return NULL;
387 }
388
389 static bool __mesh_add_string(json_object *jobj,
390                 const char *desc, const char *str)
391 {
392         json_object *jstring = json_object_new_string(str);
393
394         if (!jstring)
395                 return false;
396
397         json_object_object_add(jobj, desc, jstring);
398         return true;
399 }
400
401 static bool __mesh_get_token(json_object *jobj, uint8_t token[8])
402 {
403         json_object *jval;
404         const char *str;
405
406         if (!json_object_object_get_ex(jobj, "Network_Token", &jval))
407                 return false;
408
409         str = json_object_get_string(jval);
410         if (!_bt_mesh_util_convert_string_to_hex(str, strlen(str), token, 8))
411                 return false;
412
413         return true;
414 }
415
416 static bool __mesh_get_uuid(json_object *jobj, uint8_t uuid[16])
417 {
418         json_object *jval;
419         const char *str;
420
421         if (!json_object_object_get_ex(jobj, "Config_Node_UUID", &jval))
422                 return false;
423
424         str = json_object_get_string(jval);
425         if (!_bt_mesh_util_convert_string_to_hex(str, strlen(str), uuid, 16))
426                 return false;
427
428         return true;
429 }
430
431 static bool __mesh_add_u8_8(json_object *jobj,
432                 const char *desc, const uint8_t value[8])
433 {
434         json_object *jstring;
435         char buf[17];
436
437         _bt_mesh_util_convert_hex_to_string((uint8_t *) value, 8, buf, 17);
438         jstring = json_object_new_string(buf);
439         if (!jstring)
440                 return false;
441
442         json_object_object_add(jobj, desc, jstring);
443         return true;
444 }
445
446 static bool __mesh_add_u8_16(json_object *jobj,
447                 const char *desc, const uint8_t value[16])
448 {
449         json_object *jstring;
450         char buf[33];
451
452         _bt_mesh_util_convert_hex_to_string((uint8_t *) value, 16, buf, 33);
453         jstring = json_object_new_string(buf);
454         if (!jstring)
455                 return false;
456
457         json_object_object_add(jobj, desc, jstring);
458         return true;
459 }
460
461 void _bt_mesh_conf_free(_bt_mesh_cdb_t *cfg)
462 {
463         g_free(cfg->cfg_fname);
464         g_free(cfg->owner);
465         g_free(cfg->app_cred);
466         json_object_put(cfg->jcfg);
467         g_slist_free_full(cfg->groups, g_free);
468         g_free(cfg);
469 }
470
471 bool _bt_mesh_conf_parse_data(void *cfg,  int k)
472 {
473         _bt_mesh_cdb_t *conf = (_bt_mesh_cdb_t*) cfg;
474         if (!conf)
475                 return false;
476         return true;
477 }
478
479 static bool __mesh_jarray_group_delete(json_object *jarray, uint16_t group_addr)
480 {
481         int i, sz = json_object_array_length(jarray);
482         json_object *jval;
483         char buf[15];
484
485         for (i = 0; i < sz; ++i) {
486                 json_object *jentry;
487                 uint16_t addr;
488                 const char *str;
489
490                 jentry = json_object_array_get_idx(jarray, i);
491                 if (!json_object_object_get_ex(jentry, "name",
492                                         &jval))
493                         continue;
494
495                 str = json_object_get_string(jval);
496                 if (!str)
497                         continue;
498                 memcpy(buf, str + 6, 5);
499                 BT_INFO("Mesh: JSON Group string:[%s]", buf);
500                 if (sscanf(buf, "%04hx", &addr) != 1)
501                         continue;
502                 BT_INFO("Mesh: JSON Group in Hex [0x%2.2x]", addr);
503
504                 if (group_addr == addr)
505                         break;
506
507         }
508         if (i == sz) {
509                 BT_INFO("Mesh: Failed to remove group");
510                 return false;
511         }
512
513         json_object_array_del_idx(jarray, i, 1);
514         return true;
515 }
516
517 static void __mesh_jarray_key_del(json_object *jarray, int16_t idx)
518 {
519         int i, sz = json_object_array_length(jarray);
520
521         for (i = 0; i < sz; ++i) {
522                 json_object *jentry;
523                 int val;
524
525                 jentry = json_object_array_get_idx(jarray, i);
526
527                 if (!__mesh_get_int(jentry, "index", &val))
528                         continue;
529
530                 if (val == idx) {
531                         json_object_array_del_idx(jarray, i, 1);
532                         return;
533                 }
534         }
535 }
536
537 static bool __mesh_delete_group(_bt_mesh_cdb_t *cfg,
538                 json_object *jobj, const char *desc, uint16_t addr)
539 {
540         json_object *jarray;
541
542         if (!json_object_object_get_ex(jobj, desc, &jarray))
543                 return false;
544
545         if (!__mesh_jarray_group_delete(jarray, addr))
546                 return false;
547
548         return __bt_mesh_save_configruation_file(cfg);
549 }
550
551 static bool __mesh_delete_key(_bt_mesh_cdb_t *cfg,
552                 json_object *jobj, const char *desc, uint16_t idx)
553 {
554         json_object *jarray;
555
556         if (!json_object_object_get_ex(jobj, desc, &jarray))
557                 return true;
558
559         __mesh_jarray_key_del(jarray, idx);
560
561         return __bt_mesh_save_configruation_file(cfg);
562 }
563
564 bool _bt_mesh_conf_set_phase_network_key(_bt_mesh_cdb_t *cfg,
565                 uint16_t net_idx, uint8_t phase)
566 {
567         json_object *jval, *jarray, *jkey;
568
569         if (!cfg || !cfg->jcfg)
570                 return false;
571
572         json_object_object_get_ex(cfg->jcfg, "netKeys", &jarray);
573         if (!jarray || json_object_get_type(jarray) != json_type_array)
574                 return false;
575
576         jkey = __mesh_get_key_object(jarray, net_idx);
577         if (!jkey)
578                 return false;
579
580         jval = json_object_new_int(phase);
581         if (!jval)
582                 return false;
583
584         json_object_object_add(jkey, "phase", jval);
585
586         return __bt_mesh_save_configruation_file(cfg);
587 }
588
589 bool _bt_mesh_conf_delete_application_key(_bt_mesh_cdb_t *cfg, uint16_t app_idx)
590 {
591         if (!cfg || !cfg->jcfg)
592                 return false;
593
594         return __mesh_delete_key(cfg, cfg->jcfg, "appKeys", app_idx);
595 }
596
597 bool _bt_mesh_conf_set_model_info(_bt_mesh_cdb_t *cfg,
598                 uint16_t unicast, GSList *models)
599 {
600         int sz;
601         json_object *jnode, *jobj, *jelements;
602         GSList *l;
603
604         BT_INFO("Mesh: Set All model informations in the node [0x%2.2x]",
605                         unicast);
606
607         if (!cfg || !cfg->jcfg)
608                 return false;
609
610         jnode = __mesh_get_node_by_unicast(cfg, unicast);
611         if (!jnode)
612                 return false;
613
614         jelements = json_object_object_get(jnode, "elements");
615         if (!jelements)
616                 return false;
617
618         sz = json_object_array_length(jelements);
619         BT_INFO("Mesh: Total elements [%d]", sz);
620         BT_INFO("Mesh: Total Models in List [%d]",
621                         g_slist_length(models));
622
623         for (l = models; l != NULL; l = g_slist_next(l)) {
624                 json_object *jentry, *jmods;
625                 bluetooth_mesh_model_t *mod = l->data;
626
627                 BT_INFO("Mesh: Elem Idx [%u]", mod->elem_index);
628                 BT_INFO("Mesh: Model ID [0x%4.4x]", mod->model_id);
629
630                 jentry = json_object_array_get_idx(jelements, mod->elem_index);
631                 if (!jentry)
632                         return false;
633
634                 /* Write Index for the eleement */
635                 if (!__mesh_write_int(jentry, "index", (int)mod->elem_index))
636                         return false;
637
638                 /* Set Hardcoded location */
639                 if (!__mesh_write_uint16_hex(jentry, "location", 0x0000))
640                         return false;
641
642                 jmods = json_object_object_get(jentry, "models");
643                 if (!jmods) {
644                         /* For backwards compatibility */
645                         jmods = json_object_new_array();
646                         json_object_object_add(jentry, "models", jmods);
647                 }
648
649                 /* TODO: Vendor Model Entry: Only BT SIG model entry is handled now */
650                 jobj = __mesh_init_model((uint16_t)mod->model_id);
651                 if (!jobj)
652                         return false;
653
654                 json_object_array_add(jmods, jobj);
655         }
656
657         /* Save */
658         return  __bt_mesh_save_configruation_file(cfg);
659 }
660
661 bool _bt_mesh_conf_set_vendor_info(_bt_mesh_cdb_t *cfg,
662                 uint16_t unicast, uint16_t crpl, uint16_t cid,
663                         uint16_t vid, uint16_t pid,
664                                 int proxy, int relay,
665                                         int lpn, int frnd)
666 {
667         json_object *jnode, *jobj;
668
669         BT_INFO("Mesh: Set Vednor Information in CDB for node [0x%2.2x]",
670                         unicast);
671
672         if (!cfg || !cfg->jcfg)
673                 return false;
674
675         jnode = __mesh_get_node_by_unicast(cfg, unicast);
676         if (!jnode) {
677                 BT_INFO("Mesh: Node not found");
678                 return false;
679         }
680
681         /* Company ID */
682         if (!__mesh_write_uint16_hex(jnode, "crpl", crpl)) {
683                 BT_ERR("Mesh: Could not write CRPL");
684                 return false;
685         }
686
687         /* Company ID */
688         if (!__mesh_write_uint16_hex(jnode, "cid", cid)) {
689                 BT_ERR("Mesh: Could not write CID");
690                 return false;
691         }
692
693         /* Vendor ID or Product ID */
694         if (!__mesh_write_uint16_hex(jnode, "pid", pid)) {
695                 BT_INFO("Mesh: Could not write PID");
696                 return false;
697         }
698
699         /* Version ID */
700         if (!__mesh_write_uint16_hex(jnode, "vid", vid)) {
701                 BT_INFO("Mesh: Could not write VID");
702                 return false;
703         }
704
705         jobj = json_object_object_get(jnode, "features");
706         if (!jobj) {
707                 jobj = json_object_new_object();
708                 json_object_object_add(jnode, "features", jobj);
709         }
710
711         BT_INFO("Mesh: Set features in CDB");
712
713         __mesh_write_int(jobj, "relay", relay ? 1 : 0);
714         __mesh_write_int(jobj, "friend", frnd ? 1 : 0);
715         __mesh_write_int(jobj, "proxy", proxy ? 1 : 0);
716         __mesh_write_int(jobj, "lowPower", lpn ? 1 : 0);
717
718         BT_INFO("Mesh: All vendor Info data set successfully");
719
720         return __bt_mesh_save_configruation_file(cfg);
721 }
722
723 bool _bt_mesh_conf_set_unicast_address_range(_bt_mesh_cdb_t *cfg,
724                 uint16_t low, uint16_t high)
725 {
726         if (!cfg || !cfg->jcfg)
727                 return false;
728
729         if (!__mesh_write_uint16_hex(cfg->jcfg, "low", low))
730                 return false;
731
732         if (!__mesh_write_uint16_hex(cfg->jcfg, "high", high))
733                 return false;
734
735         return __bt_mesh_save_configruation_file(cfg);
736 }
737
738 bool _bt_mesh_conf_insert_node_object(_bt_mesh_cdb_t *cfg,
739                 uint8_t uuid[16], uint8_t num_els,
740                         uint16_t unicast, uint16_t net_idx)
741 {
742         json_object *jnode;
743         json_object *jelements, *jnodes, *jnetkeys, *jappkeys;
744         int i;
745
746         if (!cfg || !cfg->jcfg)
747                 return false;
748
749         jnode = __mesh_get_node_by_uuid(cfg->jcfg, uuid);
750         if (jnode) {
751                 BT_ERR("MESH:Node already exists");
752                 return false;
753         }
754
755         jnode = json_object_new_object();
756         if (!jnode)
757                 return false;
758
759         if (!__mesh_add_u8_16(jnode, "uuid", uuid))
760                 goto fail;
761
762         jelements = json_object_new_array();
763         if (!jelements)
764                 goto fail;
765
766         for (i = 0; i < num_els; ++i) {
767                 json_object *jelement = json_object_new_object();
768
769                 if (!jelement) {
770                         json_object_put(jelements);
771                         goto fail;
772                 }
773
774                 __mesh_write_int(jelement, "elementIndex", i);
775                 json_object_array_add(jelements, jelement);
776         }
777
778         json_object_object_add(jnode, "elements", jelements);
779
780         jnetkeys = json_object_new_array();
781         if (!jnetkeys)
782                 goto fail;
783
784         json_object_object_add(jnode, "netKeys", jnetkeys);
785
786         if (!__mesh_add_node_key(cfg, jnode, "netKeys", net_idx))
787                 goto fail;
788
789         jappkeys = json_object_new_array();
790         if (!jappkeys)
791                 goto fail;
792
793         json_object_object_add(jnode, "appKeys", jappkeys);
794
795         if (!__mesh_write_uint16_hex(jnode, "unicastAddress", unicast))
796                 goto fail;
797
798         if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes))
799                 goto fail;
800
801         json_object_array_add(jnodes, jnode);
802
803         if (!__bt_mesh_save_configruation_file(cfg))
804                 goto fail;
805
806         return true;
807
808 fail:
809         json_object_put(jnode);
810         return false;
811 }
812
813 bool _bt_mesh_conf_insert_application_key(_bt_mesh_cdb_t *cfg,
814                 uint16_t net_idx, uint16_t app_idx)
815 {
816         if (!cfg || !cfg->jcfg)
817                 return false;
818
819         if (!__mesh_add_app_key(cfg->jcfg, net_idx, app_idx))
820                 return false;
821
822         return __bt_mesh_save_configruation_file(cfg);
823 }
824
825 bool _bt_mesh_conf_insert_network_key(_bt_mesh_cdb_t *cfg,
826                 uint16_t net_idx, uint8_t key_refresh)
827 {
828         json_object *jkey, *jarray;
829
830         if (!cfg || !cfg->jcfg)
831                 return false;
832
833         json_object_object_get_ex(cfg->jcfg, "netKeys", &jarray);
834         if (!jarray || json_object_get_type(jarray) != json_type_array)
835                 return false;
836
837         if (__mesh_get_key_object(jarray, net_idx))
838                 return true;
839
840         jkey = json_object_new_object();
841
842         if (!__mesh_write_int(jkey, "index", net_idx))
843                 goto fail;
844
845         if (!__mesh_write_int(jkey, "phase", key_refresh))
846                 goto fail;
847
848         json_object_array_add(jarray, jkey);
849
850         return __bt_mesh_save_configruation_file(cfg);
851
852 fail:
853         json_object_put(jkey);
854         return false;
855 }
856
857 bool _bt_mesh_conf_delete_network_key(_bt_mesh_cdb_t *cfg,
858                 uint16_t net_idx)
859 {
860         if (!cfg || !cfg->jcfg)
861                 return false;
862
863         return __mesh_delete_key(cfg, cfg->jcfg, "netKeys", net_idx);
864 }
865
866
867 bool _bt_mesh_conf_node_set_timetolive_value(_bt_mesh_cdb_t *cfg,
868                 uint16_t unicast, uint8_t ttl)
869 {
870         json_object *jnode;
871
872         if (!cfg || !cfg->jcfg)
873                 return false;
874
875         jnode = __mesh_get_node_by_unicast(cfg, unicast);
876         if (!jnode)
877                 return false;
878
879         if (!__mesh_write_int(jnode, "defaultTTL", ttl))
880                 return false;
881
882         return __bt_mesh_save_configruation_file(cfg);
883 }
884
885 bool _bt_mesh_conf_node_insert_network_key(_bt_mesh_cdb_t *cfg,
886                 uint16_t unicast, uint16_t net_idx)
887 {
888         json_object *jnode;
889
890         if (!cfg || !cfg->jcfg)
891                 return false;
892
893         jnode = __mesh_get_node_by_unicast(cfg, unicast);
894         if (!jnode)
895                 return false;
896
897         return __mesh_add_node_key(cfg, jnode, "netKeys", net_idx);
898 }
899
900 bool _bt_mesh_conf_node_delete_network_key(_bt_mesh_cdb_t *cfg,
901                 uint16_t unicast, uint16_t net_idx)
902 {
903         json_object *jnode;
904
905         if (!cfg || !cfg->jcfg)
906                 return false;
907
908         jnode = __mesh_get_node_by_unicast(cfg, unicast);
909         if (!jnode)
910                 return false;
911
912         return __mesh_delete_key(cfg, jnode, "netKeys", net_idx);
913 }
914
915 bool _bt_mesh_conf_node_insert_application_key(_bt_mesh_cdb_t *cfg,
916                 uint16_t unicast, uint16_t idx)
917 {
918         json_object *jnode;
919
920         if (!cfg || !cfg->jcfg)
921                 return false;
922
923         jnode = __mesh_get_node_by_unicast(cfg, unicast);
924         if (!jnode)
925                 return false;
926
927         return __mesh_add_node_key(cfg, jnode, "appKeys", idx);
928 }
929
930 bool _bt_mesh_conf_node_delete_application_key(_bt_mesh_cdb_t *cfg,
931         uint16_t unicast, uint16_t idx)
932 {
933         json_object *jnode;
934
935         if (!cfg || !cfg->jcfg)
936                 return false;
937
938         jnode = __mesh_get_node_by_unicast(cfg, unicast);
939         if (!jnode)
940                 return false;
941
942         return __mesh_delete_key(cfg, jnode, "appKeys", idx);
943 }
944
945 _bt_mesh_cdb_t *_bt_mesh_conf_database_create(const char *file_name,
946                 const uint8_t uuid[16],
947                         const uint8_t token[8], const char *network_name,
948                                 const char *sender, const char *app_cred)
949 {
950         _bt_mesh_cdb_t *cfg;
951         json_object *jcfg, *jarray;
952
953         if (!file_name)
954                 return NULL;
955
956         if (!network_name)
957                 return NULL;
958
959         if (!app_cred)
960                 return NULL;
961
962         jcfg = json_object_new_object();
963         if (!jcfg)
964                 return NULL;
965
966         cfg = g_malloc0(sizeof(_bt_mesh_cdb_t));
967         cfg->jcfg = jcfg;
968         cfg->cfg_fname = g_strdup(file_name);
969         cfg->owner = g_strdup(sender);
970         cfg->app_cred = g_strdup(app_cred);
971         memcpy(&cfg->token, (void*)token, 8);
972         memcpy(&cfg->uuid, (void*)uuid, 16);
973
974         if (!__mesh_add_u8_8(jcfg, "Network_Token", token))
975                 goto fail;
976
977         if (!__mesh_add_u8_16(jcfg, "Config_Node_UUID", uuid))
978                 goto fail;
979
980         if (!__mesh_add_string(jcfg, "Network_Name", network_name))
981                 goto fail;
982
983         if (!__mesh_add_string(jcfg, "Application_Credential", app_cred))
984                 goto fail;
985
986         jarray = json_object_new_array();
987         if (!jarray)
988                 goto fail;
989
990         json_object_object_add(jcfg, "nodes", jarray);
991
992         jarray = json_object_new_array();
993         if (!jarray)
994                 goto fail;
995
996         json_object_object_add(jcfg, "netKeys", jarray);
997
998         jarray = json_object_new_array();
999         if (!jarray)
1000                 goto fail;
1001
1002         json_object_object_add(jcfg, "appKeys", jarray);
1003
1004         if (!__bt_mesh_save_configruation_file(cfg))
1005                 goto fail;
1006
1007         return cfg;
1008
1009 fail:
1010         _bt_mesh_conf_free(cfg);
1011
1012         return NULL;
1013 }
1014
1015 bool _bt_mesh_conf_delete_node(_bt_mesh_cdb_t *cfg, uint16_t unicast)
1016 {
1017         json_object *jarray;
1018         int i, sz;
1019
1020         if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jarray))
1021                 return false;
1022
1023         if (!jarray || json_object_get_type(jarray) != json_type_array)
1024                 return false;
1025
1026         sz = json_object_array_length(jarray);
1027
1028         for (i = 0; i < sz; ++i) {
1029                 json_object *jentry, *jval;
1030                 uint16_t addr;
1031                 const char *str;
1032
1033                 jentry = json_object_array_get_idx(jarray, i);
1034                 if (!json_object_object_get_ex(jentry, "unicastAddress",
1035                                         &jval))
1036                         continue;
1037
1038                 str = json_object_get_string(jval);
1039                 if (sscanf(str, "%04hx", &addr) != 1)
1040                         continue;
1041
1042                 if (addr == unicast)
1043                         break;
1044         }
1045
1046         if (i == sz)
1047                 return true;
1048
1049         json_object_array_del_idx(jarray, i, 1);
1050
1051         return __bt_mesh_save_configruation_file(cfg);
1052 }
1053
1054 uint16_t** _bt_mesh_conf_get_all_model_info(_bt_mesh_cdb_t *cfg,
1055                 int element_index, int *num_models)
1056 {
1057         int sz;
1058         int i;
1059         json_object *jcfg;
1060         json_object *jnode;
1061         json_object *jarray = NULL;
1062         json_object *jelement = NULL;
1063         json_object *jmodelarray = NULL;
1064         const char *str;
1065         uint16_t **models = NULL;
1066
1067         if (!cfg)
1068                 return NULL;
1069
1070         jcfg = cfg->jcfg;
1071         if (!jcfg)
1072                 return NULL;
1073
1074         jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
1075         if (!jnode) {
1076                 BT_ERR("Mesh: Node not found with UUID");
1077                 return NULL;
1078         }
1079
1080         /* Get element array object */
1081         json_object_object_get_ex(jnode, "elements", &jarray);
1082
1083         if (!jarray || json_object_get_type(jarray) != json_type_array) {
1084                 BT_ERR("Mesh:could not get element array");
1085                 return NULL;
1086         }
1087
1088         /* Get specific element by index */
1089         jelement = __mesh_get_key_object(jarray, element_index);
1090         if (!jelement) {
1091                 BT_ERR("Mesh: Could not find element");
1092                 return NULL;
1093         }
1094
1095         /* Get Model array object inside the selected element */
1096         json_object_object_get_ex(jelement, "models", &jmodelarray);
1097
1098         if (!jmodelarray || json_object_get_type(jmodelarray) != json_type_array) {
1099                 BT_ERR("Mesh: Could not get Model Array");
1100                 return NULL;
1101         }
1102
1103         sz = json_object_array_length(jmodelarray);
1104         BT_INFO("Mesh: Total number of Models in Element index [%d] is [%d]",
1105                         element_index, sz);
1106
1107         models = (uint16_t**) g_malloc0(sz * sizeof(uint16_t*));
1108
1109         for (i = 0; i < sz; ++i) {
1110                 json_object *jentry, *jval;
1111                 uint16_t mod_id;
1112
1113                 BT_INFO("Mesh: Model [%d]", i);
1114                 jentry = json_object_array_get_idx(jmodelarray, i);
1115
1116                 if (!json_object_object_get_ex(jentry, "modelId", &jval)) {
1117                         BT_ERR("Mesh: Failed to read Model in index [%d]", i);
1118                         for (int j = 0 ; j < sz; j++)
1119                                 g_free(models[j]);
1120                         g_free(models);
1121                         return NULL;
1122                 }
1123
1124                 str = json_object_get_string(jval);
1125                 BT_INFO("Mesh: Model ID String [%s]", str);
1126                 /* Only standard models are handled now */
1127                 if (sscanf(str, "%04hx", &mod_id) != 1) {
1128                         BT_INFO("Mesh: Failed to read Model ID from Model entry [%s]", str);
1129                         for (int j = 0 ; j < sz; j++)
1130                                 g_free(models[j]);
1131                         g_free(models);
1132                         return NULL;
1133                 }
1134
1135                 BT_INFO("Mesh: Model string [%s] Model ID [0x%4.4x]", str, mod_id);
1136                 models[i] = g_malloc0(sizeof(uint16_t));
1137                 *models[i] = mod_id;
1138         }
1139         /* TODO: Need to handle vendor models */
1140         BT_INFO("Mesh: Got all model info");
1141         *num_models = sz;
1142         return models;
1143 }
1144
1145 bool _bt_mesh_conf_get_element_count(_bt_mesh_cdb_t *cfg,
1146                 uint16_t *num_elems)
1147 {
1148         int sz;
1149         json_object *jcfg;
1150         json_object *jnode;
1151         json_object *jarray = NULL;
1152
1153         if (!cfg)
1154                 return false;
1155
1156         jcfg = cfg->jcfg;
1157         if (!jcfg)
1158                 return false;
1159
1160         jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
1161         if (!jnode) {
1162                 BT_ERR("Mesh: Node by UUID not found");
1163                 return false;
1164         }
1165
1166         json_object_object_get_ex(jnode, "elements", &jarray);
1167
1168         if (!jarray || json_object_get_type(jarray) != json_type_array) {
1169                 BT_ERR("Mesh: Element array not found in Node");
1170                 return false;
1171         }
1172
1173         sz = json_object_array_length(jarray);
1174         if (sz == 0) {
1175                 BT_ERR("Mesh: Element array length is 0");
1176                 return false;
1177         }
1178         *num_elems = sz;
1179
1180         return true;
1181 }
1182
1183 bool _bt_mesh_conf_fetch_vendor_specific_info(
1184         _bt_mesh_cdb_t *cfg, uint16_t unicast,
1185                 uint16_t *cid, uint16_t *vid,
1186                         uint16_t *version, uint16_t *crpl,
1187                                 int *relay, int *friend,
1188                                         int *proxy, int *lpn)
1189 {
1190         json_object *jcfg;
1191         json_object *jnode;
1192         json_object *jobj = NULL;
1193         json_object *jobjfeature = NULL;
1194         const char *str;
1195
1196         if (!cfg)
1197                 return false;
1198         jcfg = cfg->jcfg;
1199         if (!jcfg)
1200                 return false;
1201
1202         jnode = __mesh_get_node_by_unicast(cfg, unicast);
1203         if (!jnode) {
1204                 BT_ERR("Mesh: Node not found by unicast [0x%2.2x]", unicast);
1205                 return false;
1206         }
1207
1208         /* Get CRPL */
1209         if (!json_object_object_get_ex(jnode, "crpl", &jobj)) {
1210                 BT_ERR("Mesh: CRPL info not found");
1211                 return false;
1212         }
1213
1214         str = json_object_get_string(jobj);
1215         if (!str)
1216                 return false;
1217
1218         if (sscanf(str, "%04hx", crpl) != 1)
1219                 return false;
1220
1221         BT_INFO("Mesh: Got CRPL[%s]", str);
1222         /* Get Company ID */
1223         if (!json_object_object_get_ex(jnode, "cid", &jobj))
1224                 return false;
1225
1226         str = json_object_get_string(jobj);
1227         if (!str)
1228                 return false;
1229         if (sscanf(str, "%04hx", cid) != 1)
1230                 return false;
1231
1232         BT_INFO("Mesh: Got CID[%s]", str);
1233         /* Get Vendor ID */
1234         if (!json_object_object_get_ex(jnode, "pid", &jobj))
1235                 return false;
1236
1237         str = json_object_get_string(jobj);
1238         if (!str)
1239                 return false;
1240
1241         if (sscanf(str, "%04hx", vid) != 1)
1242                 return false;
1243
1244         BT_INFO("Mesh: Got PID[%s]", str);
1245         /* Get Version ID */
1246         if (!json_object_object_get_ex(jnode, "vid", &jobj))
1247                 return false;
1248
1249         str = json_object_get_string(jobj);
1250         if (!str)
1251                 return false;
1252         if (sscanf(str, "%04hx", version) != 1)
1253                 return false;
1254
1255         BT_INFO("Mesh: got version [%s]", str);
1256         jobj = json_object_object_get(jnode, "features");
1257
1258         if (jobj) {
1259                 if (json_object_object_get_ex(jobj, "relay", &jobjfeature)) {
1260                         str = json_object_get_string(jobjfeature);
1261                         if (str) {
1262                                 sscanf(str, "%d", relay);
1263                                 BT_INFO("Mesh: Got Relay [%s]", str);
1264                         }
1265                 }
1266
1267                 if (json_object_object_get_ex(jobj, "friend", &jobjfeature)) {
1268                         str = json_object_get_string(jobjfeature);
1269                         if (str) {
1270                                 sscanf(str, "%d", friend);
1271                                 BT_INFO("Mesh: Got Friend [%s]", str);
1272                         }
1273                 }
1274
1275                 if (json_object_object_get_ex(jobj, "proxy", &jobjfeature)) {
1276                         str = json_object_get_string(jobjfeature);
1277                         if (str) {
1278                                 sscanf(str, "%d", proxy);
1279                                 BT_INFO("Mesh: Got Proxy[%s]", str);
1280                         }
1281                 }
1282                 if (json_object_object_get_ex(jobj, "lowPower", &jobjfeature)) {
1283                         str = json_object_get_string(jobjfeature);
1284                         if (str) {
1285                                 sscanf(str, "%d", lpn);
1286                                 BT_INFO("Mesh: Got LPN[%s]", str);
1287                         }
1288                 }
1289         }
1290         return true;
1291 }
1292
1293 GSList *_bt_mesh_conf_load_group_info(_bt_mesh_cdb_t *cfg)
1294 {
1295         json_object *jgroups;
1296         GSList *groups = NULL;
1297         int i, sz;
1298
1299         if (!cfg || !cfg->jcfg)
1300                 return NULL;
1301
1302         if (!json_object_object_get_ex(cfg->jcfg, "groups", &jgroups)) {
1303                 jgroups = json_object_new_array();
1304                 if (!jgroups)
1305                         return NULL;
1306
1307                 json_object_object_add(cfg->jcfg, "groups", jgroups);
1308         }
1309
1310         sz = json_object_array_length(jgroups);
1311
1312         for (i = 0; i < sz; ++i) {
1313                 json_object *jgroup, *jval;
1314                 _bt_mesh_group_t *grp;
1315                 uint16_t addr, addr_len;
1316                 const char *str;
1317
1318                 jgroup = json_object_array_get_idx(jgroups, i);
1319                 if (!jgroup)
1320                         continue;
1321
1322                 if (!json_object_object_get_ex(jgroup, "name", &jval))
1323                         continue;
1324
1325                 str = json_object_get_string(jval);
1326                 if (strlen(str) != 10)
1327                         continue;
1328
1329                 if (sscanf(str + 6, "%04hx", &addr) != 1)
1330                         continue;
1331                 if (!json_object_object_get_ex(jgroup, "address", &jval))
1332                         continue;
1333
1334                 str = json_object_get_string(jval);
1335                 addr_len = strlen(str);
1336                 if (addr_len != 4 && addr_len != 32)
1337                         continue;
1338
1339                 if (addr_len == 32 && !MESH_IS_VIRTUAL(addr))
1340                         continue;
1341
1342                 grp = g_malloc0(sizeof(_bt_mesh_group_t));
1343
1344                 if (addr_len == 4)
1345                         sscanf(str, "%04hx", &grp->grp_addr);
1346                 else {
1347                         _bt_mesh_util_convert_string_to_hex(str,
1348                                 32, grp->label_uuid, 16);
1349                         grp->grp_addr = addr;
1350                 }
1351
1352                 groups = g_slist_append(groups, grp);
1353         }
1354
1355         return groups;
1356 }
1357
1358 bool _bt_mesh_conf_insert_group_info(_bt_mesh_cdb_t *cfg,
1359                 _bt_mesh_group_t *grp)
1360 {
1361         json_object *jgroup, *jgroups, *jval;
1362         char buf[16];
1363
1364         if (!cfg || !cfg->jcfg)
1365                 return false;
1366
1367         if (!json_object_object_get_ex(cfg->jcfg, "groups", &jgroups)) {
1368                 BT_INFO("Mesh: Group JSON object is not present: Create");
1369                 jgroups = json_object_new_array();
1370                 if (!jgroups)
1371                         return false;
1372
1373                 json_object_object_add(cfg->jcfg, "groups", jgroups);
1374         }
1375
1376         jgroup = json_object_new_object();
1377         if (!jgroup)
1378                 return false;
1379
1380         snprintf(buf, 11, "Group_%4.4x", grp->grp_addr);
1381         jval = json_object_new_string(buf);
1382         json_object_object_add(jgroup, "name", jval);
1383
1384         if (MESH_IS_VIRTUAL(grp->grp_addr)) {
1385                 if (!__mesh_add_u8_16(jgroup, "address", grp->label_uuid))
1386                         goto fail;
1387         } else {
1388                 if (!__mesh_write_uint16_hex(jgroup, "address", grp->grp_addr))
1389                         goto fail;
1390         }
1391
1392         json_object_array_add(jgroups, jgroup);
1393
1394         return __bt_mesh_save_configruation_file(cfg);
1395
1396 fail:
1397         json_object_put(jgroup);
1398         return false;
1399 }
1400
1401 bool _bt_mesh_conf_delete_group_entry(_bt_mesh_cdb_t *cfg, uint16_t addr)
1402 {
1403         if (!cfg || !cfg->jcfg)
1404                 return false;
1405
1406         return __mesh_delete_group(cfg, cfg->jcfg, "groups", addr);
1407 }
1408
1409 static json_object *__mesh_get_model_by_modelid(json_object *jelement,
1410                 uint32_t model_id)
1411 {
1412         int sz;
1413         json_object *jval = NULL;
1414         json_object *jmodelarray = NULL;
1415
1416         /* Get Model array object inside the selected element */
1417         json_object_object_get_ex(jelement, "models", &jmodelarray);
1418
1419         if (!jmodelarray || json_object_get_type(jmodelarray) != json_type_array) {
1420                 BT_ERR("Mesh: Could not get Model Array");
1421                 return NULL;
1422         }
1423
1424         /* Get specific model object inside model array */
1425         sz = json_object_array_length(jmodelarray);
1426         BT_INFO("Mesh: Total number of Models in Element is [%d]", sz);
1427
1428         for (int i = 0; i < sz; ++i) {
1429                 uint16_t mod_id;
1430                 const char *str;
1431                 json_object *jentry = NULL;
1432
1433                 BT_INFO("Mesh: Model [%d]", i);
1434                 jentry = json_object_array_get_idx(jmodelarray, i);
1435
1436                 if (!json_object_object_get_ex(jentry, "modelId", &jval)) {
1437                         BT_ERR("Mesh: Failed to read Model in index [%d]", i);
1438                         return NULL;
1439                 }
1440
1441                 str = json_object_get_string(jval);
1442                 if (sscanf(str, "%04hx", &mod_id) != 1) {
1443                         BT_INFO("Mesh: Failed to read Model ID from Model entry [%s]", str);
1444                         return NULL;
1445                 }
1446
1447                 BT_INFO("Mesh: Model string [%s] Model ID [0x%4.4x]", str, mod_id);
1448                 if ((uint16_t)model_id == mod_id) {
1449                         BT_INFO("Mesh: Found required model");
1450                         return jentry;
1451                 }
1452         }
1453         /* TODO: Need to handle vendor models */
1454
1455         return NULL;
1456 }
1457
1458 static json_object *__mesh_get_model_by_unicast_modelid(_bt_mesh_cdb_t *cfg,
1459                 uint16_t unicast, int element_index, uint32_t model_id)
1460 {
1461         json_object *jnode = NULL;
1462         json_object *jarray = NULL;
1463         json_object *jelement = NULL;
1464         json_object *jmodel = NULL;
1465
1466         if (!cfg || !cfg->jcfg)
1467                 return NULL;
1468
1469         /* Get specific node by unicast */
1470         jnode = __mesh_get_node_by_unicast(cfg, unicast);
1471         if (!jnode)
1472                 return NULL;
1473
1474         /* Get element array object inside node */
1475         json_object_object_get_ex(jnode, "elements", &jarray);
1476         if (!jarray || json_object_get_type(jarray) != json_type_array) {
1477                 BT_ERR("Mesh:could not get element array");
1478                 return NULL;
1479         }
1480
1481         /* Get specific element by index */
1482         jelement = __mesh_get_key_object(jarray, element_index);
1483         if (!jelement) {
1484                 BT_ERR("Mesh: Could not find element");
1485                 return NULL;
1486         }
1487
1488         /* Get specific model by model-id */
1489         jmodel = __mesh_get_model_by_modelid(jelement, model_id);
1490         if (!jmodel)
1491                 return NULL;
1492
1493         return jmodel;
1494 }
1495
1496 static json_object *__mesh_get_sub_group(json_object *jgroups, uint16_t group_addr)
1497 {
1498         json_object *jval = NULL;
1499         int sz = json_object_array_length(jgroups);
1500         BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
1501
1502         for (int i = 0; i < sz; ++i) {
1503                 uint16_t group_address;
1504                 const char *str;
1505                 json_object *jentry = NULL;
1506
1507                 BT_INFO("Mesh: sub-addr [%d]", i);
1508                 jentry = json_object_array_get_idx(jgroups, i);
1509
1510                 if (!json_object_object_get_ex(jentry, "sub-addr", &jval)) {
1511                         BT_ERR("Mesh: Failed to read sub-addr in index [%d]", i);
1512                         return NULL;
1513                 }
1514
1515                 str = json_object_get_string(jval);
1516                 if (sscanf(str, "%04hx", &group_address) != 1) {
1517                         BT_INFO("Mesh: Failed to read group address from sub-addr entry [%s]", str);
1518                         return NULL;
1519                 }
1520
1521                 BT_INFO("Mesh: group addr string [%s] sub-addr [0x%4.4x]", str, group_address);
1522                 if (group_addr == group_address) {
1523                         BT_INFO("Mesh: Found required sub-addr");
1524                         return jentry;
1525                 }
1526         }
1527         return NULL;
1528 }
1529
1530 static bool __mesh_del_sub_group(json_object *jgroups, uint16_t group_addr)
1531 {
1532         json_object *jval = NULL;
1533         int i = 0;
1534         int sz = json_object_array_length(jgroups);
1535         BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
1536
1537         for (i = 0; i < sz; ++i) {
1538                 uint16_t group_address;
1539                 const char *str;
1540                 json_object *jentry = NULL;
1541
1542                 BT_INFO("Mesh: sub-addr [%d]", i);
1543                 jentry = json_object_array_get_idx(jgroups, i);
1544
1545                 if (!json_object_object_get_ex(jentry, "sub-addr", &jval)) {
1546                         BT_ERR("Mesh: Failed to read sub-addr in index [%d]", i);
1547                         return false;
1548                 }
1549
1550                 str = json_object_get_string(jval);
1551                 if (sscanf(str, "%04hx", &group_address) != 1) {
1552                         BT_INFO("Mesh: Failed to read group address from sub-addr entry [%s]", str);
1553                         return NULL;
1554                 }
1555
1556                 BT_INFO("Mesh: group addr string [%s] sub-addr [0x%4.4x]", str, group_address);
1557                 if (group_addr == group_address) {
1558                         BT_INFO("Mesh: Found required sub-addr");
1559                         break;
1560                 }
1561         }
1562
1563         if (i == sz)
1564                 return true;
1565
1566         json_object_array_del_idx(jgroups, i, 1);
1567
1568         return true;
1569 }
1570
1571 bool _bt_mesh_conf_add_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
1572                         int element_index, uint32_t model_id, uint16_t group_addr)
1573 {
1574         json_object *jmodel = NULL;
1575         json_object *jgroups = NULL;
1576         json_object *jgroup = NULL;
1577
1578         BT_INFO("Mesh: Set model config informations in the node [0x%2.2x] \
1579                         element index [%d] model [0x%4.4x] group addr [0x%2.2x]",
1580                         unicast, element_index, model_id, group_addr);
1581
1582         if (!cfg || !cfg->jcfg)
1583                 return false;
1584
1585         /* Get model to be updated */
1586         jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
1587                                                 element_index, model_id);
1588         if (!jmodel)
1589                 return false;
1590
1591         /* Find existing sub-addr group */
1592         if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups)) {
1593                 BT_INFO("Mesh: Sub-addr group JSON object is not present: Create");
1594                 jgroups = json_object_new_array();
1595                 if (!jgroups)
1596                         return false;
1597
1598                 json_object_object_add(jmodel, "sub-addr", jgroups);
1599         }
1600
1601         jgroup = __mesh_get_sub_group(jgroups, group_addr);
1602         if (jgroup) {
1603                 BT_DBG("sub-addr already present in list");
1604                 return true;
1605         }
1606
1607         /* Write group address */
1608         jgroup = json_object_new_object();
1609         if (!jgroup)
1610                 return false;
1611
1612         if (!__mesh_write_uint16_hex(jgroup, "sub-addr", group_addr))
1613                 return false;
1614
1615         json_object_array_add(jgroups, jgroup);
1616
1617         /* Save */
1618         return  __bt_mesh_save_configruation_file(cfg);
1619 }
1620
1621 bool _bt_mesh_conf_delete_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
1622                         int element_index, uint32_t model_id, uint16_t group_addr)
1623 {
1624         json_object *jmodel = NULL;
1625         json_object *jgroups = NULL;
1626
1627         BT_INFO("Mesh: Set model config informations in the node [0x%2.2x] \
1628                         element index [%d] model [0x%4.4x] group addr [0x%2.2x]",
1629                         unicast, element_index, model_id, group_addr);
1630
1631         if (!cfg || !cfg->jcfg)
1632                 return false;
1633
1634         /* Get model to be updated */
1635         jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
1636                                                 element_index, model_id);
1637         if (!jmodel)
1638                 return false;
1639
1640         /* Delete group address */
1641         if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups))
1642                 return false;
1643
1644         if (!__mesh_del_sub_group(jgroups, group_addr))
1645                 return false;
1646
1647         /* Save */
1648         return  __bt_mesh_save_configruation_file(cfg);
1649 }
1650
1651 bool _bt_mesh_conf_delete_all_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
1652                                                 int element_index, uint32_t model_id)
1653 {
1654         json_object *jmodel = NULL;
1655         json_object *jgroups = NULL;
1656         int sz;
1657
1658         BT_INFO("Mesh: Delete all model sub informations in the node [0x%2.2x] \
1659                                         element index [%d] model [0x%4.4x]",
1660                                         unicast, element_index, model_id);
1661
1662         if (!cfg || !cfg->jcfg)
1663                 return false;
1664
1665         /* Get model to be updated */
1666         jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
1667                                                 element_index, model_id);
1668         if (!jmodel)
1669                 return false;
1670
1671         /* Delete all group address */
1672         if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups))
1673                 return false;
1674
1675         sz = json_object_array_length(jgroups);
1676         BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
1677
1678         for (int i = sz - 1; i >= 0 ; --i)
1679                 json_object_array_del_idx(jgroups, i, 1);
1680
1681         /* Save */
1682         return  __bt_mesh_save_configruation_file(cfg);
1683 }
1684
1685 bool _bt_mesh_conf_overwrite_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
1686                         int element_index, uint32_t model_id, uint16_t group_addr)
1687 {
1688         json_object *jmodel = NULL;
1689         json_object *jgroups = NULL;
1690         json_object *jgroup = NULL;
1691         int sz;
1692
1693         BT_INFO("Mesh: Set model config informations in the node [0x%2.2x] \
1694                         element index [%d] model [0x%4.4x] group addr [0x%2.2x]",
1695                         unicast, element_index, model_id, group_addr);
1696
1697         if (!cfg || !cfg->jcfg)
1698                 return false;
1699
1700         /* Get model to be updated */
1701         jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
1702                                                 element_index, model_id);
1703         if (!jmodel)
1704                 return false;
1705
1706         /* Find group array */
1707         if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups)) {
1708                 BT_INFO("Mesh: Sub-addr group JSON object is not present: Create");
1709                 jgroups = json_object_new_array();
1710                 if (!jgroups)
1711                         return false;
1712
1713                 json_object_object_add(jmodel, "sub-addr", jgroups);
1714         } else {
1715                 /* Found group array: Delete all group address */
1716                 sz = json_object_array_length(jgroups);
1717                 BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
1718
1719                 for (int i = sz - 1; i >= 0 ; --i) {
1720                         BT_INFO("Mesh: Delete sub-addr entry [%d]", i);
1721                         json_object_array_del_idx(jgroups, i, 1);
1722                 }
1723         }
1724
1725         /* Over-write new group address */
1726         jgroup = json_object_new_object();
1727         if (!jgroup)
1728                 return false;
1729
1730         if (!__mesh_write_uint16_hex(jgroup, "sub-addr", group_addr))
1731                 return false;
1732
1733         json_object_array_add(jgroups, jgroup);
1734
1735         /* Save */
1736         return  __bt_mesh_save_configruation_file(cfg);
1737 }
1738
1739 bool _bt_mesh_is_group_subscribed(_bt_mesh_cdb_t *cfg, uint16_t group_addr)
1740 {
1741         json_object *jnodes;
1742         int i, sz = 0;
1743
1744         if (!cfg || !cfg->jcfg)
1745                 return false;
1746
1747         json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes);
1748         if (!jnodes || json_object_get_type(jnodes) != json_type_array)
1749                 return false;
1750
1751         sz = json_object_array_length(jnodes);
1752
1753         for (i = 0; i < sz; ++i) {
1754                 json_object *jnode, *jarray;
1755                 int ele_cnt;
1756                 int j;
1757
1758                 jnode = json_object_array_get_idx(jnodes, i);
1759                 if (!jnode)
1760                         continue;
1761
1762                 if (!json_object_object_get_ex(jnode, "elements", &jarray))
1763                         return false;
1764
1765                 if (!jarray || json_object_get_type(jarray) != json_type_array)
1766                         return false;
1767
1768                 ele_cnt = json_object_array_length(jarray);
1769
1770                 for (j = 0; j < ele_cnt; ++j) {
1771                         json_object *jentry, *jval, *jmods;
1772                         int32_t index;
1773                         int k, mod_cnt;
1774
1775                         jentry = json_object_array_get_idx(jarray, j);
1776                         if (!json_object_object_get_ex(jentry, "index", &jval))
1777                                 return false;
1778
1779                         index = json_object_get_int(jval);
1780                         if (index > 0xff)
1781                                 return false;
1782
1783                         if (!json_object_object_get_ex(jentry, "models", &jmods))
1784                                 continue;
1785
1786                         mod_cnt = json_object_array_length(jmods);
1787                         BT_INFO("Mesh: Total Model count in element Index [%d] is [%d]",
1788                                 index, mod_cnt);
1789
1790                         for (k = 0; k < mod_cnt; ++k) {
1791                                 json_object *jmod;
1792                                 json_object *jgroups, *jgroup;
1793
1794                                 jmod = json_object_array_get_idx(jmods, k);
1795
1796                                 if (!json_object_object_get_ex(jmod, "sub-addr", &jgroups))
1797                                         continue;
1798
1799                                 /* Find existing sub-addr group */
1800                                 jgroup = __mesh_get_sub_group(jgroups, group_addr);
1801                                 if (jgroup) {
1802                                         BT_DBG("sub-addr present in list");
1803                                         return true;
1804                                 }
1805                         }
1806                 }
1807         }
1808         return false;
1809 }
1810
1811 bool _bt_mesh_conf_set_network_friendly_name(_bt_mesh_cdb_t *cfg,
1812                 const char *network_name)
1813 {
1814         json_object *jcfg;
1815
1816         if (!cfg)
1817                 return false;
1818         jcfg = cfg->jcfg;
1819
1820         if (!jcfg)
1821                 return false;
1822
1823         json_object_object_del(jcfg, "Network_Name");
1824         __mesh_add_string(jcfg, "Network_Name", network_name);
1825
1826
1827         BT_INFO("Mesh: CDB: Network New Name [%s]", network_name);
1828         return __bt_mesh_save_configruation_file(cfg);
1829 }
1830
1831 const char * _bt_mesh_conf_get_network_friendly_name(_bt_mesh_cdb_t *cfg)
1832 {
1833         json_object *jcfg;
1834         json_object *jobj = NULL;
1835         const char *str;
1836
1837         if (!cfg)
1838                 return NULL;
1839         jcfg = cfg->jcfg;
1840
1841         if (!jcfg)
1842                 return NULL;
1843
1844         /* Get Network Name */
1845         if (!json_object_object_get_ex(jcfg, "Network_Name", &jobj))
1846                 return NULL;
1847
1848         str = json_object_get_string(jobj);
1849         if (!str)
1850                 return NULL;
1851
1852         BT_INFO("Mesh: CDB: Network Name [%s]", str);
1853         return str;
1854 }
1855
1856 static bool __mesh_load_composition(_bt_mesh_cdb_t *cfg,
1857                 json_object *jnode, uint16_t unicast)
1858 {
1859         json_object *jarray;
1860         int i, ele_cnt;
1861
1862         if (!json_object_object_get_ex(jnode, "elements", &jarray))
1863                 return false;
1864
1865         if (json_object_get_type(jarray) != json_type_array)
1866                 return false;
1867
1868         ele_cnt = json_object_array_length(jarray);
1869
1870         for (i = 0; i < ele_cnt; ++i) {
1871                 json_object *jentry, *jval, *jmods;
1872                 int32_t index;
1873                 int k, mod_cnt;
1874
1875                 jentry = json_object_array_get_idx(jarray, i);
1876                 if (!json_object_object_get_ex(jentry, "index", &jval))
1877                         return false;
1878
1879                 index = json_object_get_int(jval);
1880                 if (index > 0xff)
1881                         return false;
1882
1883                 if (!json_object_object_get_ex(jentry, "models", &jmods))
1884                         return false;
1885
1886                 mod_cnt = json_object_array_length(jmods);
1887                 BT_INFO("Mesh: Total Model count in element Index [%d] is [%d]",
1888                         index, mod_cnt);
1889
1890                 for (k = 0; k < mod_cnt; ++k) {
1891                         json_object *jmod, *jid;
1892                         uint32_t mod_id, len;
1893                         const char *str;
1894
1895                         jmod = json_object_array_get_idx(jmods, k);
1896                         if (!json_object_object_get_ex(jmod, "modelId", &jid))
1897                                 return false;
1898
1899                         str = json_object_get_string(jid);
1900                         len = strlen(str);
1901
1902                         if (len != 4 && len != 8)
1903                                 return false;
1904
1905                         if ((len == 4) && (sscanf(str, "%04x", &mod_id) != 1))
1906                                 return false;
1907
1908                         if ((len == 8) && (sscanf(str, "%08x", &mod_id) != 1))
1909                                 return false;
1910
1911                         _bt_mesh_node_set_model(cfg->uuid,
1912                                         unicast, index, mod_id, len == 8);
1913                 }
1914         }
1915
1916         return true;
1917 }
1918
1919 bool _bt_mesh_conf_set_node_comp_data(_bt_mesh_cdb_t *cfg,
1920                 uint16_t unicast, uint8_t *data, uint16_t len)
1921 {
1922         uint16_t features;
1923         int sz, i = 0;
1924         json_object *jnode, *jobj, *jelements;
1925         uint16_t crpl;
1926
1927         if (!cfg || !cfg->jcfg)
1928                 return false;
1929
1930         jnode = __mesh_get_node_by_unicast(cfg, unicast);
1931         if (!jnode)
1932                 return false;
1933
1934         /* skip page -- We only support Page Zero */
1935         data++;
1936         len--;
1937
1938         /* If "crpl" property is present, composition is already recorded */
1939         if (json_object_object_get_ex(jnode, "crpl", &jobj))
1940                 return true;
1941
1942         if (!__mesh_write_uint16_hex(jnode, "cid", l_get_le16(&data[0])))
1943                 return false;
1944
1945         if (!__mesh_write_uint16_hex(jnode, "pid", l_get_le16(&data[2])))
1946                 return false;
1947
1948         if (!__mesh_write_uint16_hex(jnode, "vid", l_get_le16(&data[4])))
1949                 return false;
1950
1951         crpl = l_get_le16(&data[6]);
1952
1953         features = l_get_le16(&data[8]);
1954         data += 10;
1955         len -= 10;
1956
1957         jobj = json_object_object_get(jnode, "features");
1958         if (!jobj) {
1959                 jobj = json_object_new_object();
1960                 json_object_object_add(jnode, "features", jobj);
1961         }
1962
1963         if ((features & MESH_FEATURE_RELAY))
1964                 __mesh_write_int(jobj, "relay", 1);
1965         else
1966                 __mesh_write_int(jobj, "relay", 0);
1967
1968         if ((features & MESH_FEATURE_FRIEND))
1969                 __mesh_write_int(jobj, "friend", 1);
1970         else
1971                 __mesh_write_int(jobj, "friend", 0);
1972
1973         if ((features & MESH_FEATURE_PROXY))
1974                 __mesh_write_int(jobj, "proxy", 1);
1975         else
1976                 __mesh_write_int(jobj, "proxy", 0);
1977
1978         if ((features & MESH_FEATURE_LPN))
1979                 __mesh_write_int(jobj, "lowPower", 1);
1980         else
1981                 __mesh_write_int(jobj, "lowPower", 0);
1982
1983         jelements = json_object_object_get(jnode, "elements");
1984         if (!jelements)
1985                 return false;
1986
1987         sz = json_object_array_length(jelements);
1988
1989         while (len) {
1990                 json_object *jentry, *jmods;
1991                 uint32_t mod_id;
1992                 uint8_t m, v;
1993
1994                 /* Mismatch in the element count */
1995                 if (i >= sz)
1996                         return false;
1997
1998                 jentry = json_object_array_get_idx(jelements, i);
1999
2000                 __mesh_write_int(jentry, "index", i);
2001
2002                 if (!__mesh_write_uint16_hex(jentry, "location", l_get_le16(data)))
2003                         return false;
2004
2005                 data += 2;
2006                 len -= 2;
2007
2008                 m = *data++;
2009                 v = *data++;
2010                 len -= 2;
2011
2012                 jmods = json_object_object_get(jentry, "models");
2013                 if (!jmods) {
2014                         /* For backwards compatibility */
2015                         jmods = json_object_new_array();
2016                         json_object_object_add(jentry, "models", jmods);
2017                 }
2018
2019                 while (len >= 2 && m--) {
2020                         mod_id = l_get_le16(data);
2021
2022                         jobj = __mesh_init_model(mod_id);
2023                         if (!jobj)
2024                                 goto fail;
2025
2026                         json_object_array_add(jmods, jobj);
2027                         data += 2;
2028                         len -= 2;
2029                 }
2030
2031                 while (len >= 4 && v--) {
2032                         jobj = json_object_new_object();
2033                         mod_id = l_get_le16(data + 2);
2034                         mod_id = l_get_le16(data) << 16 | mod_id;
2035
2036                         jobj = __mesh_init_vendor_model(mod_id);
2037                         if (!jobj)
2038                                 goto fail;
2039
2040                         json_object_array_add(jmods, jobj);
2041
2042                         data += 4;
2043                         len -= 4;
2044                 }
2045
2046                 i++;
2047         }
2048
2049         /* CRPL is written last. Will be used to check composition's presence */
2050         if (!__mesh_write_uint16_hex(jnode, "crpl", crpl))
2051                 goto fail;
2052
2053         /* Initiate remote's composition from storage */
2054         if (!__mesh_load_composition(cfg, jnode, unicast))
2055                 goto fail;
2056
2057         return  __bt_mesh_save_configruation_file(cfg);
2058
2059 fail:
2060         /* Reset elements array */
2061         json_object_object_del(jnode, "elements");
2062         __mesh_init_elements(sz);
2063
2064         return false;
2065 }
2066
2067 _bt_mesh_cdb_t* _bt_mesh_conf_load(const char *file_name,
2068                 const char *token)
2069 {
2070         char token_str[17];
2071         int fd;
2072         char *str;
2073         struct stat st;
2074         ssize_t sz;
2075         json_object *jcfg;
2076         _bt_mesh_cdb_t *cfg;
2077
2078         fd = open(file_name, O_RDONLY);
2079         if (fd < 0) {
2080                 BT_ERR("Mesh: Could not open file [%s]",
2081                                 file_name);
2082                 return NULL;
2083         }
2084
2085         if (fstat(fd, &st) == -1) {
2086                 close(fd);
2087                 BT_ERR("Mesh: Could not stat file [%s]",
2088                                 file_name);
2089                 return NULL;
2090         }
2091
2092         str = (char *) g_malloc0(st.st_size + 1);
2093         if (!str) {
2094                 close(fd);
2095                 BT_ERR("Mesh: Could not stat file [%s]",
2096                                 file_name);
2097                 return NULL;
2098         }
2099
2100         sz = read(fd, str, st.st_size);
2101         if (sz != st.st_size) {
2102                 BT_ERR("Mesh: Failed to read configuration file [%s]", file_name);
2103                 close(fd);
2104                 g_free(str);
2105                 return NULL;
2106         }
2107
2108         jcfg = json_tokener_parse(str);
2109
2110         close(fd);
2111         g_free(str);
2112
2113         if (!jcfg)
2114                 return NULL;
2115         cfg = g_malloc0(sizeof(_bt_mesh_cdb_t));
2116
2117         cfg->jcfg = jcfg;
2118         cfg->cfg_fname = g_strdup(file_name);
2119
2120         if (!__mesh_get_uuid(jcfg, cfg->uuid)) {
2121                 BT_ERR("Mesh: Configuration file missing UUID");
2122                 goto fail;
2123         }
2124
2125         if (!__mesh_get_token(jcfg, cfg->token)) {
2126                 BT_ERR("Mesh: Configuration file missing token");
2127                 goto fail;
2128         }
2129
2130         _bt_mesh_util_convert_hex_to_string(cfg->token, 8, token_str, 17);
2131
2132         /* Match CDB file tken with user's token */
2133         if (g_strcmp0(token_str, token)) {
2134                 BT_INFO("Mesh: Token did not match! File token [%s] requested token [%s]",
2135                                 token_str, token);
2136                 goto fail;
2137         }
2138
2139         BT_INFO("Mesh: Token found");
2140         /* TODO: Load keys and remotes */
2141         return cfg;
2142 fail:
2143         _bt_mesh_conf_free(cfg);
2144         return NULL;
2145 }
2146
2147 bool _bt_mesh_conf_load_all_nodes(_bt_mesh_cdb_t *cfg)
2148 {
2149         json_object *jnodes;
2150         int i, sz, node_count = 0;
2151
2152         json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes);
2153         if (!jnodes || json_object_get_type(jnodes) != json_type_array)
2154                 return false;
2155
2156         sz = json_object_array_length(jnodes);
2157
2158         for (i = 0; i < sz; ++i) {
2159                 json_object *jnode, *jval, *jarray;
2160                 uint8_t uuid[16];
2161                 uint16_t unicast, key_idx;
2162                 const char *str;
2163                 int ele_cnt, key_cnt;
2164                 int j;
2165
2166                 jnode = json_object_array_get_idx(jnodes, i);
2167                 if (!jnode)
2168                         continue;
2169
2170                 if (!json_object_object_get_ex(jnode, "uuid", &jval))
2171                         continue;
2172
2173                 str = json_object_get_string(jval);
2174                 if (strlen(str) != 32)
2175                         continue;
2176
2177                 _bt_mesh_util_convert_string_to_hex(str, 32, uuid, 16);
2178
2179                 if (!json_object_object_get_ex(jnode, "unicastAddress", &jval))
2180                         continue;
2181
2182                 str = json_object_get_string(jval);
2183                 if (sscanf(str, "%04hx", &unicast) != 1)
2184                         continue;
2185
2186                 json_object_object_get_ex(jnode, "elements", &jarray);
2187                 if (!jarray || json_object_get_type(jarray) != json_type_array)
2188                         continue;
2189
2190                 ele_cnt = json_object_array_length(jarray);
2191
2192                 if (ele_cnt > MESH_MAX_ELE_COUNT)
2193                         continue;
2194
2195                 json_object_object_get_ex(jnode, "netKeys", &jarray);
2196                 if (!jarray || json_object_get_type(jarray) != json_type_array)
2197                         continue;
2198
2199                 key_cnt = json_object_array_length(jarray);
2200                 if (key_cnt < 0)
2201                         continue;
2202
2203                 key_idx = __mesh_node_parse_key(jarray, 0);
2204                 if (key_idx == MESH_KEY_IDX_INVALID)
2205                         continue;
2206
2207                 _bt_mesh_node_add_node(cfg->uuid, (const uint8_t *)uuid, unicast, ele_cnt,
2208                                 key_idx);
2209                 for (j = 1; j < key_cnt; j++) {
2210                         key_idx = __mesh_node_parse_key(jarray, j);
2211
2212                         if (key_idx != MESH_KEY_IDX_INVALID)
2213                                 _bt_mesh_node_add_net_key(cfg->uuid, unicast, key_idx);
2214                 }
2215
2216                 json_object_object_get_ex(jnode, "appKeys", &jarray);
2217                 if (!jarray || json_object_get_type(jarray) != json_type_array)
2218                         continue;
2219
2220                 key_cnt = json_object_array_length(jarray);
2221                 for (j = 0; j < key_cnt; j++) {
2222                         key_idx = __mesh_node_parse_key(jarray, j);
2223
2224                         if (key_idx != MESH_KEY_IDX_INVALID)
2225                                 _bt_mesh_node_add_app_key(cfg->uuid, unicast, key_idx);
2226                 }
2227
2228                 __mesh_load_composition(cfg, jnode, unicast);
2229
2230                 node_count++;
2231
2232                 /* TODO: Add the rest of the configuration */
2233         }
2234
2235         if (node_count != sz)
2236                 BT_ERR("Mesh: CDB: The remote node configuration load is incomplete!");
2237
2238         return true;
2239 }
2240
2241 bool _bt_mesh_conf_load_all_keys(_bt_mesh_cdb_t* cfg)
2242 {
2243         json_object *jarray, *jentry;
2244         int net_idx, app_idx;
2245         int i, key_cnt;
2246         json_object *jobj = cfg->jcfg;
2247
2248         json_object_object_get_ex(jobj, "netKeys", &jarray);
2249         if (!jarray || json_object_get_type(jarray) != json_type_array)
2250                 return false;
2251
2252         key_cnt = json_object_array_length(jarray);
2253         if (key_cnt < 0)
2254                 return false;
2255
2256         for (i = 0; i < key_cnt; ++i) {
2257                 int phase;
2258
2259                 jentry = json_object_array_get_idx(jarray, i);
2260
2261                 if (!__mesh_get_int(jentry, "index", &net_idx))
2262                         return false;
2263
2264                 _bt_mesh_keys_add_net_key(cfg->uuid, (uint16_t) net_idx);
2265
2266                 if (!__mesh_get_int(jentry, "phase", &phase))
2267                         return false;
2268
2269                 _bt_mesh_keys_set_net_key_phase(cfg, net_idx, (uint8_t) phase, false);
2270         }
2271
2272         json_object_object_get_ex(jobj, "appKeys", &jarray);
2273         if (!jarray || json_object_get_type(jarray) != json_type_array)
2274                 return false;
2275
2276         key_cnt = json_object_array_length(jarray);
2277         if (key_cnt < 0)
2278                 return false;
2279
2280         for (i = 0; i < key_cnt; ++i) {
2281
2282                 jentry = json_object_array_get_idx(jarray, i);
2283                 if (!__mesh_get_int(jentry, "boundNetKey", &net_idx))
2284                         return false;
2285
2286                 if (!__mesh_get_int(jentry, "index", &app_idx))
2287                         return false;
2288
2289                 _bt_mesh_keys_add_app_key(cfg->uuid, (uint16_t) net_idx, (uint16_t) app_idx);
2290         }
2291
2292         return true;
2293 }