Mesh: Fix & Refactor Mesh Model Subscription codes
[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
340         json_object_object_get_ex(jcfg, "nodes", &jarray);
341         if (!jarray || json_object_get_type(jarray) != json_type_array)
342                 return NULL;
343
344         sz = json_object_array_length(jarray);
345
346         for (i = 0; i < sz; ++i) {
347                 json_object *jentry, *jval;
348                 const char *str;
349
350                 jentry = json_object_array_get_idx(jarray, i);
351                 if (!json_object_object_get_ex(jentry, "uuid", &jval))
352                         return NULL;
353
354                 str = json_object_get_string(jval);
355                 if (strlen(str) != 32)
356                         continue;
357
358                 if (!g_strcmp0(buf, str))
359                         return jentry;
360         }
361
362         return NULL;
363 }
364
365 static json_object *__mesh_get_key_object(json_object *jarray,
366                 uint16_t idx)
367 {
368         int i, sz = json_object_array_length(jarray);
369
370         for (i = 0; i < sz; ++i) {
371                 json_object *jentry;
372                 int jidx;
373
374                 jentry = json_object_array_get_idx(jarray, i);
375                 if (!__mesh_get_int(jentry, "index", &jidx))
376                         return NULL;
377
378                 if (jidx == idx)
379                         return jentry;
380         }
381
382         return NULL;
383 }
384
385 static bool __mesh_add_string(json_object *jobj,
386                 const char *desc, const char *str)
387 {
388         json_object *jstring = json_object_new_string(str);
389
390         if (!jstring)
391                 return false;
392
393         json_object_object_add(jobj, desc, jstring);
394         return true;
395 }
396
397 static bool __mesh_get_token(json_object *jobj, uint8_t token[8])
398 {
399         json_object *jval;
400         const char *str;
401
402         if (!json_object_object_get_ex(jobj, "token", &jval))
403                 return false;
404
405         str = json_object_get_string(jval);
406         if (!_bt_mesh_util_convert_string_to_hex(str, strlen(str), token, 8))
407                 return false;
408
409         return true;
410 }
411
412 static bool __mesh_get_uuid(json_object *jobj, uint8_t uuid[16])
413 {
414         json_object *jval;
415         const char *str;
416
417         if (!json_object_object_get_ex(jobj, "uuid", &jval))
418                 return false;
419
420         str = json_object_get_string(jval);
421         if (!_bt_mesh_util_convert_string_to_hex(str, strlen(str), uuid, 16))
422                 return false;
423
424         return true;
425 }
426
427 static bool __mesh_add_u8_8(json_object *jobj,
428                 const char *desc, const uint8_t value[8])
429 {
430         json_object *jstring;
431         char buf[17];
432
433         _bt_mesh_util_convert_hex_to_string((uint8_t *) value, 8, buf, 17);
434         jstring = json_object_new_string(buf);
435         if (!jstring)
436                 return false;
437
438         json_object_object_add(jobj, desc, jstring);
439         return true;
440 }
441
442 static bool __mesh_add_u8_16(json_object *jobj,
443                 const char *desc, const uint8_t value[16])
444 {
445         json_object *jstring;
446         char buf[33];
447
448         _bt_mesh_util_convert_hex_to_string((uint8_t *) value, 16, buf, 33);
449         jstring = json_object_new_string(buf);
450         if (!jstring)
451                 return false;
452
453         json_object_object_add(jobj, desc, jstring);
454         return true;
455 }
456
457 void _bt_mesh_conf_free(_bt_mesh_cdb_t *cfg)
458 {
459         g_free(cfg->cfg_fname);
460         g_free(cfg->app_cred);
461         json_object_put(cfg->jcfg);
462         g_free(cfg);
463 }
464
465 bool _bt_mesh_conf_parse_data(void *cfg,  int k)
466 {
467         _bt_mesh_cdb_t *conf = (_bt_mesh_cdb_t*) cfg;
468         if (!conf)
469                 return false;
470         return true;
471 }
472
473 static bool __mesh_jarray_group_delete(json_object *jarray, uint16_t group_addr)
474 {
475         int i, sz = json_object_array_length(jarray);
476         json_object *jval;
477         char buf[15];
478
479         for (i = 0; i < sz; ++i) {
480                 json_object *jentry;
481                 uint16_t addr;
482                 const char *str;
483
484                 jentry = json_object_array_get_idx(jarray, i);
485                 if (!json_object_object_get_ex(jentry, "name",
486                                         &jval))
487                         continue;
488
489                 str = json_object_get_string(jval);
490                 memcpy(buf, str + 6, 5);
491                 BT_INFO("Mesh: JSON Group string:[%s]", buf);
492                 if (sscanf(buf, "%04hx", &addr) != 1)
493                         continue;
494                 BT_INFO("Mesh: JSON Group in Hex [0x%2.2x]", addr);
495
496                 if (group_addr == addr)
497                         break;
498
499         }
500         if (i == sz) {
501                 BT_INFO("Mesh: Failed to remove group");
502                 return false;
503         }
504
505         json_object_array_del_idx(jarray, i, 1);
506         return true;
507 }
508
509 static void __mesh_jarray_key_del(json_object *jarray, int16_t idx)
510 {
511         int i, sz = json_object_array_length(jarray);
512
513         for (i = 0; i < sz; ++i) {
514                 json_object *jentry;
515                 int val;
516
517                 jentry = json_object_array_get_idx(jarray, i);
518
519                 if (!__mesh_get_int(jentry, "index", &val))
520                         continue;
521
522                 if (val == idx) {
523                         json_object_array_del_idx(jarray, i, 1);
524                         return;
525                 }
526         }
527 }
528
529 static bool __mesh_delete_group(_bt_mesh_cdb_t *cfg,
530                 json_object *jobj, const char *desc, uint16_t addr)
531 {
532         json_object *jarray;
533
534         if (!json_object_object_get_ex(jobj, desc, &jarray))
535                 return false;
536
537         if (!__mesh_jarray_group_delete(jarray, addr))
538                 return false;
539
540         return __bt_mesh_save_configruation_file(cfg);
541 }
542
543 static bool __mesh_delete_key(_bt_mesh_cdb_t *cfg,
544                 json_object *jobj, const char *desc, uint16_t idx)
545 {
546         json_object *jarray;
547
548         if (!json_object_object_get_ex(jobj, desc, &jarray))
549                 return true;
550
551         __mesh_jarray_key_del(jarray, idx);
552
553         return __bt_mesh_save_configruation_file(cfg);
554 }
555
556 bool _bt_mesh_conf_set_phase_network_key(_bt_mesh_cdb_t *cfg,
557                 uint16_t net_idx, uint8_t phase)
558 {
559         json_object *jval, *jarray, *jkey;
560
561         if (!cfg || !cfg->jcfg)
562                 return false;
563
564         json_object_object_get_ex(cfg->jcfg, "netKeys", &jarray);
565         if (!jarray || json_object_get_type(jarray) != json_type_array)
566                 return false;
567
568         jkey = __mesh_get_key_object(jarray, net_idx);
569         if (!jkey)
570                 return false;
571
572         jval = json_object_new_int(phase);
573         if (!jval)
574                 return false;
575
576         json_object_object_add(jkey, "phase", jval);
577
578         return __bt_mesh_save_configruation_file(cfg);
579 }
580
581 bool _bt_mesh_conf_delete_application_key(_bt_mesh_cdb_t *cfg, uint16_t app_idx)
582 {
583         if (!cfg || !cfg->jcfg)
584                 return false;
585
586         return __mesh_delete_key(cfg, cfg->jcfg, "appKeys", app_idx);
587 }
588
589 bool _bt_mesh_conf_set_unicast_address_range(_bt_mesh_cdb_t *cfg,
590                 uint16_t low, uint16_t high)
591 {
592         if (!cfg || !cfg->jcfg)
593                 return false;
594
595         if (!__mesh_write_uint16_hex(cfg->jcfg, "low", low))
596                 return false;
597
598         if (!__mesh_write_uint16_hex(cfg->jcfg, "high", high))
599                 return false;
600
601         return __bt_mesh_save_configruation_file(cfg);
602 }
603
604 bool _bt_mesh_conf_insert_node_object(_bt_mesh_cdb_t *cfg,
605                 uint8_t uuid[16], uint8_t num_els,
606                         uint16_t unicast, uint16_t net_idx)
607 {
608         json_object *jnode;
609         json_object *jelements, *jnodes, *jnetkeys, *jappkeys;
610         int i;
611
612         if (!cfg || !cfg->jcfg)
613                 return false;
614
615         jnode = __mesh_get_node_by_uuid(cfg->jcfg, uuid);
616         if (jnode) {
617                 BT_ERR("MESH:Node already exists");
618                 return false;
619         }
620
621         jnode = json_object_new_object();
622         if (!jnode)
623                 return false;
624
625         if (!__mesh_add_u8_16(jnode, "uuid", uuid))
626                 goto fail;
627
628         jelements = json_object_new_array();
629         if (!jelements)
630                 goto fail;
631
632         for (i = 0; i < num_els; ++i) {
633                 json_object *jelement = json_object_new_object();
634
635                 if (!jelement) {
636                         json_object_put(jelements);
637                         goto fail;
638                 }
639
640                 __mesh_write_int(jelement, "elementIndex", i);
641                 json_object_array_add(jelements, jelement);
642         }
643
644         json_object_object_add(jnode, "elements", jelements);
645
646         jnetkeys = json_object_new_array();
647         if (!jnetkeys)
648                 goto fail;
649
650         json_object_object_add(jnode, "netKeys", jnetkeys);
651
652         if (!__mesh_add_node_key(cfg, jnode, "netKeys", net_idx))
653                 goto fail;
654
655         jappkeys = json_object_new_array();
656         if (!jappkeys)
657                 goto fail;
658
659         json_object_object_add(jnode, "appKeys", jappkeys);
660
661         if (!__mesh_write_uint16_hex(jnode, "unicastAddress", unicast))
662                 goto fail;
663
664         if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes))
665                 goto fail;
666
667         json_object_array_add(jnodes, jnode);
668
669         if (!__bt_mesh_save_configruation_file(cfg))
670                 goto fail;
671
672         return true;
673
674 fail:
675         json_object_put(jnode);
676         return false;
677 }
678
679 bool _bt_mesh_conf_insert_application_key(_bt_mesh_cdb_t *cfg,
680                 uint16_t net_idx, uint16_t app_idx)
681 {
682         if (!cfg || !cfg->jcfg)
683                 return false;
684
685         if (!__mesh_add_app_key(cfg->jcfg, net_idx, app_idx))
686                 return false;
687
688         return __bt_mesh_save_configruation_file(cfg);
689 }
690
691 bool _bt_mesh_conf_insert_network_key(_bt_mesh_cdb_t *cfg,
692                 uint16_t net_idx, uint8_t key_refresh)
693 {
694         json_object *jkey, *jarray;
695
696         if (!cfg || !cfg->jcfg)
697                 return false;
698
699         json_object_object_get_ex(cfg->jcfg, "netKeys", &jarray);
700         if (!jarray || json_object_get_type(jarray) != json_type_array)
701                 return false;
702
703         if (__mesh_get_key_object(jarray, net_idx))
704                 return true;
705
706         jkey = json_object_new_object();
707
708         if (!__mesh_write_int(jkey, "index", net_idx))
709                 goto fail;
710
711         if (!__mesh_write_int(jkey, "phase", key_refresh))
712                 goto fail;
713
714         json_object_array_add(jarray, jkey);
715
716         return __bt_mesh_save_configruation_file(cfg);
717
718 fail:
719         json_object_put(jkey);
720         return false;
721 }
722
723 bool _bt_mesh_conf_delete_network_key(_bt_mesh_cdb_t *cfg,
724                 uint16_t net_idx)
725 {
726         if (!cfg || !cfg->jcfg)
727                 return false;
728
729         return __mesh_delete_key(cfg, cfg->jcfg, "netKeys", net_idx);
730 }
731
732
733 bool _bt_mesh_conf_node_set_timetolive_value(_bt_mesh_cdb_t *cfg,
734                 uint16_t unicast, uint8_t ttl)
735 {
736         json_object *jnode;
737
738         if (!cfg || !cfg->jcfg)
739                 return false;
740
741         jnode = __mesh_get_node_by_unicast(cfg, unicast);
742         if (!jnode)
743                 return false;
744
745         if (!__mesh_write_int(jnode, "defaultTTL", ttl))
746                 return false;
747
748         return __bt_mesh_save_configruation_file(cfg);
749 }
750
751 bool _bt_mesh_conf_node_insert_network_key(_bt_mesh_cdb_t *cfg,
752                 uint16_t unicast, uint16_t net_idx)
753 {
754         json_object *jnode;
755
756         if (!cfg || !cfg->jcfg)
757                 return false;
758
759         jnode = __mesh_get_node_by_unicast(cfg, unicast);
760         if (!jnode)
761                 return false;
762
763         return __mesh_add_node_key(cfg, jnode, "netKeys", net_idx);
764 }
765
766 bool _bt_mesh_conf_node_delete_network_key(_bt_mesh_cdb_t *cfg,
767                 uint16_t unicast, uint16_t net_idx)
768 {
769         json_object *jnode;
770
771         if (!cfg || !cfg->jcfg)
772                 return false;
773
774         jnode = __mesh_get_node_by_unicast(cfg, unicast);
775         if (!jnode)
776                 return false;
777
778         return __mesh_delete_key(cfg, jnode, "netKeys", net_idx);
779 }
780
781 bool _bt_mesh_conf_node_insert_application_key(_bt_mesh_cdb_t *cfg,
782                 uint16_t unicast, uint16_t idx)
783 {
784         json_object *jnode;
785
786         if (!cfg || !cfg->jcfg)
787                 return false;
788
789         jnode = __mesh_get_node_by_unicast(cfg, unicast);
790         if (!jnode)
791                 return false;
792
793         return __mesh_add_node_key(cfg, jnode, "appKeys", idx);
794 }
795
796 bool _bt_mesh_conf_node_delete_application_key(_bt_mesh_cdb_t *cfg,
797         uint16_t unicast, uint16_t idx)
798 {
799         json_object *jnode;
800
801         if (!cfg || !cfg->jcfg)
802                 return false;
803
804         jnode = __mesh_get_node_by_unicast(cfg, unicast);
805         if (!jnode)
806                 return false;
807
808         return __mesh_delete_key(cfg, jnode, "appKeys", idx);
809 }
810
811 _bt_mesh_cdb_t *_bt_mesh_conf_database_create(const char *file_name,
812                 const uint8_t uuid[16],
813                         const uint8_t token[8], const char *network_name,
814                                 const char *app_cred)
815 {
816         _bt_mesh_cdb_t *cfg;
817         json_object *jcfg, *jarray;
818
819         if (!file_name)
820                 return NULL;
821
822         if (!network_name)
823                 return NULL;
824
825         if (!app_cred)
826                 return NULL;
827
828         jcfg = json_object_new_object();
829         if (!jcfg)
830                 return NULL;
831
832         cfg = g_malloc0(sizeof(_bt_mesh_cdb_t));
833         cfg->jcfg = jcfg;
834         cfg->cfg_fname = g_strdup(file_name);
835         cfg->app_cred = g_strdup(app_cred);
836         memcpy(&cfg->token, (void*)token, 8);
837         memcpy(&cfg->uuid, (void*)uuid, 16);
838
839         if (!__mesh_add_u8_8(jcfg, "Network_Token", token))
840                 goto fail;
841
842         if (!__mesh_add_u8_16(jcfg, "Config_Node_UUID", uuid))
843                 goto fail;
844
845         if (!__mesh_add_string(jcfg, "Network_Name", network_name))
846                 goto fail;
847
848         if (!__mesh_add_string(jcfg, "Application_Credential", app_cred))
849                 goto fail;
850
851         jarray = json_object_new_array();
852         if (!jarray)
853                 goto fail;
854
855         json_object_object_add(jcfg, "nodes", jarray);
856
857         jarray = json_object_new_array();
858         if (!jarray)
859                 goto fail;
860
861         json_object_object_add(jcfg, "netKeys", jarray);
862
863         jarray = json_object_new_array();
864         if (!jarray)
865                 goto fail;
866
867         json_object_object_add(jcfg, "appKeys", jarray);
868
869         if (!__bt_mesh_save_configruation_file(cfg))
870                 goto fail;
871
872         return cfg;
873
874 fail:
875         _bt_mesh_conf_free(cfg);
876
877         return NULL;
878 }
879
880 bool _bt_mesh_conf_delete_node(_bt_mesh_cdb_t *cfg, uint16_t unicast)
881 {
882         json_object *jarray;
883         int i, sz;
884
885         if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jarray))
886                 return false;
887
888         if (!jarray || json_object_get_type(jarray) != json_type_array)
889                 return false;
890
891         sz = json_object_array_length(jarray);
892
893         for (i = 0; i < sz; ++i) {
894                 json_object *jentry, *jval;
895                 uint16_t addr;
896                 const char *str;
897
898                 jentry = json_object_array_get_idx(jarray, i);
899                 if (!json_object_object_get_ex(jentry, "unicastAddress",
900                                         &jval))
901                         continue;
902
903                 str = json_object_get_string(jval);
904                 if (sscanf(str, "%04hx", &addr) != 1)
905                         continue;
906
907                 if (addr == unicast)
908                         break;
909         }
910
911         if (i == sz)
912                 return true;
913
914         json_object_array_del_idx(jarray, i, 1);
915
916         return __bt_mesh_save_configruation_file(cfg);
917 }
918
919 uint16_t** _bt_mesh_conf_get_all_model_info(_bt_mesh_cdb_t *cfg,
920                 int element_index, int *num_models)
921 {
922         int sz;
923         int i;
924         json_object *jcfg;
925         json_object *jnode;
926         json_object *jarray = NULL;
927         json_object *jelement = NULL;
928         json_object *jmodelarray = NULL;
929         const char *str;
930         uint16_t **models;
931
932         if (!cfg)
933                 return NULL;
934
935         jcfg = cfg->jcfg;
936         if (!jcfg)
937                 return NULL;
938
939         jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
940         if (jnode)
941                 return NULL;
942
943         /* Get element array object */
944         json_object_object_get_ex(jnode, "elements", &jarray);
945
946         if (!jarray || json_object_get_type(jarray) != json_type_array)
947                 return NULL;
948
949         /* Get specific element by index */
950         jelement = __mesh_get_key_object(jarray, element_index);
951         if (!jelement)
952                 return NULL;
953
954
955         /* Get Model array object inside the selected element */
956         json_object_object_get_ex(jelement, "models", &jmodelarray);
957
958         if (!jmodelarray || json_object_get_type(jmodelarray) != json_type_array)
959                 return NULL;
960
961         sz = json_object_array_length(jmodelarray);
962         models = (uint16_t**) g_malloc0(sz * sizeof(uint16_t*));
963
964         for (i = 0; i < sz; ++i) {
965                 json_object *jentry;
966
967                 jentry = json_object_array_get_idx(jmodelarray, i);
968                 str = json_object_get_string(jentry);
969                 /* Only standard models are handled now */
970                 if (sscanf(str, "%04hx", models[i]) != 1) {
971                         for (int j =0 ; j < sz; j++)
972                                 g_free(models[j]);
973                         g_free(models);
974                         return NULL;
975                 }
976         }
977         /* TODO: Need to handle vendor models */
978         *num_models = sz;
979         return models;
980 }
981
982 bool _bt_mesh_conf_get_element_count(_bt_mesh_cdb_t *cfg,
983                 uint16_t *num_elems)
984 {
985         int sz;
986         json_object *jcfg;
987         json_object *jnode;
988         json_object *jarray = NULL;
989
990         if (!cfg)
991                 return false;
992
993         jcfg = cfg->jcfg;
994         if (!jcfg)
995                 return false;
996
997         jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
998         if (jnode)
999                 return false;
1000
1001         json_object_object_get_ex(jnode, "elements", &jarray);
1002
1003         if (!jarray || json_object_get_type(jarray) != json_type_array)
1004                 return false;
1005
1006         sz = json_object_array_length(jarray);
1007         if (sz == 0)
1008                 return false;
1009         *num_elems = sz;
1010
1011         return true;
1012 }
1013
1014 bool _bt_mesh_conf_fetch_vendor_specific_info(_bt_mesh_cdb_t *cfg,
1015         uint16_t *cid, uint16_t *vid,
1016                 uint16_t *version, uint16_t *crpl,
1017                         int *relay, int *friend,
1018                                 int *proxy, int *lpn)
1019 {
1020         json_object *jcfg;
1021         json_object *jnode;
1022         json_object *jobj = NULL;
1023         json_object *jobjfeature = NULL;
1024         const char *str;
1025
1026         if (!cfg)
1027                 return false;
1028
1029         jcfg = cfg->jcfg;
1030         if (!jcfg)
1031                 return false;
1032
1033         jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
1034         if (jnode)
1035                 return false;
1036
1037         /* Get CRPL */
1038         if (!json_object_object_get_ex(jnode, "crpl", &jobj))
1039                 return false;
1040
1041         str = json_object_get_string(jobj);
1042         if (!str)
1043                 return false;
1044         if (sscanf(str, "%04hx", crpl) != 1)
1045                 return false;
1046
1047         /* Get Company ID */
1048         if (!json_object_object_get_ex(jnode, "cid", &jobj))
1049                 return false;
1050
1051         str = json_object_get_string(jobj);
1052         if (!str)
1053                 return false;
1054         if (sscanf(str, "%04hx", cid) != 1)
1055                 return false;
1056
1057         /* Get Vendor ID */
1058         if (!json_object_object_get_ex(jnode, "pid", &jobj))
1059                 return false;
1060
1061         str = json_object_get_string(jobj);
1062         if (!str)
1063                 return false;
1064
1065         if (sscanf(str, "%04hx", vid) != 1)
1066                 return false;
1067
1068         /* Get Version ID */
1069         if (!json_object_object_get_ex(jnode, "vid", &jobj))
1070                 return false;
1071
1072         str = json_object_get_string(jobj);
1073         if (!str)
1074                 return false;
1075         if (sscanf(str, "%04hx", version) != 1)
1076                 return false;
1077
1078         jobj = json_object_object_get(jnode, "features");
1079
1080         if (jobj) {
1081                 if (json_object_object_get_ex(jobj, "relay", &jobjfeature)) {
1082                         str = json_object_get_string(jobj);
1083                         if (str)
1084                                 sscanf(str, "%d", relay);
1085                 }
1086
1087                 if (json_object_object_get_ex(jobj, "friend", &jobjfeature)) {
1088                         str = json_object_get_string(jobj);
1089                         if (str)
1090                                 sscanf(str, "%d", friend);
1091                 }
1092
1093                 if (json_object_object_get_ex(jobj, "proxy", &jobjfeature)) {
1094                         str = json_object_get_string(jobj);
1095                         if (str)
1096                                 sscanf(str, "%d", proxy);
1097                 }
1098                 if (json_object_object_get_ex(jobj, "lowPower", &jobjfeature)) {
1099                         str = json_object_get_string(jobj);
1100                         if (str)
1101                                 sscanf(str, "%d", lpn);
1102                 }
1103         }
1104         return true;
1105 }
1106
1107 GSList *_bt_mesh_conf_load_group_info(_bt_mesh_cdb_t *cfg)
1108 {
1109         json_object *jgroups;
1110         GSList *groups = NULL;
1111         int i, sz;
1112
1113         if (!cfg || !cfg->jcfg)
1114                 return NULL;
1115
1116         if (!json_object_object_get_ex(cfg->jcfg, "groups", &jgroups)) {
1117                 jgroups = json_object_new_array();
1118                 if (!jgroups)
1119                         return NULL;
1120
1121                 json_object_object_add(cfg->jcfg, "groups", jgroups);
1122         }
1123
1124         sz = json_object_array_length(jgroups);
1125
1126         for (i = 0; i < sz; ++i) {
1127                 json_object *jgroup, *jval;
1128                 _bt_mesh_group_t *grp;
1129                 uint16_t addr, addr_len;
1130                 const char *str;
1131
1132                 jgroup = json_object_array_get_idx(jgroups, i);
1133                 if (!jgroup)
1134                         continue;
1135
1136                 if (!json_object_object_get_ex(jgroup, "name", &jval))
1137                         continue;
1138
1139                 str = json_object_get_string(jval);
1140                 if (strlen(str) != 10)
1141                         continue;
1142
1143                 if (sscanf(str + 6, "%04hx", &addr) != 1)
1144                         continue;
1145                 if (!json_object_object_get_ex(jgroup, "address", &jval))
1146                         continue;
1147
1148                 str = json_object_get_string(jval);
1149                 addr_len = strlen(str);
1150                 if (addr_len != 4 && addr_len != 32)
1151                         continue;
1152
1153                 if (addr_len == 32 && !MESH_IS_VIRTUAL(addr))
1154                         continue;
1155
1156                 grp = g_malloc0(sizeof(_bt_mesh_group_t));
1157
1158                 if (addr_len == 4)
1159                         sscanf(str, "%04hx", &grp->grp_addr);
1160                 else {
1161                         _bt_mesh_util_convert_string_to_hex(str,
1162                                 32, grp->label_uuid, 16);
1163                         grp->grp_addr = addr;
1164                 }
1165
1166                 groups = g_slist_append(groups, grp);
1167         }
1168
1169         return groups;
1170 }
1171
1172 bool _bt_mesh_conf_insert_group_info(_bt_mesh_cdb_t *cfg,
1173                 _bt_mesh_group_t *grp)
1174 {
1175         json_object *jgroup, *jgroups, *jval;
1176         char buf[16];
1177
1178         if (!cfg || !cfg->jcfg)
1179                 return false;
1180
1181         if (!json_object_object_get_ex(cfg->jcfg, "groups", &jgroups)) {
1182                 BT_INFO("Mesh: Group JSON object is not present: Create");
1183                 jgroups = json_object_new_array();
1184                 if (!jgroups)
1185                         return false;
1186
1187                 json_object_object_add(cfg->jcfg, "groups", jgroups);
1188         }
1189
1190         jgroup = json_object_new_object();
1191         if (!jgroup)
1192                 return false;
1193
1194         snprintf(buf, 11, "Group_%4.4x", grp->grp_addr);
1195         jval = json_object_new_string(buf);
1196         json_object_object_add(jgroup, "name", jval);
1197
1198         if (MESH_IS_VIRTUAL(grp->grp_addr)) {
1199                 if (!__mesh_add_u8_16(jgroup, "address", grp->label_uuid))
1200                         goto fail;
1201         } else {
1202                 if (!__mesh_write_uint16_hex(jgroup, "address", grp->grp_addr))
1203                         goto fail;
1204         }
1205
1206         json_object_array_add(jgroups, jgroup);
1207
1208         return __bt_mesh_save_configruation_file(cfg);
1209
1210 fail:
1211         json_object_put(jgroup);
1212         return false;
1213 }
1214
1215 bool _bt_mesh_conf_delete_group_entry(_bt_mesh_cdb_t *cfg, uint16_t addr)
1216 {
1217         if (!cfg || !cfg->jcfg)
1218                 return false;
1219
1220         return __mesh_delete_group(cfg, cfg->jcfg, "groups", addr);
1221 }
1222
1223 bool _bt_mesh_conf_set_network_friendly_name(_bt_mesh_cdb_t *cfg,
1224                 const char *network_name)
1225 {
1226         json_object *jcfg;
1227
1228         if (!cfg)
1229                 return false;
1230         jcfg = cfg->jcfg;
1231
1232         if (!jcfg)
1233                 return false;
1234
1235         json_object_object_del(jcfg, "Network_Name");
1236         __mesh_add_string(jcfg, "Network_Name", network_name);
1237
1238
1239         BT_INFO("Mesh: CDB: Network New Name [%s]", network_name);
1240         return __bt_mesh_save_configruation_file(cfg);
1241 }
1242
1243 const char * _bt_mesh_conf_get_network_friendly_name(_bt_mesh_cdb_t *cfg)
1244 {
1245         json_object *jcfg;
1246         json_object *jobj = NULL;
1247         const char *str;
1248
1249         if (!cfg)
1250                 return NULL;
1251         jcfg = cfg->jcfg;
1252
1253         if (!jcfg)
1254                 return NULL;
1255
1256         /* Get Network Name */
1257         if (!json_object_object_get_ex(jcfg, "Network_Name", &jobj))
1258                 return NULL;
1259
1260         str = json_object_get_string(jobj);
1261         if (!str)
1262                 return NULL;
1263
1264         BT_INFO("Mesh: CDB: Network Name [%s]", str);
1265         return str;
1266 }
1267
1268 static bool __mesh_load_composition(_bt_mesh_cdb_t *cfg,
1269                 json_object *jnode, uint16_t unicast)
1270 {
1271         json_object *jarray;
1272         int i, ele_cnt;
1273
1274         if (!json_object_object_get_ex(jnode, "elements", &jarray))
1275                 return false;
1276
1277         if (json_object_get_type(jarray) != json_type_array)
1278                 return false;
1279
1280         ele_cnt = json_object_array_length(jarray);
1281
1282         for (i = 0; i < ele_cnt; ++i) {
1283                 json_object *jentry, *jval, *jmods;
1284                 int32_t index;
1285                 int k, mod_cnt;
1286
1287                 jentry = json_object_array_get_idx(jarray, i);
1288                 if (!json_object_object_get_ex(jentry, "index", &jval))
1289                         return false;
1290
1291                 index = json_object_get_int(jval);
1292                 if (index > 0xff)
1293                         return false;
1294
1295                 if (!json_object_object_get_ex(jentry, "models", &jmods))
1296                         return false;
1297
1298                 mod_cnt = json_object_array_length(jmods);
1299                 BT_INFO("Mesh: Total Model count in element Index [%d] is [%d]",
1300                         index, mod_cnt);
1301
1302                 for (k = 0; k < mod_cnt; ++k) {
1303                         json_object *jmod, *jid;
1304                         uint32_t mod_id, len;
1305                         const char *str;
1306
1307                         jmod = json_object_array_get_idx(jmods, k);
1308                         if (!json_object_object_get_ex(jmod, "modelId", &jid))
1309                                 return false;
1310
1311                         str = json_object_get_string(jid);
1312                         len = strlen(str);
1313
1314                         if (len != 4 && len != 8)
1315                                 return false;
1316
1317                         if ((len == 4) && (sscanf(str, "%04x", &mod_id) != 1))
1318                                 return false;
1319
1320                         if ((len == 8) && (sscanf(str, "%08x", &mod_id) != 1))
1321                                 return false;
1322
1323                         _bt_mesh_node_set_model(cfg->uuid,
1324                                         unicast, index, mod_id, len == 8);
1325                 }
1326         }
1327
1328         return true;
1329 }
1330
1331 bool _bt_mesh_conf_set_node_comp_data(_bt_mesh_cdb_t *cfg,
1332                 uint16_t unicast, uint8_t *data, uint16_t len)
1333 {
1334         uint16_t features;
1335         int sz, i = 0;
1336         json_object *jnode, *jobj, *jelements;
1337         uint16_t crpl;
1338
1339         if (!cfg || !cfg->jcfg)
1340                 return false;
1341
1342         jnode = __mesh_get_node_by_unicast(cfg, unicast);
1343         if (!jnode)
1344                 return false;
1345
1346         /* skip page -- We only support Page Zero */
1347         data++;
1348         len--;
1349
1350         /* If "crpl" property is present, composition is already recorded */
1351         if (json_object_object_get_ex(jnode, "crpl", &jobj))
1352                 return true;
1353
1354         if (!__mesh_write_uint16_hex(jnode, "cid", l_get_le16(&data[0])))
1355                 return false;
1356
1357         if (!__mesh_write_uint16_hex(jnode, "pid", l_get_le16(&data[2])))
1358                 return false;
1359
1360         if (!__mesh_write_uint16_hex(jnode, "vid", l_get_le16(&data[4])))
1361                 return false;
1362
1363         crpl = l_get_le16(&data[6]);
1364
1365         features = l_get_le16(&data[8]);
1366         data += 10;
1367         len -= 10;
1368
1369         jobj = json_object_object_get(jnode, "features");
1370         if (!jobj) {
1371                 jobj = json_object_new_object();
1372                 json_object_object_add(jnode, "features", jobj);
1373         }
1374
1375         if ((features & MESH_FEATURE_RELAY))
1376                 __mesh_write_int(jobj, "relay", 1);
1377         else
1378                 __mesh_write_int(jobj, "relay", 0);
1379
1380         if ((features & MESH_FEATURE_FRIEND))
1381                 __mesh_write_int(jobj, "friend", 1);
1382         else
1383                 __mesh_write_int(jobj, "friend", 0);
1384
1385         if ((features & MESH_FEATURE_PROXY))
1386                 __mesh_write_int(jobj, "proxy", 1);
1387         else
1388                 __mesh_write_int(jobj, "proxy", 0);
1389
1390         if ((features & MESH_FEATURE_LPN))
1391                 __mesh_write_int(jobj, "lowPower", 1);
1392         else
1393                 __mesh_write_int(jobj, "lowPower", 0);
1394
1395         jelements = json_object_object_get(jnode, "elements");
1396         if (!jelements)
1397                 return false;
1398
1399         sz = json_object_array_length(jelements);
1400
1401         while (len) {
1402                 json_object *jentry, *jmods;
1403                 uint32_t mod_id;
1404                 uint8_t m, v;
1405
1406                 /* Mismatch in the element count */
1407                 if (i >= sz)
1408                         return false;
1409
1410                 jentry = json_object_array_get_idx(jelements, i);
1411
1412                 __mesh_write_int(jentry, "index", i);
1413
1414                 if (!__mesh_write_uint16_hex(jentry, "location", l_get_le16(data)))
1415                         return false;
1416
1417                 data += 2;
1418                 len -= 2;
1419
1420                 m = *data++;
1421                 v = *data++;
1422                 len -= 2;
1423
1424                 jmods = json_object_object_get(jentry, "models");
1425                 if (!jmods) {
1426                         /* For backwards compatibility */
1427                         jmods = json_object_new_array();
1428                         json_object_object_add(jentry, "models", jmods);
1429                 }
1430
1431                 while (len >= 2 && m--) {
1432                         mod_id = l_get_le16(data);
1433
1434                         jobj = __mesh_init_model(mod_id);
1435                         if (!jobj)
1436                                 goto fail;
1437
1438                         json_object_array_add(jmods, jobj);
1439                         data += 2;
1440                         len -= 2;
1441                 }
1442
1443                 while (len >= 4 && v--) {
1444                         jobj = json_object_new_object();
1445                         mod_id = l_get_le16(data + 2);
1446                         mod_id = l_get_le16(data) << 16 | mod_id;
1447
1448                         jobj = __mesh_init_vendor_model(mod_id);
1449                         if (!jobj)
1450                                 goto fail;
1451
1452                         json_object_array_add(jmods, jobj);
1453
1454                         data += 4;
1455                         len -= 4;
1456                 }
1457
1458                 i++;
1459         }
1460
1461         /* CRPL is written last. Will be used to check composition's presence */
1462         if (!__mesh_write_uint16_hex(jnode, "crpl", crpl))
1463                 goto fail;
1464
1465         /* Initiate remote's composition from storage */
1466         if (!__mesh_load_composition(cfg, jnode, unicast))
1467                 goto fail;
1468
1469         return  __bt_mesh_save_configruation_file(cfg);
1470
1471 fail:
1472         /* Reset elements array */
1473         json_object_object_del(jnode, "elements");
1474         __mesh_init_elements(sz);
1475
1476         return false;
1477 }
1478
1479 _bt_mesh_cdb_t* _bt_mesh_conf_load(const char *file_name,
1480                 const char *token)
1481 {
1482         char *token_str = NULL;
1483         int fd;
1484         char *str;
1485         struct stat st;
1486         ssize_t sz;
1487         json_object *jcfg;
1488         _bt_mesh_cdb_t *cfg;
1489
1490         fd = open(file_name, O_RDONLY);
1491         if (fd < 0)
1492                 return NULL;
1493
1494         if (fstat(fd, &st) == -1) {
1495                 close(fd);
1496                 return NULL;
1497         }
1498
1499         str = (char *) g_malloc0(st.st_size + 1);
1500         if (!str) {
1501                 close(fd);
1502                 return NULL;
1503         }
1504
1505         sz = read(fd, str, st.st_size);
1506         if (sz != st.st_size) {
1507                 BT_ERR("Mesh: Failed to read configuration file [%s]", file_name);
1508                 g_free(str);
1509                 return NULL;
1510         }
1511
1512         jcfg = json_tokener_parse(str);
1513
1514         close(fd);
1515         g_free(str);
1516
1517         if (!jcfg)
1518                 return NULL;
1519         cfg = g_malloc0(sizeof(_bt_mesh_cdb_t));
1520
1521         cfg->jcfg = jcfg;
1522         cfg->cfg_fname = g_strdup(file_name);
1523
1524         if (!__mesh_get_uuid(jcfg, cfg->uuid)) {
1525                 BT_ERR("Mesh: Configuration file missing UUID");
1526                 goto fail;
1527         }
1528
1529         if (!__mesh_get_token(jcfg, cfg->token)) {
1530                 BT_ERR("Mesh: Configuration file missing token");
1531                 goto fail;
1532         }
1533
1534         token_str = _bt_service_convert_hex_to_string((unsigned char*)cfg->token, 8);
1535
1536         /* Match CDB file tken with user's token */
1537         if (g_strcmp0(token_str, token)) {
1538                 BT_INFO("Mesh: Token did not match! File token [%s] requested token [%s]",
1539                                 cfg->token, token);
1540                 goto fail;
1541         }
1542         /* TODO: Load keys and remotes */
1543         return cfg;
1544 fail:
1545         _bt_mesh_conf_free(cfg);
1546         return NULL;
1547 }
1548
1549 bool _bt_mesh_conf_load_all_nodes(_bt_mesh_cdb_t *cfg)
1550 {
1551         json_object *jnodes;
1552         int i, sz, node_count = 0;
1553
1554         json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes);
1555         if (!jnodes || json_object_get_type(jnodes) != json_type_array)
1556                 return false;
1557
1558         sz = json_object_array_length(jnodes);
1559
1560         for (i = 0; i < sz; ++i) {
1561                 json_object *jnode, *jval, *jarray;
1562                 uint8_t uuid[16];
1563                 uint16_t unicast, key_idx;
1564                 const char *str;
1565                 int ele_cnt, key_cnt;
1566                 int j;
1567
1568                 jnode = json_object_array_get_idx(jnodes, i);
1569                 if (!jnode)
1570                         continue;
1571
1572                 if (!json_object_object_get_ex(jnode, "uuid", &jval))
1573                         continue;
1574
1575                 str = json_object_get_string(jval);
1576                 if (strlen(str) != 32)
1577                         continue;
1578
1579                 _bt_mesh_util_convert_string_to_hex(str, 32, uuid, 16);
1580
1581                 if (!json_object_object_get_ex(jnode, "unicastAddress", &jval))
1582                         continue;
1583
1584                 str = json_object_get_string(jval);
1585                 if (sscanf(str, "%04hx", &unicast) != 1)
1586                         continue;
1587
1588                 json_object_object_get_ex(jnode, "elements", &jarray);
1589                 if (!jarray || json_object_get_type(jarray) != json_type_array)
1590                         continue;
1591
1592                 ele_cnt = json_object_array_length(jarray);
1593
1594                 if (ele_cnt > MESH_MAX_ELE_COUNT)
1595                         continue;
1596
1597                 json_object_object_get_ex(jnode, "netKeys", &jarray);
1598                 if (!jarray || json_object_get_type(jarray) != json_type_array)
1599                         continue;
1600
1601                 key_cnt = json_object_array_length(jarray);
1602                 if (key_cnt < 0)
1603                         continue;
1604
1605                 key_idx = __mesh_node_parse_key(jarray, 0);
1606                 if (key_idx == MESH_KEY_IDX_INVALID)
1607                         continue;
1608
1609                 _bt_mesh_node_add_node(cfg->uuid, (const uint8_t *)uuid, unicast, ele_cnt,
1610                                 key_idx);
1611                 for (j = 1; j < key_cnt; j++) {
1612                         key_idx = __mesh_node_parse_key(jarray, j);
1613
1614                         if (key_idx != MESH_KEY_IDX_INVALID)
1615                                 _bt_mesh_node_add_net_key(cfg->uuid, unicast, key_idx);
1616                 }
1617
1618                 json_object_object_get_ex(jnode, "appKeys", &jarray);
1619                 if (!jarray || json_object_get_type(jarray) != json_type_array)
1620                         continue;
1621
1622                 key_cnt = json_object_array_length(jarray);
1623                 for (j = 0; j < key_cnt; j++) {
1624                         key_idx = __mesh_node_parse_key(jarray, j);
1625
1626                         if (key_idx != MESH_KEY_IDX_INVALID)
1627                                 _bt_mesh_node_add_app_key(cfg->uuid, unicast, key_idx);
1628                 }
1629
1630                 __mesh_load_composition(cfg, jnode, unicast);
1631
1632                 node_count++;
1633
1634                 /* TODO: Add the rest of the configuration */
1635         }
1636
1637         if (node_count != sz)
1638                 BT_ERR("Mesh: CDB: The remote node configuration load is incomplete!");
1639
1640         return true;
1641 }
1642
1643 bool _bt_mesh_conf_load_all_keys(_bt_mesh_cdb_t* cfg)
1644 {
1645         json_object *jarray, *jentry;
1646         int net_idx, app_idx;
1647         int i, key_cnt;
1648         json_object *jobj = cfg->jcfg;
1649
1650         json_object_object_get_ex(jobj, "netKeys", &jarray);
1651         if (!jarray || json_object_get_type(jarray) != json_type_array)
1652                 return false;
1653
1654         key_cnt = json_object_array_length(jarray);
1655         if (key_cnt < 0)
1656                 return false;
1657
1658         for (i = 0; i < key_cnt; ++i) {
1659                 int phase;
1660
1661                 jentry = json_object_array_get_idx(jarray, i);
1662
1663                 if (!__mesh_get_int(jentry, "index", &net_idx))
1664                         return false;
1665
1666                 _bt_mesh_keys_add_net_key(cfg->uuid, (uint16_t) net_idx);
1667
1668                 if (!__mesh_get_int(jentry, "phase", &phase))
1669                         return false;
1670
1671                 _bt_mesh_keys_set_net_key_phase(cfg, net_idx, (uint8_t) phase, false);
1672         }
1673
1674         json_object_object_get_ex(jobj, "appKeys", &jarray);
1675         if (!jarray || json_object_get_type(jarray) != json_type_array)
1676                 return false;
1677
1678         key_cnt = json_object_array_length(jarray);
1679         if (key_cnt < 0)
1680                 return false;
1681
1682         for (i = 0; i < key_cnt; ++i) {
1683
1684                 jentry = json_object_array_get_idx(jarray, i);
1685                 if (!__mesh_get_int(jentry, "boundNetKey", &net_idx))
1686                         return false;
1687
1688                 if (!__mesh_get_int(jentry, "index", &app_idx))
1689                         return false;
1690
1691                 _bt_mesh_keys_add_app_key(cfg->uuid, (uint16_t) net_idx, (uint16_t) app_idx);
1692         }
1693
1694         return true;
1695 }