4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6 * @author: Anupam Roy <anupam.r@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
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"
41 #include "bt-internal-types.h"
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>
61 static const char *bak_ext = ".bak";
62 static const char *tmp_ext = ".tmp";
64 static bool __bt_mesh_save_cdb(
65 _bt_mesh_cdb_t *cfg, const char *fname)
71 outfile = fopen(fname, "w");
73 BT_ERR("Failed to save configuration to %s",
78 str = json_object_to_json_string_ext(cfg->jcfg,
79 JSON_C_TO_STRING_PRETTY);
81 if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
82 BT_ERR("Incomplete write of mesh configuration");
91 static bool __bt_mesh_save_configruation_file(_bt_mesh_cdb_t *cfg)
93 char *fname_tmp, *fname_bak, *fname_cfg;
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);
101 result = __bt_mesh_save_cdb(cfg, fname_tmp);
105 rename(fname_cfg, fname_bak);
106 rename(fname_tmp, fname_cfg);
114 gettimeofday(&cfg->write_time, NULL);
119 static bool __mesh_get_int(json_object *jobj,
120 const char *keyword, int *value)
124 if (!json_object_object_get_ex(jobj, keyword, &jvalue))
127 *value = json_object_get_int(jvalue);
128 if (errno == EINVAL) {
129 BT_ERR("MESH:Error: %s should contain an integer value\n",
137 static uint16_t __mesh_node_parse_key(json_object *jarray, int i)
142 jkey = json_object_array_get_idx(jarray, i);
144 return MESH_KEY_IDX_INVALID;
146 if (!__mesh_get_int(jkey, "index", &idx))
147 return MESH_KEY_IDX_INVALID;
149 return (uint16_t)idx;
152 static bool __mesh_write_int(json_object *jobj,
153 const char *keyword, int val)
157 json_object_object_del(jobj, keyword);
159 jval = json_object_new_int(val);
163 json_object_object_add(jobj, keyword, jval);
167 static bool __mesh_write_uint32_hex(json_object *jobj,
168 const char *desc, uint32_t val)
170 json_object *jstring;
173 snprintf(buf, 9, "%8.8x", val);
174 jstring = json_object_new_string(buf);
178 /* Overwrite old value if present */
179 json_object_object_del(jobj, desc);
181 json_object_object_add(jobj, desc, jstring);
185 static bool __mesh_write_uint16_hex(json_object *jobj,
186 const char *desc, uint16_t value)
188 json_object *jstring;
191 snprintf(buf, 5, "%4.4x", value);
192 jstring = json_object_new_string(buf);
196 json_object_object_add(jobj, desc, jstring);
200 static json_object *__mesh_init_model(uint16_t mod_id)
204 jmod = json_object_new_object();
206 if (!__mesh_write_uint16_hex(jmod, "modelId", mod_id)) {
207 json_object_put(jmod);
214 static json_object *__mesh_init_vendor_model(uint32_t mod_id)
218 jmod = json_object_new_object();
220 if (!__mesh_write_uint32_hex(jmod, "modelId", mod_id)) {
221 json_object_put(jmod);
228 static json_object *__mesh_init_elements(uint8_t num_els)
230 json_object *jelements;
233 jelements = json_object_new_array();
235 for (i = 0; i < num_els; ++i) {
236 json_object *jelement, *jmods;
238 jelement = json_object_new_object();
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);
245 json_object_array_add(jelements, jelement);
250 static bool __mesh_add_app_key(json_object *jobj,
251 uint16_t net_idx, uint16_t app_idx)
253 json_object *jkey, *jarray;
255 json_object_object_get_ex(jobj, "appKeys", &jarray);
256 if (!jarray || json_object_get_type(jarray) != json_type_array)
259 jkey = json_object_new_object();
261 if (!__mesh_write_int(jkey, "boundNetKey", (int)net_idx))
264 if (!__mesh_write_int(jkey, "index", (int)app_idx))
267 json_object_array_add(jarray, jkey);
271 json_object_put(jkey);
275 static bool __mesh_add_node_key(_bt_mesh_cdb_t *cfg,
276 json_object *jobj, const char *desc, uint16_t idx)
278 json_object *jkey, *jarray;
280 json_object_object_get_ex(jobj, desc, &jarray);
281 if (!jarray || json_object_get_type(jarray) != json_type_array)
284 jkey = json_object_new_object();
286 if (!__mesh_write_int(jkey, "index", (int)idx)) {
287 json_object_put(jkey);
291 json_object_array_add(jarray, jkey);
293 return __bt_mesh_save_configruation_file(cfg);
296 static json_object *__mesh_get_node_by_unicast(_bt_mesh_cdb_t *cfg,
302 if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jarray))
305 if (!jarray || json_object_get_type(jarray) != json_type_array)
308 sz = json_object_array_length(jarray);
310 for (i = 0; i < sz; ++i) {
311 json_object *jentry, *jval;
315 jentry = json_object_array_get_idx(jarray, i);
316 if (!json_object_object_get_ex(jentry, "unicastAddress",
320 str = json_object_get_string(jval);
321 if (sscanf(str, "%04hx", &addr) != 1)
331 static json_object *__mesh_get_node_by_uuid(json_object *jcfg,
334 json_object *jarray = NULL;
338 _bt_mesh_util_convert_hex_to_string(uuid, 16, buf, sizeof(buf));
339 BT_INFO("Mesh: Find Node with UUID [%s]", buf);
341 json_object_object_get_ex(jcfg, "nodes", &jarray);
342 if (!jarray || json_object_get_type(jarray) != json_type_array)
345 sz = json_object_array_length(jarray);
346 BT_INFO("Mesh: Total nodes present in CDB [%d]", sz);
348 for (i = 0; i < sz; ++i) {
349 json_object *jentry, *jval;
352 jentry = json_object_array_get_idx(jarray, i);
353 if (!json_object_object_get_ex(jentry, "uuid", &jval))
356 str = json_object_get_string(jval);
357 if (strlen(str) != 32)
359 BT_INFO("Mesh: Got one node with UUID [%s]", str);
360 BT_INFO("Mesh: Match with uuid [%s]", buf);
362 if (!g_strcmp0(buf, str))
369 static json_object *__mesh_get_key_object(json_object *jarray,
372 int i, sz = json_object_array_length(jarray);
374 for (i = 0; i < sz; ++i) {
378 jentry = json_object_array_get_idx(jarray, i);
379 if (!__mesh_get_int(jentry, "index", &jidx))
389 static bool __mesh_add_string(json_object *jobj,
390 const char *desc, const char *str)
392 json_object *jstring = json_object_new_string(str);
397 json_object_object_add(jobj, desc, jstring);
401 static bool __mesh_get_token(json_object *jobj, uint8_t token[8])
406 if (!json_object_object_get_ex(jobj, "Network_Token", &jval))
409 str = json_object_get_string(jval);
410 if (!_bt_mesh_util_convert_string_to_hex(str, strlen(str), token, 8))
416 static bool __mesh_get_uuid(json_object *jobj, uint8_t uuid[16])
421 if (!json_object_object_get_ex(jobj, "Config_Node_UUID", &jval))
424 str = json_object_get_string(jval);
425 if (!_bt_mesh_util_convert_string_to_hex(str, strlen(str), uuid, 16))
431 static bool __mesh_add_u8_8(json_object *jobj,
432 const char *desc, const uint8_t value[8])
434 json_object *jstring;
437 _bt_mesh_util_convert_hex_to_string((uint8_t *) value, 8, buf, 17);
438 jstring = json_object_new_string(buf);
442 json_object_object_add(jobj, desc, jstring);
446 static bool __mesh_add_u8_16(json_object *jobj,
447 const char *desc, const uint8_t value[16])
449 json_object *jstring;
452 _bt_mesh_util_convert_hex_to_string((uint8_t *) value, 16, buf, 33);
453 jstring = json_object_new_string(buf);
457 json_object_object_add(jobj, desc, jstring);
461 void _bt_mesh_conf_free(_bt_mesh_cdb_t *cfg)
463 g_free(cfg->cfg_fname);
465 g_free(cfg->app_cred);
466 json_object_put(cfg->jcfg);
467 g_slist_free_full(cfg->groups, g_free);
471 bool _bt_mesh_conf_parse_data(void *cfg, int k)
473 _bt_mesh_cdb_t *conf = (_bt_mesh_cdb_t*) cfg;
479 static bool __mesh_jarray_group_delete(json_object *jarray, uint16_t group_addr)
481 int i, sz = json_object_array_length(jarray);
485 for (i = 0; i < sz; ++i) {
490 jentry = json_object_array_get_idx(jarray, i);
491 if (!json_object_object_get_ex(jentry, "name",
495 str = json_object_get_string(jval);
498 memcpy(buf, str + 6, 5);
499 BT_INFO("Mesh: JSON Group string:[%s]", buf);
500 if (sscanf(buf, "%04hx", &addr) != 1)
502 BT_INFO("Mesh: JSON Group in Hex [0x%2.2x]", addr);
504 if (group_addr == addr)
509 BT_INFO("Mesh: Failed to remove group");
513 json_object_array_del_idx(jarray, i, 1);
517 static void __mesh_jarray_key_del(json_object *jarray, int16_t idx)
519 int i, sz = json_object_array_length(jarray);
521 for (i = 0; i < sz; ++i) {
525 jentry = json_object_array_get_idx(jarray, i);
527 if (!__mesh_get_int(jentry, "index", &val))
531 json_object_array_del_idx(jarray, i, 1);
537 static bool __mesh_delete_group(_bt_mesh_cdb_t *cfg,
538 json_object *jobj, const char *desc, uint16_t addr)
542 if (!json_object_object_get_ex(jobj, desc, &jarray))
545 if (!__mesh_jarray_group_delete(jarray, addr))
548 return __bt_mesh_save_configruation_file(cfg);
551 static bool __mesh_delete_key(_bt_mesh_cdb_t *cfg,
552 json_object *jobj, const char *desc, uint16_t idx)
556 if (!json_object_object_get_ex(jobj, desc, &jarray))
559 __mesh_jarray_key_del(jarray, idx);
561 return __bt_mesh_save_configruation_file(cfg);
564 bool _bt_mesh_conf_set_phase_network_key(_bt_mesh_cdb_t *cfg,
565 uint16_t net_idx, uint8_t phase)
567 json_object *jval, *jarray, *jkey;
569 if (!cfg || !cfg->jcfg)
572 json_object_object_get_ex(cfg->jcfg, "netKeys", &jarray);
573 if (!jarray || json_object_get_type(jarray) != json_type_array)
576 jkey = __mesh_get_key_object(jarray, net_idx);
580 jval = json_object_new_int(phase);
584 json_object_object_add(jkey, "phase", jval);
586 return __bt_mesh_save_configruation_file(cfg);
589 bool _bt_mesh_conf_delete_application_key(_bt_mesh_cdb_t *cfg, uint16_t app_idx)
591 if (!cfg || !cfg->jcfg)
594 return __mesh_delete_key(cfg, cfg->jcfg, "appKeys", app_idx);
597 bool _bt_mesh_conf_set_model_info(_bt_mesh_cdb_t *cfg,
598 uint16_t unicast, GSList *models)
601 json_object *jnode, *jobj, *jelements;
604 BT_INFO("Mesh: Set All model informations in the node [0x%2.2x]",
607 if (!cfg || !cfg->jcfg)
610 jnode = __mesh_get_node_by_unicast(cfg, unicast);
614 jelements = json_object_object_get(jnode, "elements");
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));
623 for (l = models; l != NULL; l = g_slist_next(l)) {
624 json_object *jentry, *jmods;
625 bluetooth_mesh_model_t *mod = l->data;
627 BT_INFO("Mesh: Elem Idx [%u]", mod->elem_index);
628 BT_INFO("Mesh: Model ID [0x%4.4x]", mod->model_id);
630 jentry = json_object_array_get_idx(jelements, mod->elem_index);
634 /* Write Index for the eleement */
635 if (!__mesh_write_int(jentry, "index", (int)mod->elem_index))
638 /* Set Hardcoded location */
639 if (!__mesh_write_uint16_hex(jentry, "location", 0x0000))
642 jmods = json_object_object_get(jentry, "models");
644 /* For backwards compatibility */
645 jmods = json_object_new_array();
646 json_object_object_add(jentry, "models", jmods);
649 /* TODO: Vendor Model Entry: Only BT SIG model entry is handled now */
650 jobj = __mesh_init_model((uint16_t)mod->model_id);
654 json_object_array_add(jmods, jobj);
658 return __bt_mesh_save_configruation_file(cfg);
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,
667 json_object *jnode, *jobj;
669 BT_INFO("Mesh: Set Vednor Information in CDB for node [0x%2.2x]",
672 if (!cfg || !cfg->jcfg)
675 jnode = __mesh_get_node_by_unicast(cfg, unicast);
677 BT_INFO("Mesh: Node not found");
682 if (!__mesh_write_uint16_hex(jnode, "crpl", crpl)) {
683 BT_ERR("Mesh: Could not write CRPL");
688 if (!__mesh_write_uint16_hex(jnode, "cid", cid)) {
689 BT_ERR("Mesh: Could not write CID");
693 /* Vendor ID or Product ID */
694 if (!__mesh_write_uint16_hex(jnode, "pid", pid)) {
695 BT_INFO("Mesh: Could not write PID");
700 if (!__mesh_write_uint16_hex(jnode, "vid", vid)) {
701 BT_INFO("Mesh: Could not write VID");
705 jobj = json_object_object_get(jnode, "features");
707 jobj = json_object_new_object();
708 json_object_object_add(jnode, "features", jobj);
711 BT_INFO("Mesh: Set features in CDB");
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);
718 BT_INFO("Mesh: All vendor Info data set successfully");
720 return __bt_mesh_save_configruation_file(cfg);
723 bool _bt_mesh_conf_set_unicast_address_range(_bt_mesh_cdb_t *cfg,
724 uint16_t low, uint16_t high)
726 if (!cfg || !cfg->jcfg)
729 if (!__mesh_write_uint16_hex(cfg->jcfg, "low", low))
732 if (!__mesh_write_uint16_hex(cfg->jcfg, "high", high))
735 return __bt_mesh_save_configruation_file(cfg);
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)
743 json_object *jelements, *jnodes, *jnetkeys, *jappkeys;
746 if (!cfg || !cfg->jcfg)
749 jnode = __mesh_get_node_by_uuid(cfg->jcfg, uuid);
751 BT_ERR("MESH:Node already exists");
755 jnode = json_object_new_object();
759 if (!__mesh_add_u8_16(jnode, "uuid", uuid))
762 jelements = json_object_new_array();
766 for (i = 0; i < num_els; ++i) {
767 json_object *jelement = json_object_new_object();
770 json_object_put(jelements);
774 __mesh_write_int(jelement, "elementIndex", i);
775 json_object_array_add(jelements, jelement);
778 json_object_object_add(jnode, "elements", jelements);
780 jnetkeys = json_object_new_array();
784 json_object_object_add(jnode, "netKeys", jnetkeys);
786 if (!__mesh_add_node_key(cfg, jnode, "netKeys", net_idx))
789 jappkeys = json_object_new_array();
793 json_object_object_add(jnode, "appKeys", jappkeys);
795 if (!__mesh_write_uint16_hex(jnode, "unicastAddress", unicast))
798 if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes))
801 json_object_array_add(jnodes, jnode);
803 if (!__bt_mesh_save_configruation_file(cfg))
809 json_object_put(jnode);
813 bool _bt_mesh_conf_insert_application_key(_bt_mesh_cdb_t *cfg,
814 uint16_t net_idx, uint16_t app_idx)
816 if (!cfg || !cfg->jcfg)
819 if (!__mesh_add_app_key(cfg->jcfg, net_idx, app_idx))
822 return __bt_mesh_save_configruation_file(cfg);
825 bool _bt_mesh_conf_insert_network_key(_bt_mesh_cdb_t *cfg,
826 uint16_t net_idx, uint8_t key_refresh)
828 json_object *jkey, *jarray;
830 if (!cfg || !cfg->jcfg)
833 json_object_object_get_ex(cfg->jcfg, "netKeys", &jarray);
834 if (!jarray || json_object_get_type(jarray) != json_type_array)
837 if (__mesh_get_key_object(jarray, net_idx))
840 jkey = json_object_new_object();
842 if (!__mesh_write_int(jkey, "index", net_idx))
845 if (!__mesh_write_int(jkey, "phase", key_refresh))
848 json_object_array_add(jarray, jkey);
850 return __bt_mesh_save_configruation_file(cfg);
853 json_object_put(jkey);
857 bool _bt_mesh_conf_delete_network_key(_bt_mesh_cdb_t *cfg,
860 if (!cfg || !cfg->jcfg)
863 return __mesh_delete_key(cfg, cfg->jcfg, "netKeys", net_idx);
867 bool _bt_mesh_conf_node_set_timetolive_value(_bt_mesh_cdb_t *cfg,
868 uint16_t unicast, uint8_t ttl)
872 if (!cfg || !cfg->jcfg)
875 jnode = __mesh_get_node_by_unicast(cfg, unicast);
879 if (!__mesh_write_int(jnode, "defaultTTL", ttl))
882 return __bt_mesh_save_configruation_file(cfg);
885 bool _bt_mesh_conf_node_insert_network_key(_bt_mesh_cdb_t *cfg,
886 uint16_t unicast, uint16_t net_idx)
890 if (!cfg || !cfg->jcfg)
893 jnode = __mesh_get_node_by_unicast(cfg, unicast);
897 return __mesh_add_node_key(cfg, jnode, "netKeys", net_idx);
900 bool _bt_mesh_conf_node_delete_network_key(_bt_mesh_cdb_t *cfg,
901 uint16_t unicast, uint16_t net_idx)
905 if (!cfg || !cfg->jcfg)
908 jnode = __mesh_get_node_by_unicast(cfg, unicast);
912 return __mesh_delete_key(cfg, jnode, "netKeys", net_idx);
915 bool _bt_mesh_conf_node_insert_application_key(_bt_mesh_cdb_t *cfg,
916 uint16_t unicast, uint16_t idx)
920 if (!cfg || !cfg->jcfg)
923 jnode = __mesh_get_node_by_unicast(cfg, unicast);
927 return __mesh_add_node_key(cfg, jnode, "appKeys", idx);
930 bool _bt_mesh_conf_node_delete_application_key(_bt_mesh_cdb_t *cfg,
931 uint16_t unicast, uint16_t idx)
935 if (!cfg || !cfg->jcfg)
938 jnode = __mesh_get_node_by_unicast(cfg, unicast);
942 return __mesh_delete_key(cfg, jnode, "appKeys", idx);
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)
951 json_object *jcfg, *jarray;
962 jcfg = json_object_new_object();
966 cfg = g_malloc0(sizeof(_bt_mesh_cdb_t));
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);
974 if (!__mesh_add_u8_8(jcfg, "Network_Token", token))
977 if (!__mesh_add_u8_16(jcfg, "Config_Node_UUID", uuid))
980 if (!__mesh_add_string(jcfg, "Network_Name", network_name))
983 if (!__mesh_add_string(jcfg, "Application_Credential", app_cred))
986 jarray = json_object_new_array();
990 json_object_object_add(jcfg, "nodes", jarray);
992 jarray = json_object_new_array();
996 json_object_object_add(jcfg, "netKeys", jarray);
998 jarray = json_object_new_array();
1002 json_object_object_add(jcfg, "appKeys", jarray);
1004 if (!__bt_mesh_save_configruation_file(cfg))
1010 _bt_mesh_conf_free(cfg);
1015 bool _bt_mesh_conf_delete_node(_bt_mesh_cdb_t *cfg, uint16_t unicast)
1017 json_object *jarray;
1020 if (!json_object_object_get_ex(cfg->jcfg, "nodes", &jarray))
1023 if (!jarray || json_object_get_type(jarray) != json_type_array)
1026 sz = json_object_array_length(jarray);
1028 for (i = 0; i < sz; ++i) {
1029 json_object *jentry, *jval;
1033 jentry = json_object_array_get_idx(jarray, i);
1034 if (!json_object_object_get_ex(jentry, "unicastAddress",
1038 str = json_object_get_string(jval);
1039 if (sscanf(str, "%04hx", &addr) != 1)
1042 if (addr == unicast)
1049 json_object_array_del_idx(jarray, i, 1);
1051 return __bt_mesh_save_configruation_file(cfg);
1054 uint16_t** _bt_mesh_conf_get_all_model_info(_bt_mesh_cdb_t *cfg,
1055 int element_index, int *num_models)
1061 json_object *jarray = NULL;
1062 json_object *jelement = NULL;
1063 json_object *jmodelarray = NULL;
1065 uint16_t **models = NULL;
1074 jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
1076 BT_ERR("Mesh: Node not found with UUID");
1080 /* Get element array object */
1081 json_object_object_get_ex(jnode, "elements", &jarray);
1083 if (!jarray || json_object_get_type(jarray) != json_type_array) {
1084 BT_ERR("Mesh:could not get element array");
1088 /* Get specific element by index */
1089 jelement = __mesh_get_key_object(jarray, element_index);
1091 BT_ERR("Mesh: Could not find element");
1095 /* Get Model array object inside the selected element */
1096 json_object_object_get_ex(jelement, "models", &jmodelarray);
1098 if (!jmodelarray || json_object_get_type(jmodelarray) != json_type_array) {
1099 BT_ERR("Mesh: Could not get Model Array");
1103 sz = json_object_array_length(jmodelarray);
1104 BT_INFO("Mesh: Total number of Models in Element index [%d] is [%d]",
1107 models = (uint16_t**) g_malloc0(sz * sizeof(uint16_t*));
1109 for (i = 0; i < sz; ++i) {
1110 json_object *jentry, *jval;
1113 BT_INFO("Mesh: Model [%d]", i);
1114 jentry = json_object_array_get_idx(jmodelarray, i);
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++)
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++)
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;
1139 /* TODO: Need to handle vendor models */
1140 BT_INFO("Mesh: Got all model info");
1145 bool _bt_mesh_conf_get_element_count(_bt_mesh_cdb_t *cfg,
1146 uint16_t *num_elems)
1151 json_object *jarray = NULL;
1160 jnode = __mesh_get_node_by_uuid(jcfg, cfg->uuid);
1162 BT_ERR("Mesh: Node by UUID not found");
1166 json_object_object_get_ex(jnode, "elements", &jarray);
1168 if (!jarray || json_object_get_type(jarray) != json_type_array) {
1169 BT_ERR("Mesh: Element array not found in Node");
1173 sz = json_object_array_length(jarray);
1175 BT_ERR("Mesh: Element array length is 0");
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)
1192 json_object *jobj = NULL;
1193 json_object *jobjfeature = NULL;
1202 jnode = __mesh_get_node_by_unicast(cfg, unicast);
1204 BT_ERR("Mesh: Node not found by unicast [0x%2.2x]", unicast);
1209 if (!json_object_object_get_ex(jnode, "crpl", &jobj)) {
1210 BT_ERR("Mesh: CRPL info not found");
1214 str = json_object_get_string(jobj);
1218 if (sscanf(str, "%04hx", crpl) != 1)
1221 BT_INFO("Mesh: Got CRPL[%s]", str);
1222 /* Get Company ID */
1223 if (!json_object_object_get_ex(jnode, "cid", &jobj))
1226 str = json_object_get_string(jobj);
1229 if (sscanf(str, "%04hx", cid) != 1)
1232 BT_INFO("Mesh: Got CID[%s]", str);
1234 if (!json_object_object_get_ex(jnode, "pid", &jobj))
1237 str = json_object_get_string(jobj);
1241 if (sscanf(str, "%04hx", vid) != 1)
1244 BT_INFO("Mesh: Got PID[%s]", str);
1245 /* Get Version ID */
1246 if (!json_object_object_get_ex(jnode, "vid", &jobj))
1249 str = json_object_get_string(jobj);
1252 if (sscanf(str, "%04hx", version) != 1)
1255 BT_INFO("Mesh: got version [%s]", str);
1256 jobj = json_object_object_get(jnode, "features");
1259 if (json_object_object_get_ex(jobj, "relay", &jobjfeature)) {
1260 str = json_object_get_string(jobjfeature);
1262 sscanf(str, "%d", relay);
1263 BT_INFO("Mesh: Got Relay [%s]", str);
1267 if (json_object_object_get_ex(jobj, "friend", &jobjfeature)) {
1268 str = json_object_get_string(jobjfeature);
1270 sscanf(str, "%d", friend);
1271 BT_INFO("Mesh: Got Friend [%s]", str);
1275 if (json_object_object_get_ex(jobj, "proxy", &jobjfeature)) {
1276 str = json_object_get_string(jobjfeature);
1278 sscanf(str, "%d", proxy);
1279 BT_INFO("Mesh: Got Proxy[%s]", str);
1282 if (json_object_object_get_ex(jobj, "lowPower", &jobjfeature)) {
1283 str = json_object_get_string(jobjfeature);
1285 sscanf(str, "%d", lpn);
1286 BT_INFO("Mesh: Got LPN[%s]", str);
1293 GSList *_bt_mesh_conf_load_group_info(_bt_mesh_cdb_t *cfg)
1295 json_object *jgroups;
1296 GSList *groups = NULL;
1299 if (!cfg || !cfg->jcfg)
1302 if (!json_object_object_get_ex(cfg->jcfg, "groups", &jgroups)) {
1303 jgroups = json_object_new_array();
1307 json_object_object_add(cfg->jcfg, "groups", jgroups);
1310 sz = json_object_array_length(jgroups);
1312 for (i = 0; i < sz; ++i) {
1313 json_object *jgroup, *jval;
1314 _bt_mesh_group_t *grp;
1315 uint16_t addr, addr_len;
1318 jgroup = json_object_array_get_idx(jgroups, i);
1322 if (!json_object_object_get_ex(jgroup, "name", &jval))
1325 str = json_object_get_string(jval);
1326 if (strlen(str) != 10)
1329 if (sscanf(str + 6, "%04hx", &addr) != 1)
1331 if (!json_object_object_get_ex(jgroup, "address", &jval))
1334 str = json_object_get_string(jval);
1335 addr_len = strlen(str);
1336 if (addr_len != 4 && addr_len != 32)
1339 if (addr_len == 32 && !MESH_IS_VIRTUAL(addr))
1342 grp = g_malloc0(sizeof(_bt_mesh_group_t));
1345 sscanf(str, "%04hx", &grp->grp_addr);
1347 _bt_mesh_util_convert_string_to_hex(str,
1348 32, grp->label_uuid, 16);
1349 grp->grp_addr = addr;
1352 groups = g_slist_append(groups, grp);
1358 bool _bt_mesh_conf_insert_group_info(_bt_mesh_cdb_t *cfg,
1359 _bt_mesh_group_t *grp)
1361 json_object *jgroup, *jgroups, *jval;
1364 if (!cfg || !cfg->jcfg)
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();
1373 json_object_object_add(cfg->jcfg, "groups", jgroups);
1376 jgroup = json_object_new_object();
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);
1384 if (MESH_IS_VIRTUAL(grp->grp_addr)) {
1385 if (!__mesh_add_u8_16(jgroup, "address", grp->label_uuid))
1388 if (!__mesh_write_uint16_hex(jgroup, "address", grp->grp_addr))
1392 json_object_array_add(jgroups, jgroup);
1394 return __bt_mesh_save_configruation_file(cfg);
1397 json_object_put(jgroup);
1401 bool _bt_mesh_conf_delete_group_entry(_bt_mesh_cdb_t *cfg, uint16_t addr)
1403 if (!cfg || !cfg->jcfg)
1406 return __mesh_delete_group(cfg, cfg->jcfg, "groups", addr);
1409 static json_object *__mesh_get_model_by_modelid(json_object *jelement,
1413 json_object *jval = NULL;
1414 json_object *jmodelarray = NULL;
1416 /* Get Model array object inside the selected element */
1417 json_object_object_get_ex(jelement, "models", &jmodelarray);
1419 if (!jmodelarray || json_object_get_type(jmodelarray) != json_type_array) {
1420 BT_ERR("Mesh: Could not get Model Array");
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);
1428 for (int i = 0; i < sz; ++i) {
1431 json_object *jentry = NULL;
1433 BT_INFO("Mesh: Model [%d]", i);
1434 jentry = json_object_array_get_idx(jmodelarray, i);
1436 if (!json_object_object_get_ex(jentry, "modelId", &jval)) {
1437 BT_ERR("Mesh: Failed to read Model in index [%d]", i);
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);
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");
1453 /* TODO: Need to handle vendor models */
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)
1461 json_object *jnode = NULL;
1462 json_object *jarray = NULL;
1463 json_object *jelement = NULL;
1464 json_object *jmodel = NULL;
1466 if (!cfg || !cfg->jcfg)
1469 /* Get specific node by unicast */
1470 jnode = __mesh_get_node_by_unicast(cfg, unicast);
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");
1481 /* Get specific element by index */
1482 jelement = __mesh_get_key_object(jarray, element_index);
1484 BT_ERR("Mesh: Could not find element");
1488 /* Get specific model by model-id */
1489 jmodel = __mesh_get_model_by_modelid(jelement, model_id);
1496 static json_object *__mesh_get_sub_group(json_object *jgroups, uint16_t group_addr)
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);
1502 for (int i = 0; i < sz; ++i) {
1503 uint16_t group_address;
1505 json_object *jentry = NULL;
1507 BT_INFO("Mesh: sub-addr [%d]", i);
1508 jentry = json_object_array_get_idx(jgroups, i);
1510 if (!json_object_object_get_ex(jentry, "sub-addr", &jval)) {
1511 BT_ERR("Mesh: Failed to read sub-addr in index [%d]", i);
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);
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");
1530 static bool __mesh_del_sub_group(json_object *jgroups, uint16_t group_addr)
1532 json_object *jval = NULL;
1534 int sz = json_object_array_length(jgroups);
1535 BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
1537 for (i = 0; i < sz; ++i) {
1538 uint16_t group_address;
1540 json_object *jentry = NULL;
1542 BT_INFO("Mesh: sub-addr [%d]", i);
1543 jentry = json_object_array_get_idx(jgroups, i);
1545 if (!json_object_object_get_ex(jentry, "sub-addr", &jval)) {
1546 BT_ERR("Mesh: Failed to read sub-addr in index [%d]", i);
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);
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");
1566 json_object_array_del_idx(jgroups, i, 1);
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)
1574 json_object *jmodel = NULL;
1575 json_object *jgroups = NULL;
1576 json_object *jgroup = NULL;
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);
1582 if (!cfg || !cfg->jcfg)
1585 /* Get model to be updated */
1586 jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
1587 element_index, model_id);
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();
1598 json_object_object_add(jmodel, "sub-addr", jgroups);
1601 jgroup = __mesh_get_sub_group(jgroups, group_addr);
1603 BT_DBG("sub-addr already present in list");
1607 /* Write group address */
1608 jgroup = json_object_new_object();
1612 if (!__mesh_write_uint16_hex(jgroup, "sub-addr", group_addr)) {
1613 json_object_put(jgroup);
1617 json_object_array_add(jgroups, jgroup);
1620 return __bt_mesh_save_configruation_file(cfg);
1623 bool _bt_mesh_conf_delete_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
1624 int element_index, uint32_t model_id, uint16_t group_addr)
1626 json_object *jmodel = NULL;
1627 json_object *jgroups = NULL;
1629 BT_INFO("Mesh: Set model config informations in the node [0x%2.2x] \
1630 element index [%d] model [0x%4.4x] group addr [0x%2.2x]",
1631 unicast, element_index, model_id, group_addr);
1633 if (!cfg || !cfg->jcfg)
1636 /* Get model to be updated */
1637 jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
1638 element_index, model_id);
1642 /* Delete group address */
1643 if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups))
1646 if (!__mesh_del_sub_group(jgroups, group_addr))
1650 return __bt_mesh_save_configruation_file(cfg);
1653 bool _bt_mesh_conf_delete_all_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
1654 int element_index, uint32_t model_id)
1656 json_object *jmodel = NULL;
1657 json_object *jgroups = NULL;
1660 BT_INFO("Mesh: Delete all model sub informations in the node [0x%2.2x] \
1661 element index [%d] model [0x%4.4x]",
1662 unicast, element_index, model_id);
1664 if (!cfg || !cfg->jcfg)
1667 /* Get model to be updated */
1668 jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
1669 element_index, model_id);
1673 /* Delete all group address */
1674 if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups))
1677 sz = json_object_array_length(jgroups);
1678 BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
1680 for (int i = sz - 1; i >= 0 ; --i)
1681 json_object_array_del_idx(jgroups, i, 1);
1684 return __bt_mesh_save_configruation_file(cfg);
1687 bool _bt_mesh_conf_overwrite_model_config_data(_bt_mesh_cdb_t *cfg, uint16_t unicast,
1688 int element_index, uint32_t model_id, uint16_t group_addr)
1690 json_object *jmodel = NULL;
1691 json_object *jgroups = NULL;
1692 json_object *jgroup = NULL;
1695 BT_INFO("Mesh: Set model config informations in the node [0x%2.2x] \
1696 element index [%d] model [0x%4.4x] group addr [0x%2.2x]",
1697 unicast, element_index, model_id, group_addr);
1699 if (!cfg || !cfg->jcfg)
1702 /* Get model to be updated */
1703 jmodel = __mesh_get_model_by_unicast_modelid(cfg, unicast,
1704 element_index, model_id);
1708 /* Find group array */
1709 if (!json_object_object_get_ex(jmodel, "sub-addr", &jgroups)) {
1710 BT_INFO("Mesh: Sub-addr group JSON object is not present: Create");
1711 jgroups = json_object_new_array();
1715 json_object_object_add(jmodel, "sub-addr", jgroups);
1717 /* Found group array: Delete all group address */
1718 sz = json_object_array_length(jgroups);
1719 BT_INFO("Mesh: Total sub-addr entry present is [%d]", sz);
1721 for (int i = sz - 1; i >= 0 ; --i) {
1722 BT_INFO("Mesh: Delete sub-addr entry [%d]", i);
1723 json_object_array_del_idx(jgroups, i, 1);
1727 /* Over-write new group address */
1728 jgroup = json_object_new_object();
1732 if (!__mesh_write_uint16_hex(jgroup, "sub-addr", group_addr)) {
1733 json_object_put(jgroup);
1737 json_object_array_add(jgroups, jgroup);
1740 return __bt_mesh_save_configruation_file(cfg);
1743 bool _bt_mesh_is_group_subscribed(_bt_mesh_cdb_t *cfg, uint16_t group_addr)
1745 json_object *jnodes;
1748 if (!cfg || !cfg->jcfg)
1751 json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes);
1752 if (!jnodes || json_object_get_type(jnodes) != json_type_array)
1755 sz = json_object_array_length(jnodes);
1757 for (i = 0; i < sz; ++i) {
1758 json_object *jnode, *jarray;
1762 jnode = json_object_array_get_idx(jnodes, i);
1766 if (!json_object_object_get_ex(jnode, "elements", &jarray))
1769 if (!jarray || json_object_get_type(jarray) != json_type_array)
1772 ele_cnt = json_object_array_length(jarray);
1774 for (j = 0; j < ele_cnt; ++j) {
1775 json_object *jentry, *jval, *jmods;
1779 jentry = json_object_array_get_idx(jarray, j);
1780 if (!json_object_object_get_ex(jentry, "index", &jval))
1783 index = json_object_get_int(jval);
1787 if (!json_object_object_get_ex(jentry, "models", &jmods))
1790 mod_cnt = json_object_array_length(jmods);
1791 BT_INFO("Mesh: Total Model count in element Index [%d] is [%d]",
1794 for (k = 0; k < mod_cnt; ++k) {
1796 json_object *jgroups, *jgroup;
1798 jmod = json_object_array_get_idx(jmods, k);
1800 if (!json_object_object_get_ex(jmod, "sub-addr", &jgroups))
1803 /* Find existing sub-addr group */
1804 jgroup = __mesh_get_sub_group(jgroups, group_addr);
1806 BT_DBG("sub-addr present in list");
1815 bool _bt_mesh_conf_set_network_friendly_name(_bt_mesh_cdb_t *cfg,
1816 const char *network_name)
1827 json_object_object_del(jcfg, "Network_Name");
1828 __mesh_add_string(jcfg, "Network_Name", network_name);
1831 BT_INFO("Mesh: CDB: Network New Name [%s]", network_name);
1832 return __bt_mesh_save_configruation_file(cfg);
1835 const char * _bt_mesh_conf_get_network_friendly_name(_bt_mesh_cdb_t *cfg)
1838 json_object *jobj = NULL;
1848 /* Get Network Name */
1849 if (!json_object_object_get_ex(jcfg, "Network_Name", &jobj))
1852 str = json_object_get_string(jobj);
1856 BT_INFO("Mesh: CDB: Network Name [%s]", str);
1860 static bool __mesh_load_composition(_bt_mesh_cdb_t *cfg,
1861 json_object *jnode, uint16_t unicast)
1863 json_object *jarray;
1866 if (!json_object_object_get_ex(jnode, "elements", &jarray))
1869 if (json_object_get_type(jarray) != json_type_array)
1872 ele_cnt = json_object_array_length(jarray);
1874 for (i = 0; i < ele_cnt; ++i) {
1875 json_object *jentry, *jval, *jmods;
1879 jentry = json_object_array_get_idx(jarray, i);
1880 if (!json_object_object_get_ex(jentry, "index", &jval))
1883 index = json_object_get_int(jval);
1887 if (!json_object_object_get_ex(jentry, "models", &jmods))
1890 mod_cnt = json_object_array_length(jmods);
1891 BT_INFO("Mesh: Total Model count in element Index [%d] is [%d]",
1894 for (k = 0; k < mod_cnt; ++k) {
1895 json_object *jmod, *jid;
1896 uint32_t mod_id, len;
1899 jmod = json_object_array_get_idx(jmods, k);
1900 if (!json_object_object_get_ex(jmod, "modelId", &jid))
1903 str = json_object_get_string(jid);
1906 if (len != 4 && len != 8)
1909 if ((len == 4) && (sscanf(str, "%04x", &mod_id) != 1))
1912 if ((len == 8) && (sscanf(str, "%08x", &mod_id) != 1))
1915 _bt_mesh_node_set_model(cfg->uuid,
1916 unicast, index, mod_id, len == 8);
1923 bool _bt_mesh_conf_set_node_comp_data(_bt_mesh_cdb_t *cfg,
1924 uint16_t unicast, uint8_t *data, uint16_t len)
1928 json_object *jnode, *jobj, *jelements;
1931 if (!cfg || !cfg->jcfg)
1934 jnode = __mesh_get_node_by_unicast(cfg, unicast);
1938 /* skip page -- We only support Page Zero */
1942 /* If "crpl" property is present, composition is already recorded */
1943 if (json_object_object_get_ex(jnode, "crpl", &jobj))
1946 if (!__mesh_write_uint16_hex(jnode, "cid", l_get_le16(&data[0])))
1949 if (!__mesh_write_uint16_hex(jnode, "pid", l_get_le16(&data[2])))
1952 if (!__mesh_write_uint16_hex(jnode, "vid", l_get_le16(&data[4])))
1955 crpl = l_get_le16(&data[6]);
1957 features = l_get_le16(&data[8]);
1961 jobj = json_object_object_get(jnode, "features");
1963 jobj = json_object_new_object();
1964 json_object_object_add(jnode, "features", jobj);
1967 if ((features & MESH_FEATURE_RELAY))
1968 __mesh_write_int(jobj, "relay", 1);
1970 __mesh_write_int(jobj, "relay", 0);
1972 if ((features & MESH_FEATURE_FRIEND))
1973 __mesh_write_int(jobj, "friend", 1);
1975 __mesh_write_int(jobj, "friend", 0);
1977 if ((features & MESH_FEATURE_PROXY))
1978 __mesh_write_int(jobj, "proxy", 1);
1980 __mesh_write_int(jobj, "proxy", 0);
1982 if ((features & MESH_FEATURE_LPN))
1983 __mesh_write_int(jobj, "lowPower", 1);
1985 __mesh_write_int(jobj, "lowPower", 0);
1987 jelements = json_object_object_get(jnode, "elements");
1991 sz = json_object_array_length(jelements);
1994 json_object *jentry, *jmods;
1998 /* Mismatch in the element count */
2002 jentry = json_object_array_get_idx(jelements, i);
2004 __mesh_write_int(jentry, "index", i);
2006 if (!__mesh_write_uint16_hex(jentry, "location", l_get_le16(data)))
2016 jmods = json_object_object_get(jentry, "models");
2018 /* For backwards compatibility */
2019 jmods = json_object_new_array();
2020 json_object_object_add(jentry, "models", jmods);
2023 while (len >= 2 && m--) {
2024 mod_id = l_get_le16(data);
2026 jobj = __mesh_init_model(mod_id);
2030 json_object_array_add(jmods, jobj);
2035 while (len >= 4 && v--) {
2036 mod_id = l_get_le16(data + 2);
2037 mod_id = l_get_le16(data) << 16 | mod_id;
2039 jobj = __mesh_init_vendor_model(mod_id);
2043 json_object_array_add(jmods, jobj);
2052 /* CRPL is written last. Will be used to check composition's presence */
2053 if (!__mesh_write_uint16_hex(jnode, "crpl", crpl))
2056 /* Initiate remote's composition from storage */
2057 if (!__mesh_load_composition(cfg, jnode, unicast))
2060 return __bt_mesh_save_configruation_file(cfg);
2063 /* Reset elements array */
2064 json_object_object_del(jnode, "elements");
2065 jelements = __mesh_init_elements(sz);
2068 json_object_object_add(jnode, "elements", jelements);
2069 __bt_mesh_save_configruation_file(cfg);
2074 _bt_mesh_cdb_t* _bt_mesh_conf_load(const char *file_name,
2083 _bt_mesh_cdb_t *cfg;
2085 fd = open(file_name, O_RDONLY);
2087 BT_ERR("Mesh: Could not open file [%s]",
2092 if (fstat(fd, &st) == -1) {
2094 BT_ERR("Mesh: Could not stat file [%s]",
2099 str = (char *) g_malloc0(st.st_size + 1);
2102 BT_ERR("Mesh: Could not stat file [%s]",
2107 sz = read(fd, str, st.st_size);
2108 if (sz != st.st_size) {
2109 BT_ERR("Mesh: Failed to read configuration file [%s]", file_name);
2115 jcfg = json_tokener_parse(str);
2122 cfg = g_malloc0(sizeof(_bt_mesh_cdb_t));
2125 cfg->cfg_fname = g_strdup(file_name);
2127 if (!__mesh_get_uuid(jcfg, cfg->uuid)) {
2128 BT_ERR("Mesh: Configuration file missing UUID");
2132 if (!__mesh_get_token(jcfg, cfg->token)) {
2133 BT_ERR("Mesh: Configuration file missing token");
2137 _bt_mesh_util_convert_hex_to_string(cfg->token, 8, token_str, 17);
2139 /* Match CDB file tken with user's token */
2140 if (g_strcmp0(token_str, token)) {
2141 BT_INFO("Mesh: Token did not match! File token [%s] requested token [%s]",
2146 BT_INFO("Mesh: Token found");
2147 /* TODO: Load keys and remotes */
2150 _bt_mesh_conf_free(cfg);
2154 bool _bt_mesh_conf_load_all_nodes(_bt_mesh_cdb_t *cfg)
2156 json_object *jnodes;
2157 int i, sz, node_count = 0;
2159 json_object_object_get_ex(cfg->jcfg, "nodes", &jnodes);
2160 if (!jnodes || json_object_get_type(jnodes) != json_type_array)
2163 sz = json_object_array_length(jnodes);
2165 for (i = 0; i < sz; ++i) {
2166 json_object *jnode, *jval, *jarray;
2168 uint16_t unicast, key_idx;
2170 int ele_cnt, key_cnt;
2173 jnode = json_object_array_get_idx(jnodes, i);
2177 if (!json_object_object_get_ex(jnode, "uuid", &jval))
2180 str = json_object_get_string(jval);
2181 if (strlen(str) != 32)
2184 _bt_mesh_util_convert_string_to_hex(str, 32, uuid, 16);
2186 if (!json_object_object_get_ex(jnode, "unicastAddress", &jval))
2189 str = json_object_get_string(jval);
2190 if (sscanf(str, "%04hx", &unicast) != 1)
2193 json_object_object_get_ex(jnode, "elements", &jarray);
2194 if (!jarray || json_object_get_type(jarray) != json_type_array)
2197 ele_cnt = json_object_array_length(jarray);
2199 if (ele_cnt > MESH_MAX_ELE_COUNT)
2202 json_object_object_get_ex(jnode, "netKeys", &jarray);
2203 if (!jarray || json_object_get_type(jarray) != json_type_array)
2206 key_cnt = json_object_array_length(jarray);
2210 key_idx = __mesh_node_parse_key(jarray, 0);
2211 if (key_idx == MESH_KEY_IDX_INVALID)
2214 _bt_mesh_node_add_node(cfg->uuid, (const uint8_t *)uuid, unicast, ele_cnt,
2216 for (j = 1; j < key_cnt; j++) {
2217 key_idx = __mesh_node_parse_key(jarray, j);
2219 if (key_idx != MESH_KEY_IDX_INVALID)
2220 _bt_mesh_node_add_net_key(cfg->uuid, unicast, key_idx);
2223 json_object_object_get_ex(jnode, "appKeys", &jarray);
2224 if (!jarray || json_object_get_type(jarray) != json_type_array)
2227 key_cnt = json_object_array_length(jarray);
2228 for (j = 0; j < key_cnt; j++) {
2229 key_idx = __mesh_node_parse_key(jarray, j);
2231 if (key_idx != MESH_KEY_IDX_INVALID)
2232 _bt_mesh_node_add_app_key(cfg->uuid, unicast, key_idx);
2235 __mesh_load_composition(cfg, jnode, unicast);
2239 /* TODO: Add the rest of the configuration */
2242 if (node_count != sz)
2243 BT_ERR("Mesh: CDB: The remote node configuration load is incomplete!");
2248 bool _bt_mesh_conf_load_all_keys(_bt_mesh_cdb_t* cfg)
2250 json_object *jarray, *jentry;
2251 int net_idx, app_idx;
2253 json_object *jobj = cfg->jcfg;
2255 json_object_object_get_ex(jobj, "netKeys", &jarray);
2256 if (!jarray || json_object_get_type(jarray) != json_type_array)
2259 key_cnt = json_object_array_length(jarray);
2263 for (i = 0; i < key_cnt; ++i) {
2266 jentry = json_object_array_get_idx(jarray, i);
2268 if (!__mesh_get_int(jentry, "index", &net_idx))
2271 _bt_mesh_keys_add_net_key(cfg->uuid, (uint16_t) net_idx);
2273 if (!__mesh_get_int(jentry, "phase", &phase))
2276 _bt_mesh_keys_set_net_key_phase(cfg, net_idx, (uint8_t) phase, false);
2279 json_object_object_get_ex(jobj, "appKeys", &jarray);
2280 if (!jarray || json_object_get_type(jarray) != json_type_array)
2283 key_cnt = json_object_array_length(jarray);
2287 for (i = 0; i < key_cnt; ++i) {
2289 jentry = json_object_array_get_idx(jarray, i);
2290 if (!__mesh_get_int(jentry, "boundNetKey", &net_idx))
2293 if (!__mesh_get_int(jentry, "index", &app_idx))
2296 _bt_mesh_keys_add_app_key(cfg->uuid, (uint16_t) net_idx, (uint16_t) app_idx);