3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2018-2019 Intel Corporation. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
24 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
32 #include <json-c/json.h>
34 #include "mesh/mesh-defs.h"
35 #include "mesh/util.h"
36 #include "mesh/mesh-config.h"
38 #define CHECK_KEY_IDX_RANGE(x) (((x) >= 0) && ((x) <= 4095))
40 static bool get_int(json_object *jobj, const char *keyword, int *value)
44 if (!json_object_object_get_ex(jobj, keyword, &jvalue))
47 *value = json_object_get_int(jvalue);
54 static bool add_u64_value(json_object *jobject, const char *desc,
60 hex2str((uint8_t *) u64, 8, hexstr, 17);
61 jstring = json_object_new_string(hexstr);
65 json_object_object_add(jobject, desc, jstring);
69 static bool add_key_value(json_object *jobject, const char *desc,
70 const uint8_t key[16])
75 hex2str((uint8_t *) key, 16, hexstr, 33);
76 jstring = json_object_new_string(hexstr);
80 json_object_object_add(jobject, desc, jstring);
84 static int get_element_index(json_object *jnode, uint16_t ele_addr)
86 json_object *jvalue, *jelements;
87 uint16_t addr, num_ele;
90 if (!json_object_object_get_ex(jnode, "unicastAddress", &jvalue))
93 str = (char *)json_object_get_string(jvalue);
94 if (sscanf(str, "%04hx", &addr) != 1)
97 if (!json_object_object_get_ex(jnode, "elements", &jelements))
100 num_ele = json_object_array_length(jelements);
102 if (ele_addr >= addr + num_ele || ele_addr < addr)
105 return ele_addr - addr;
108 static json_object *get_element_model(json_object *jnode, int ele_idx,
109 uint32_t mod_id, bool vendor)
111 json_object *jelements, *jelement, *jmodels;
117 snprintf(buf, 5, "%4.4x", (uint16_t)mod_id);
119 snprintf(buf, 9, "%8.8x", mod_id);
121 if (!json_object_object_get_ex(jnode, "elements", &jelements))
124 jelement = json_object_array_get_idx(jelements, ele_idx);
128 if (!json_object_object_get_ex(jelement, "models", &jmodels))
131 num_mods = json_object_array_length(jmodels);
136 snprintf(buf, 5, "%4.4x", mod_id);
139 snprintf(buf, 9, "%8.8x", mod_id);
143 for (i = 0; i < num_mods; ++i) {
144 json_object *jmodel, *jvalue;
147 jmodel = json_object_array_get_idx(jmodels, i);
148 if (!json_object_object_get_ex(jmodel, "modelId", &jvalue))
151 str = (char *)json_object_get_string(jvalue);
155 if (!strncmp(str, buf, len))
162 static bool jarray_has_string(json_object *jarray, char *str, size_t len)
164 int i, sz = json_object_array_length(jarray);
166 for (i = 0; i < sz; ++i) {
170 jentry = json_object_array_get_idx(jarray, i);
171 str_entry = (char *)json_object_get_string(jentry);
175 if (!strncmp(str, str_entry, len))
182 static json_object *jarray_string_del(json_object *jarray, char *str,
185 int i, sz = json_object_array_length(jarray);
186 json_object *jarray_new;
188 jarray_new = json_object_new_array();
192 for (i = 0; i < sz; ++i) {
196 jentry = json_object_array_get_idx(jarray, i);
197 str_entry = (char *)json_object_get_string(jentry);
198 if (str_entry && !strncmp(str, str_entry, len))
201 json_object_get(jentry);
202 json_object_array_add(jarray_new, jentry);
208 static json_object *get_key_object(json_object *jarray, uint16_t idx)
210 int i, sz = json_object_array_length(jarray);
212 for (i = 0; i < sz; ++i) {
213 json_object *jentry, *jvalue;
216 jentry = json_object_array_get_idx(jarray, i);
217 if (!json_object_object_get_ex(jentry, "index", &jvalue))
220 jidx = json_object_get_int(jvalue);
229 static json_object *jarray_key_del(json_object *jarray, int16_t idx)
231 json_object *jarray_new;
232 int i, sz = json_object_array_length(jarray);
234 jarray_new = json_object_new_array();
238 for (i = 0; i < sz; ++i) {
239 json_object *jentry, *jvalue;
241 jentry = json_object_array_get_idx(jarray, i);
243 if (json_object_object_get_ex(jentry, "index", &jvalue)) {
244 int tmp = json_object_get_int(jvalue);
250 json_object_get(jentry);
251 json_object_array_add(jarray_new, jentry);
257 bool mesh_db_read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
262 if (!get_int(jobj, "IVindex", &tmp))
265 *idx = (uint32_t) tmp;
267 if (!get_int(jobj, "IVupdate", &tmp))
270 *update = tmp ? true : false;
275 bool mesh_db_read_token(json_object *jobj, uint8_t token[8])
283 if (!json_object_object_get_ex(jobj, "token", &jvalue))
286 str = (char *)json_object_get_string(jvalue);
287 if (!str2hex(str, strlen(str), token, 8))
293 bool mesh_db_read_device_key(json_object *jobj, uint8_t key_buf[16])
301 if (!json_object_object_get_ex(jobj, "deviceKey", &jvalue))
304 str = (char *)json_object_get_string(jvalue);
305 if (!str2hex(str, strlen(str), key_buf, 16))
311 bool mesh_db_read_app_keys(json_object *jobj, mesh_db_app_key_cb cb,
321 if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
324 if (json_object_get_type(jarray) != json_type_array)
327 len = json_object_array_length(jarray);
329 for (i = 0; i < len; ++i) {
330 json_object *jtemp, *jvalue;
331 int app_idx, net_idx;
332 bool key_refresh = false;
337 jtemp = json_object_array_get_idx(jarray, i);
339 if (!get_int(jtemp, "index", &app_idx))
342 if (!CHECK_KEY_IDX_RANGE(app_idx))
345 if (!get_int(jtemp, "boundNetKey", &net_idx))
348 if (!CHECK_KEY_IDX_RANGE(net_idx))
351 if (json_object_object_get_ex(jtemp, "oldKey", &jvalue)) {
352 str = (char *)json_object_get_string(jvalue);
353 if (!str2hex(str, strlen(str), key, 16))
358 if (!json_object_object_get_ex(jtemp, "key", &jvalue))
361 str = (char *)json_object_get_string(jvalue);
362 if (!str2hex(str, strlen(str), key_refresh ? new_key : key, 16))
365 if (!cb((uint16_t)net_idx, (uint16_t) app_idx, key,
366 key_refresh ? new_key : NULL, user_data))
373 bool mesh_db_read_net_keys(json_object *jobj, mesh_db_net_key_cb cb,
383 if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
386 if (json_object_get_type(jarray) != json_type_array)
389 len = json_object_array_length(jarray);
391 for (i = 0; i < len; ++i) {
392 json_object *jtemp, *jvalue;
395 bool key_refresh = false;
400 jtemp = json_object_array_get_idx(jarray, i);
402 if (!get_int(jtemp, "index", &idx))
405 if (!CHECK_KEY_IDX_RANGE(idx))
408 if (json_object_object_get_ex(jtemp, "oldKey", &jvalue)) {
409 str = (char *)json_object_get_string(jvalue);
410 if (!str2hex(str, strlen(str), key, 16))
415 if (!json_object_object_get_ex(jtemp, "key", &jvalue))
418 str = (char *)json_object_get_string(jvalue);
419 if (!str2hex(str, strlen(str), key_refresh ? new_key : key, 16))
422 if (!json_object_object_get_ex(jtemp, "keyRefresh", &jvalue))
423 phase = KEY_REFRESH_PHASE_NONE;
425 phase = json_object_get_int(jvalue);
428 if (!cb((uint16_t)idx, key, key_refresh ? new_key : NULL, phase,
436 bool mesh_db_net_key_add(json_object *jobj, uint16_t idx,
437 const uint8_t key[16])
439 json_object *jarray = NULL, *jentry = NULL, *jstring;
442 json_object_object_get_ex(jobj, "netKeys", &jarray);
444 jentry = get_key_object(jarray, idx);
446 /* Do not allow direct overwrite */
450 jentry = json_object_new_object();
454 snprintf(buf, 5, "%4.4x", idx);
455 jstring = json_object_new_string(buf);
459 json_object_object_add(jentry, "index", jstring);
461 if (!add_key_value(jentry, "key", key))
464 json_object_object_add(jentry, "keyRefresh",
465 json_object_new_int(KEY_REFRESH_PHASE_NONE));
468 jarray = json_object_new_array();
471 json_object_object_add(jobj, "netKeys", jarray);
474 json_object_array_add(jarray, jentry);
479 json_object_put(jentry);
484 bool mesh_db_net_key_update(json_object *jobj, uint16_t idx,
485 const uint8_t key[16])
487 json_object *jarray, *jentry, *jstring;
490 if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
493 jentry = get_key_object(jarray, idx);
494 /* Net key must be already recorded */
498 if (!json_object_object_get_ex(jentry, "key", &jstring))
501 str = json_object_get_string(jstring);
502 jstring = json_object_new_string(str);
503 json_object_object_add(jentry, "oldKey", jstring);
504 json_object_object_del(jentry, "key");
506 if (!add_key_value(jentry, "key", key))
509 json_object_object_add(jentry, "keyRefresh",
510 json_object_new_int(KEY_REFRESH_PHASE_ONE));
515 bool mesh_db_net_key_del(json_object *jobj, uint16_t idx)
517 json_object *jarray, *jarray_new;
519 if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
522 /* Check if matching entry exists */
523 if (!get_key_object(jarray, idx))
526 if (json_object_array_length(jarray) == 1) {
527 json_object_object_del(jobj, "netKeys");
532 * There is no easy way to delete a value from json array.
533 * Create a new copy without specified element and
534 * then remove old array.
536 jarray_new = jarray_key_del(jarray, idx);
540 json_object_object_del(jobj, "netKeys");
541 json_object_object_add(jobj, "netKeys", jarray_new);
546 bool mesh_db_write_device_key(json_object *jnode, uint8_t *key)
548 return add_key_value(jnode, "deviceKey", key);
551 bool mesh_db_write_token(json_object *jnode, uint8_t *token)
553 return add_u64_value(jnode, "token", token);
556 bool mesh_db_app_key_add(json_object *jobj, uint16_t net_idx, uint16_t app_idx,
557 const uint8_t key[16])
559 json_object *jarray = NULL, *jentry = NULL, *jstring = NULL;
562 json_object_object_get_ex(jobj, "appKeys", &jarray);
564 jentry = get_key_object(jarray, app_idx);
566 /* Do not allow direct overrwrite */
570 jentry = json_object_new_object();
574 snprintf(buf, 5, "%4.4x", app_idx);
575 jstring = json_object_new_string(buf);
579 json_object_object_add(jentry, "index", jstring);
581 snprintf(buf, 5, "%4.4x", net_idx);
582 jstring = json_object_new_string(buf);
586 json_object_object_add(jentry, "boundNetKey", jstring);
588 if (!add_key_value(jentry, "key", key))
592 jarray = json_object_new_array();
595 json_object_object_add(jobj, "appKeys", jarray);
598 json_object_array_add(jarray, jentry);
604 json_object_put(jentry);
609 bool mesh_db_app_key_update(json_object *jobj, uint16_t app_idx,
610 const uint8_t key[16])
612 json_object *jarray, *jentry = NULL, *jstring = NULL;
615 if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
618 /* The key entry should exist if the key is updated */
619 jentry = get_key_object(jarray, app_idx);
623 if (!json_object_object_get_ex(jentry, "key", &jstring))
626 str = json_object_get_string(jstring);
627 jstring = json_object_new_string(str);
628 json_object_object_add(jentry, "oldKey", jstring);
629 json_object_object_del(jentry, "key");
631 return add_key_value(jentry, "key", key);
634 bool mesh_db_app_key_del(json_object *jobj, uint16_t net_idx, uint16_t idx)
636 json_object *jarray, *jarray_new;
638 if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
641 /* Check if matching entry exists */
642 if (!get_key_object(jarray, idx))
645 if (json_object_array_length(jarray) == 1) {
646 json_object_object_del(jobj, "appKeys");
651 * There is no easy way to delete a value from json array.
652 * Create a new copy without specified element and
653 * then remove old array.
655 jarray_new = jarray_key_del(jarray, idx);
659 json_object_object_del(jobj, "appKeys");
660 json_object_object_add(jobj, "appKeys", jarray_new);
665 bool mesh_db_model_binding_add(json_object *jnode, uint8_t ele_idx, bool vendor,
666 uint32_t mod_id, uint16_t app_idx)
668 json_object *jmodel, *jstring, *jarray = NULL;
671 jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
675 snprintf(buf, 5, "%4.4x", app_idx);
677 json_object_object_get_ex(jmodel, "bind", &jarray);
678 if (jarray && jarray_has_string(jarray, buf, 4))
681 jstring = json_object_new_string(buf);
686 jarray = json_object_new_array();
688 json_object_put(jstring);
691 json_object_object_add(jmodel, "bind", jarray);
694 json_object_array_add(jarray, jstring);
699 bool mesh_db_model_binding_del(json_object *jnode, uint8_t ele_idx, bool vendor,
700 uint32_t mod_id, uint16_t app_idx)
702 json_object *jmodel, *jarray, *jarray_new;
705 jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
709 if (!json_object_object_get_ex(jmodel, "bind", &jarray))
712 snprintf(buf, 5, "%4.4x", app_idx);
714 if (!jarray_has_string(jarray, buf, 4))
717 if (json_object_array_length(jarray) == 1) {
718 json_object_object_del(jmodel, "bind");
723 * There is no easy way to delete a value from json array.
724 * Create a new copy without specified element and
725 * then remove old array.
727 jarray_new = jarray_string_del(jarray, buf, 4);
731 json_object_object_del(jmodel, "bind");
732 json_object_object_add(jmodel, "bind", jarray_new);
737 static void free_model(void *data)
739 struct mesh_db_model *mod = data;
741 l_free(mod->bindings);
747 static void free_element(void *data)
749 struct mesh_db_element *ele = data;
751 l_queue_destroy(ele->models, free_model);
755 static bool parse_bindings(json_object *jbindings, struct mesh_db_model *mod)
760 cnt = json_object_array_length(jbindings);
764 mod->num_bindings = cnt;
766 /* Allow empty bindings list */
770 mod->bindings = l_new(uint16_t, cnt);
772 for (i = 0; i < cnt; ++i) {
776 jvalue = json_object_array_get_idx(jbindings, i);
780 idx = json_object_get_int(jvalue);
781 if (!CHECK_KEY_IDX_RANGE(idx))
784 mod->bindings[i] = (uint16_t) idx;
790 static bool get_key_index(json_object *jobj, const char *keyword,
795 if (!get_int(jobj, keyword, &idx))
798 if (!CHECK_KEY_IDX_RANGE(idx))
801 *index = (uint16_t) idx;
805 static struct mesh_db_pub *parse_model_publication(json_object *jpub)
808 struct mesh_db_pub *pub;
812 if (!json_object_object_get_ex(jpub, "address", &jvalue))
815 str = (char *)json_object_get_string(jvalue);
817 pub = l_new(struct mesh_db_pub, 1);
821 if (sscanf(str, "%04hx", &pub->addr) != 1)
825 if (!str2hex(str, len, pub->virt_addr, 16))
833 if (!get_key_index(jpub, "index", &pub->idx))
836 if (!get_int(jpub, "ttl", &value))
838 pub->ttl = (uint8_t) value;
840 if (!get_int(jpub, "period", &value))
844 if (!get_int(jpub, "credentials", &value))
846 pub->credential = (uint8_t) value;
848 if (!json_object_object_get_ex(jpub, "retransmit", &jvalue))
851 if (!get_int(jvalue, "count", &value))
853 pub->count = (uint8_t) value;
855 if (!get_int(jvalue, "interval", &value))
857 pub->interval = (uint8_t) value;
866 static bool parse_model_subscriptions(json_object *jsubs,
867 struct mesh_db_model *mod)
869 struct mesh_db_sub *subs;
872 if (json_object_get_type(jsubs) != json_type_array)
875 cnt = json_object_array_length(jsubs);
876 /* Allow empty array */
880 subs = l_new(struct mesh_db_sub, cnt);
882 for (i = 0; i < cnt; ++i) {
887 jvalue = json_object_array_get_idx(jsubs, i);
891 str = (char *)json_object_get_string(jvalue);
896 if (sscanf(str, "%04hx", &subs[i].src.addr) != 1)
900 if (!str2hex(str, len, subs[i].src.virt_addr, 16))
918 static bool parse_models(json_object *jmodels, struct mesh_db_element *ele)
922 num_models = json_object_array_length(jmodels);
926 for (i = 0; i < num_models; ++i) {
927 json_object *jmodel, *jarray, *jvalue;
928 struct mesh_db_model *mod;
933 jmodel = json_object_array_get_idx(jmodels, i);
937 mod = l_new(struct mesh_db_model, 1);
939 if (!json_object_object_get_ex(jmodel, "modelId", &jvalue))
942 str = (char *)json_object_get_string(jvalue);
946 if (len != 4 && len != 8)
950 if (sscanf(str, "%04x", &id) != 1)
953 id |= VENDOR_ID_MASK;
954 } else if (len == 8) {
955 if (sscanf(str, "%08x", &id) != 1)
965 if (json_object_object_get_ex(jmodel, "bind", &jarray)) {
966 if (json_object_get_type(jarray) != json_type_array ||
967 !parse_bindings(jarray, mod))
971 if (json_object_object_get_ex(jmodel, "publish", &jvalue)) {
972 mod->pub = parse_model_publication(jvalue);
977 if (json_object_object_get_ex(jmodel, "subscribe", &jarray)) {
978 if (!parse_model_subscriptions(jarray, mod))
982 l_queue_push_tail(ele->models, mod);
988 l_queue_destroy(ele->models, free_model);
992 static bool parse_elements(json_object *jelements, struct mesh_db_node *node)
996 if (json_object_get_type(jelements) != json_type_array)
999 num_ele = json_object_array_length(jelements);
1001 /* Allow "empty" nodes */
1004 node->elements = l_queue_new();
1006 for (i = 0; i < num_ele; ++i) {
1007 json_object *jelement;
1008 json_object *jmodels;
1009 json_object *jvalue;
1010 struct mesh_db_element *ele;
1014 jelement = json_object_array_get_idx(jelements, i);
1018 if (!get_int(jelement, "elementIndex", &index) ||
1022 ele = l_new(struct mesh_db_element, 1);
1024 ele->models = l_queue_new();
1026 if (!json_object_object_get_ex(jelement, "location", &jvalue))
1029 str = (char *)json_object_get_string(jvalue);
1030 if (sscanf(str, "%04hx", &(ele->location)) != 1)
1033 if (json_object_object_get_ex(jelement, "models", &jmodels)) {
1034 if (json_object_get_type(jmodels) != json_type_array ||
1035 !parse_models(jmodels, ele))
1039 l_queue_push_tail(node->elements, ele);
1045 l_queue_destroy(node->elements, free_element);
1046 node->elements = NULL;
1051 static int get_mode(json_object *jvalue)
1055 str = json_object_get_string(jvalue);
1059 if (!strncasecmp(str, "disabled", strlen("disabled")))
1060 return MESH_MODE_DISABLED;
1062 if (!strncasecmp(str, "enabled", strlen("enabled")))
1063 return MESH_MODE_ENABLED;
1065 if (!strncasecmp(str, "unsupported", strlen("unsupported")))
1066 return MESH_MODE_UNSUPPORTED;
1071 static void parse_features(json_object *jconfig, struct mesh_db_node *node)
1073 json_object *jvalue, *jrelay;
1077 if (json_object_object_get_ex(jconfig, "proxy", &jvalue)) {
1078 mode = get_mode(jvalue);
1079 if (mode <= MESH_MODE_UNSUPPORTED)
1080 node->modes.proxy = mode;
1083 if (json_object_object_get_ex(jconfig, "friend", &jvalue)) {
1084 mode = get_mode(jvalue);
1085 if (mode <= MESH_MODE_UNSUPPORTED)
1086 node->modes.friend = mode;
1089 if (json_object_object_get_ex(jconfig, "lowPower", &jvalue)) {
1090 mode = get_mode(jvalue);
1091 if (mode <= MESH_MODE_UNSUPPORTED)
1092 node->modes.friend = mode;
1095 if (json_object_object_get_ex(jconfig, "beacon", &jvalue)) {
1096 mode = get_mode(jvalue);
1097 if (mode <= MESH_MODE_UNSUPPORTED)
1098 node->modes.beacon = mode;
1101 if (!json_object_object_get_ex(jconfig, "relay", &jrelay))
1104 if (json_object_object_get_ex(jrelay, "mode", &jvalue)) {
1105 mode = get_mode(jvalue);
1106 if (mode <= MESH_MODE_UNSUPPORTED)
1107 node->modes.relay.state = mode;
1113 if (!json_object_object_get_ex(jrelay, "count", &jvalue))
1116 /* TODO: check range */
1117 count = json_object_get_int(jvalue);
1118 node->modes.relay.cnt = count;
1120 if (!json_object_object_get_ex(jrelay, "interval", &jvalue))
1123 /* TODO: check range */
1124 interval = json_object_get_int(jvalue);
1125 node->modes.relay.interval = interval;
1128 static bool parse_composition(json_object *jcomp, struct mesh_db_node *node)
1130 json_object *jvalue;
1133 /* All the fields in node composition are mandatory */
1134 if (!json_object_object_get_ex(jcomp, "cid", &jvalue))
1137 str = (char *)json_object_get_string(jvalue);
1138 if (sscanf(str, "%04hx", &node->cid) != 1)
1141 if (!json_object_object_get_ex(jcomp, "pid", &jvalue))
1144 str = (char *)json_object_get_string(jvalue);
1145 if (sscanf(str, "%04hx", &node->pid) != 1)
1148 if (!json_object_object_get_ex(jcomp, "vid", &jvalue))
1151 str = (char *)json_object_get_string(jvalue);
1152 if (sscanf(str, "%04hx", &node->vid) != 1)
1155 if (!json_object_object_get_ex(jcomp, "crpl", &jvalue))
1158 str = (char *)json_object_get_string(jvalue);
1159 if (sscanf(str, "%04hx", &node->crpl) != 1)
1165 bool mesh_db_read_node(json_object *jnode, mesh_db_node_cb cb, void *user_data)
1167 struct mesh_db_node node;
1168 json_object *jvalue;
1175 l_info("Node read callback is required");
1179 memset(&node, 0, sizeof(node));
1181 if (!parse_composition(jnode, &node)) {
1182 l_info("Failed to parse local node composition");
1186 parse_features(jnode, &node);
1188 if (!json_object_object_get_ex(jnode, "unicastAddress", &jvalue)) {
1189 l_info("Bad config: Unicast address must be present");
1193 str = (char *)json_object_get_string(jvalue);
1194 if (sscanf(str, "%04hx", &node.unicast) != 1)
1197 if (json_object_object_get_ex(jnode, "defaultTTL", &jvalue)) {
1198 int ttl = json_object_get_int(jvalue);
1200 if (ttl < 0 || ttl == 1 || ttl > DEFAULT_TTL)
1202 node.ttl = (uint8_t) ttl;
1205 if (json_object_object_get_ex(jnode, "sequenceNumber", &jvalue))
1206 node.seq_number = json_object_get_int(jvalue);
1208 /* Check for required "elements" property */
1209 if (!json_object_object_get_ex(jnode, "elements", &jvalue))
1212 if (!parse_elements(jvalue, &node))
1215 return cb(&node, user_data);
1218 bool mesh_db_write_uint16_hex(json_object *jobj, const char *desc,
1221 json_object *jstring;
1227 snprintf(buf, 5, "%4.4x", value);
1228 jstring = json_object_new_string(buf);
1232 json_object_object_add(jobj, desc, jstring);
1236 bool mesh_db_write_uint32_hex(json_object *jobj, const char *desc,
1239 json_object *jstring;
1245 snprintf(buf, 9, "%8.8x", value);
1246 jstring = json_object_new_string(buf);
1250 json_object_object_add(jobj, desc, jstring);
1254 bool mesh_db_write_int(json_object *jobj, const char *keyword, int value)
1256 json_object *jvalue;
1261 json_object_object_del(jobj, keyword);
1263 jvalue = json_object_new_int(value);
1267 json_object_object_add(jobj, keyword, jvalue);
1271 bool mesh_db_write_bool(json_object *jobj, const char *keyword, bool value)
1273 json_object *jvalue;
1278 json_object_object_del(jobj, keyword);
1280 jvalue = json_object_new_boolean(value);
1284 json_object_object_add(jobj, keyword, jvalue);
1288 static const char *mode_to_string(int mode)
1291 case MESH_MODE_DISABLED:
1293 case MESH_MODE_ENABLED:
1296 return "unsupported";
1300 bool mesh_db_write_mode(json_object *jobj, const char *keyword, int value)
1302 json_object *jstring;
1307 jstring = json_object_new_string(mode_to_string(value));
1312 json_object_object_add(jobj, keyword, jstring);
1317 bool mesh_db_write_relay_mode(json_object *jnode, uint8_t mode, uint8_t count,
1320 json_object *jrelay;
1325 json_object_object_del(jnode, "relay");
1327 jrelay = json_object_new_object();
1331 if (!mesh_db_write_mode(jrelay, "mode", mode))
1334 if (!mesh_db_write_int(jrelay, "count", count))
1337 if (!mesh_db_write_int(jrelay, "interval", interval))
1340 json_object_object_add(jnode, "relay", jrelay);
1344 json_object_put(jrelay);
1348 bool mesh_db_read_net_transmit(json_object *jobj, uint8_t *cnt,
1351 json_object *jretransmit, *jvalue;
1356 if (!json_object_object_get_ex(jobj, "retransmit", &jretransmit))
1359 if (!json_object_object_get_ex(jretransmit, "count", &jvalue))
1362 *cnt = (uint8_t) json_object_get_int(jvalue);
1364 if (!json_object_object_get_ex(jretransmit, "interval", &jvalue))
1367 *interval = (uint16_t) json_object_get_int(jvalue);
1372 bool mesh_db_write_net_transmit(json_object *jobj, uint8_t cnt,
1375 json_object *jretransmit;
1380 json_object_object_del(jobj, "retransmit");
1382 jretransmit = json_object_new_object();
1386 if (!mesh_db_write_int(jretransmit, "count", cnt))
1389 if (!mesh_db_write_int(jretransmit, "interval", interval))
1392 json_object_object_add(jobj, "retransmit", jretransmit);
1396 json_object_put(jretransmit);
1401 bool mesh_db_write_iv_index(json_object *jobj, uint32_t idx, bool update)
1403 int tmp = update ? 1 : 0;
1408 if (!mesh_db_write_int(jobj, "IVindex", idx))
1411 if (!mesh_db_write_int(jobj, "IVupdate", tmp))
1417 void mesh_db_remove_property(json_object *jobj, const char *desc)
1420 json_object_object_del(jobj, desc);
1423 static void add_model(void *a, void *b)
1425 struct mesh_db_model *mod = a;
1426 json_object *jmodels = b, *jmodel;
1428 jmodel = json_object_new_object();
1433 mesh_db_write_uint16_hex(jmodel, "modelId",
1434 (uint16_t) mod->id);
1436 mesh_db_write_uint32_hex(jmodel, "modelId", mod->id);
1438 json_object_array_add(jmodels, jmodel);
1441 /* Add unprovisioned node (local) */
1442 bool mesh_db_add_node(json_object *jnode, struct mesh_db_node *node) {
1444 struct mesh_db_modes *modes = &node->modes;
1445 const struct l_queue_entry *entry;
1446 json_object *jelements;
1451 /* CID, PID, VID, crpl */
1452 if (!mesh_db_write_uint16_hex(jnode, "cid", node->cid))
1455 if (!mesh_db_write_uint16_hex(jnode, "pid", node->pid))
1458 if (!mesh_db_write_uint16_hex(jnode, "vid", node->vid))
1461 if (!mesh_db_write_uint16_hex(jnode, "crpl", node->crpl))
1464 /* Features: relay, LPN, friend, proxy*/
1465 if (!mesh_db_write_relay_mode(jnode, modes->relay.state,
1467 modes->relay.interval))
1470 if (!mesh_db_write_mode(jnode, "lowPower", modes->lpn))
1473 if (!mesh_db_write_mode(jnode, "friend", modes->friend))
1476 if (!mesh_db_write_mode(jnode, "proxy", modes->proxy))
1479 /* Beaconing state */
1480 if (!mesh_db_write_mode(jnode, "beacon", modes->beacon))
1483 /* Sequence number */
1484 json_object_object_add(jnode, "sequenceNumber",
1485 json_object_new_int(node->seq_number));
1488 json_object_object_add(jnode, "defaultTTL",
1489 json_object_new_int(node->ttl));
1492 jelements = json_object_new_array();
1496 entry = l_queue_get_entries(node->elements);
1498 for (; entry; entry = entry->next) {
1499 struct mesh_db_element *ele = entry->data;
1500 json_object *jelement, *jmodels;
1502 jelement = json_object_new_object();
1505 json_object_put(jelements);
1509 mesh_db_write_int(jelement, "elementIndex", ele->index);
1510 mesh_db_write_uint16_hex(jelement, "location", ele->location);
1511 json_object_array_add(jelements, jelement);
1514 if (l_queue_isempty(ele->models))
1517 jmodels = json_object_new_array();
1519 json_object_put(jelements);
1523 json_object_object_add(jelement, "models", jmodels);
1524 l_queue_foreach(ele->models, add_model, jmodels);
1527 json_object_object_add(jnode, "elements", jelements);
1532 static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
1534 json_object *jarray;
1537 /* Clean up all the bound appkeys */
1538 if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
1541 len = json_object_array_length(jarray);
1543 for (i = 0; i < len; ++i) {
1544 json_object *jentry;
1547 jentry = json_object_array_get_idx(jarray, i);
1549 if (!get_key_index(jentry, "boundNetKey", &idx))
1555 json_object_object_del(jentry, "oldKey");
1557 if (!get_key_index(jentry, "index", &idx))
1563 bool mesh_db_net_key_set_phase(json_object *jobj, uint16_t idx, uint8_t phase)
1565 json_object *jarray, *jentry = NULL;
1570 if (json_object_object_get_ex(jobj, "netKeys", &jarray))
1571 jentry = get_key_object(jarray, idx);
1576 json_object_object_del(jentry, "keyRefresh");
1577 json_object_object_add(jentry, "keyRefresh",
1578 json_object_new_int(phase));
1580 if (phase == KEY_REFRESH_PHASE_NONE) {
1581 json_object_object_del(jentry, "oldKey");
1582 finish_key_refresh(jobj, idx);
1588 bool mesh_db_model_pub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
1589 bool vendor, struct mesh_db_pub *pub)
1591 json_object *jmodel, *jpub, *jretransmit;
1598 ele_idx = get_element_index(jnode, addr);
1602 jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
1606 json_object_object_del(jmodel, "publish");
1608 jpub = json_object_new_object();
1613 res = add_key_value(jpub, "address", pub->virt_addr);
1615 res = mesh_db_write_uint16_hex(jpub, "address", pub->addr);
1620 if (!mesh_db_write_uint16_hex(jpub, "index", pub->idx))
1623 if (!mesh_db_write_int(jpub, "ttl", pub->ttl))
1626 if (!mesh_db_write_int(jpub, "period", pub->period))
1629 if (!mesh_db_write_int(jpub, "credentials", pub->credential ? 1 : 0))
1632 jretransmit = json_object_new_object();
1636 if (!mesh_db_write_int(jretransmit, "count", pub->count))
1639 if (!mesh_db_write_int(jretransmit, "interval", pub->interval))
1642 json_object_object_add(jpub, "retransmit", jretransmit);
1643 json_object_object_add(jmodel, "publish", jpub);
1647 json_object_put(jpub);
1651 static bool delete_model_property(json_object *jnode, uint16_t addr,
1652 uint32_t mod_id, bool vendor, const char *keyword)
1654 json_object *jmodel;
1657 ele_idx = get_element_index(jnode, addr);
1661 jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
1665 json_object_object_del(jmodel, keyword);
1670 bool mesh_db_model_pub_del(json_object *jnode, uint16_t addr, uint32_t mod_id,
1676 return delete_model_property(jnode, addr, mod_id, vendor, "publish");
1679 bool mesh_db_model_sub_add(json_object *jnode, uint16_t addr, uint32_t mod_id,
1680 bool vendor, struct mesh_db_sub *sub)
1682 json_object *jmodel, *jstring, *jarray = NULL;
1689 ele_idx = get_element_index(jnode, addr);
1693 jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
1698 snprintf(buf, 5, "%4.4x", sub->src.addr);
1701 hex2str(sub->src.virt_addr, 16, buf, 33);
1705 json_object_object_get_ex(jmodel, "subscribe", &jarray);
1706 if (jarray && jarray_has_string(jarray, buf, len))
1709 jstring = json_object_new_string(buf);
1714 jarray = json_object_new_array();
1716 json_object_put(jstring);
1719 json_object_object_add(jmodel, "subscribe", jarray);
1722 json_object_array_add(jarray, jstring);
1727 bool mesh_db_model_sub_del(json_object *jnode, uint16_t addr,
1728 uint32_t mod_id, bool vendor, struct mesh_db_sub *sub)
1730 json_object *jmodel, *jarray, *jarray_new;
1737 ele_idx = get_element_index(jnode, addr);
1741 jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
1745 if (!json_object_object_get_ex(jmodel, "subscribe", &jarray))
1749 snprintf(buf, 5, "%4.4x", sub->src.addr);
1752 hex2str(sub->src.virt_addr, 16, buf, 33);
1756 if (!jarray_has_string(jarray, buf, len))
1759 if (json_object_array_length(jarray) == 1) {
1760 json_object_object_del(jmodel, "subscribe");
1765 * There is no easy way to delete a value from a json array.
1766 * Create a new copy without specified element and
1767 * then remove old array.
1769 jarray_new = jarray_string_del(jarray, buf, len);
1773 json_object_object_del(jmodel, "subscribe");
1774 json_object_object_add(jmodel, "subscribe", jarray_new);
1779 bool mesh_db_model_sub_del_all(json_object *jnode, uint16_t addr,
1780 uint32_t mod_id, bool vendor)
1785 return delete_model_property(jnode, addr, mod_id, vendor, "subscribe");