mesh-config-json.c 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2018-2019 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #define _GNU_SOURCE
  14. #include <dirent.h>
  15. #include <errno.h>
  16. #include <fcntl.h>
  17. #include <ftw.h>
  18. #include <libgen.h>
  19. #include <limits.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <sys/time.h>
  24. #include <ell/ell.h>
  25. #include <json-c/json.h>
  26. #include "mesh/mesh-defs.h"
  27. #include "mesh/util.h"
  28. #include "mesh/mesh-config.h"
  29. /* To prevent local node JSON cache thrashing, minimum update times */
  30. #define MIN_SEQ_CACHE_TRIGGER 32
  31. #define MIN_SEQ_CACHE_VALUE (2 * 32)
  32. #define MIN_SEQ_CACHE_TIME (5 * 60)
  33. #define CHECK_KEY_IDX_RANGE(x) ((x) <= 4095)
  34. struct mesh_config {
  35. json_object *jnode;
  36. char *node_dir_path;
  37. uint8_t uuid[16];
  38. uint32_t write_seq;
  39. struct timeval write_time;
  40. struct l_queue *idles;
  41. };
  42. struct write_info {
  43. struct mesh_config *cfg;
  44. void *user_data;
  45. mesh_config_status_func_t cb;
  46. };
  47. static const char *cfgnode_name = "/node.json";
  48. static const char *bak_ext = ".bak";
  49. static const char *tmp_ext = ".tmp";
  50. static bool save_config(json_object *jnode, const char *fname)
  51. {
  52. FILE *outfile;
  53. const char *str;
  54. bool result = false;
  55. outfile = fopen(fname, "w");
  56. if (!outfile) {
  57. l_error("Failed to save configuration to %s", fname);
  58. return false;
  59. }
  60. str = json_object_to_json_string_ext(jnode, JSON_C_TO_STRING_PRETTY);
  61. if (fwrite(str, sizeof(char), strlen(str), outfile) < strlen(str))
  62. l_warn("Incomplete write of mesh configuration");
  63. else
  64. result = true;
  65. fclose(outfile);
  66. return result;
  67. }
  68. static bool get_int(json_object *jobj, const char *keyword, int *value)
  69. {
  70. json_object *jvalue;
  71. if (!json_object_object_get_ex(jobj, keyword, &jvalue))
  72. return false;
  73. *value = json_object_get_int(jvalue);
  74. if (errno == EINVAL)
  75. return false;
  76. return true;
  77. }
  78. static bool add_u64_value(json_object *jobj, const char *desc,
  79. const uint8_t u64[8])
  80. {
  81. json_object *jstring;
  82. char hexstr[17];
  83. hex2str((uint8_t *) u64, 8, hexstr, 17);
  84. jstring = json_object_new_string(hexstr);
  85. if (!jstring)
  86. return false;
  87. json_object_object_del(jobj, desc);
  88. json_object_object_add(jobj, desc, jstring);
  89. return true;
  90. }
  91. static bool add_key_value(json_object *jobj, const char *desc,
  92. const uint8_t key[16])
  93. {
  94. json_object *jstring;
  95. char hexstr[33];
  96. hex2str((uint8_t *) key, 16, hexstr, 33);
  97. jstring = json_object_new_string(hexstr);
  98. if (!jstring)
  99. return false;
  100. json_object_object_del(jobj, desc);
  101. json_object_object_add(jobj, desc, jstring);
  102. return true;
  103. }
  104. static int get_element_index(json_object *jnode, uint16_t ele_addr)
  105. {
  106. json_object *jvalue, *jelements;
  107. uint16_t addr, num_ele;
  108. char *str;
  109. if (!json_object_object_get_ex(jnode, "unicastAddress", &jvalue))
  110. return -1;
  111. str = (char *)json_object_get_string(jvalue);
  112. if (sscanf(str, "%04hx", &addr) != 1)
  113. return -1;
  114. if (!json_object_object_get_ex(jnode, "elements", &jelements))
  115. return -1;
  116. num_ele = json_object_array_length(jelements);
  117. if (ele_addr >= addr + num_ele || ele_addr < addr)
  118. return -1;
  119. return ele_addr - addr;
  120. }
  121. static json_object *get_element_model(json_object *jnode, int ele_idx,
  122. uint32_t mod_id, bool vendor)
  123. {
  124. json_object *jelements, *jelement, *jmodels;
  125. int i, num_mods;
  126. size_t len;
  127. char buf[9];
  128. if (!json_object_object_get_ex(jnode, "elements", &jelements))
  129. return NULL;
  130. jelement = json_object_array_get_idx(jelements, ele_idx);
  131. if (!jelement)
  132. return NULL;
  133. if (!json_object_object_get_ex(jelement, "models", &jmodels))
  134. return NULL;
  135. num_mods = json_object_array_length(jmodels);
  136. if (!num_mods)
  137. return NULL;
  138. if (!vendor) {
  139. snprintf(buf, 5, "%4.4x", (uint16_t)mod_id);
  140. len = 4;
  141. } else {
  142. snprintf(buf, 9, "%8.8x", mod_id);
  143. len = 8;
  144. }
  145. for (i = 0; i < num_mods; ++i) {
  146. json_object *jmodel, *jvalue;
  147. char *str;
  148. jmodel = json_object_array_get_idx(jmodels, i);
  149. if (!json_object_object_get_ex(jmodel, "modelId", &jvalue))
  150. return NULL;
  151. str = (char *)json_object_get_string(jvalue);
  152. if (!str)
  153. return NULL;
  154. if (!strncmp(str, buf, len))
  155. return jmodel;
  156. }
  157. return NULL;
  158. }
  159. static bool jarray_has_string(json_object *jarray, char *str, size_t len)
  160. {
  161. int i, sz = json_object_array_length(jarray);
  162. for (i = 0; i < sz; ++i) {
  163. json_object *jentry;
  164. char *str_entry;
  165. jentry = json_object_array_get_idx(jarray, i);
  166. str_entry = (char *)json_object_get_string(jentry);
  167. if (!str_entry)
  168. continue;
  169. if (!strncmp(str, str_entry, len))
  170. return true;
  171. }
  172. return false;
  173. }
  174. static void jarray_string_del(json_object *jarray, char *str, size_t len)
  175. {
  176. int i, sz = json_object_array_length(jarray);
  177. for (i = 0; i < sz; ++i) {
  178. json_object *jentry;
  179. char *str_entry;
  180. jentry = json_object_array_get_idx(jarray, i);
  181. str_entry = (char *)json_object_get_string(jentry);
  182. if (str_entry && !strncmp(str, str_entry, len)) {
  183. json_object_array_del_idx(jarray, i, 1);
  184. return;
  185. }
  186. }
  187. }
  188. static bool get_key_index(json_object *jobj, const char *keyword,
  189. uint16_t *index)
  190. {
  191. int idx;
  192. if (!get_int(jobj, keyword, &idx))
  193. return false;
  194. if (!CHECK_KEY_IDX_RANGE(idx))
  195. return false;
  196. *index = (uint16_t) idx;
  197. return true;
  198. }
  199. static json_object *get_key_object(json_object *jarray, uint16_t idx)
  200. {
  201. int i, sz = json_object_array_length(jarray);
  202. for (i = 0; i < sz; ++i) {
  203. json_object *jentry;
  204. uint16_t jidx;
  205. jentry = json_object_array_get_idx(jarray, i);
  206. if (!get_key_index(jentry, "index", &jidx))
  207. return NULL;
  208. if (jidx == idx)
  209. return jentry;
  210. }
  211. return NULL;
  212. }
  213. static void jarray_key_del(json_object *jarray, int16_t idx)
  214. {
  215. int i, sz = json_object_array_length(jarray);
  216. for (i = 0; i < sz; ++i) {
  217. json_object *jentry;
  218. uint16_t nidx;
  219. jentry = json_object_array_get_idx(jarray, i);
  220. if (get_key_index(jentry, "index", &nidx) && nidx == idx) {
  221. json_object_array_del_idx(jarray, i, 1);
  222. return;
  223. }
  224. }
  225. }
  226. static bool read_unicast_address(json_object *jobj, uint16_t *unicast)
  227. {
  228. json_object *jvalue;
  229. char *str;
  230. if (!json_object_object_get_ex(jobj, "unicastAddress", &jvalue))
  231. return false;
  232. str = (char *)json_object_get_string(jvalue);
  233. if (sscanf(str, "%04hx", unicast) != 1)
  234. return false;
  235. return true;
  236. }
  237. static bool read_default_ttl(json_object *jobj, uint8_t *ttl)
  238. {
  239. json_object *jvalue;
  240. int val;
  241. /* defaultTTL is optional */
  242. if (!json_object_object_get_ex(jobj, "defaultTTL", &jvalue))
  243. return true;
  244. val = json_object_get_int(jvalue);
  245. if (!val && errno == EINVAL)
  246. return false;
  247. if (val < 0 || val == 1 || val > TTL_MASK)
  248. return false;
  249. *ttl = (uint8_t) val;
  250. return true;
  251. }
  252. static bool read_seq_number(json_object *jobj, uint32_t *seq_number)
  253. {
  254. json_object *jvalue;
  255. int val;
  256. /* sequenceNumber is optional */
  257. if (!json_object_object_get_ex(jobj, "sequenceNumber", &jvalue))
  258. return true;
  259. val = json_object_get_int(jvalue);
  260. if (!val && errno == EINVAL)
  261. return false;
  262. if (val < 0 || val > SEQ_MASK + 1)
  263. return false;
  264. *seq_number = (uint32_t) val;
  265. return true;
  266. }
  267. static bool read_iv_index(json_object *jobj, uint32_t *idx, bool *update)
  268. {
  269. int tmp;
  270. /* IV index */
  271. if (!get_int(jobj, "IVindex", &tmp))
  272. return false;
  273. *idx = (uint32_t) tmp;
  274. if (!get_int(jobj, "IVupdate", &tmp))
  275. return false;
  276. *update = tmp ? true : false;
  277. return true;
  278. }
  279. static bool read_token(json_object *jobj, uint8_t token[8])
  280. {
  281. json_object *jvalue;
  282. char *str;
  283. if (!token)
  284. return false;
  285. if (!json_object_object_get_ex(jobj, "token", &jvalue))
  286. return false;
  287. str = (char *)json_object_get_string(jvalue);
  288. if (!str2hex(str, strlen(str), token, 8))
  289. return false;
  290. return true;
  291. }
  292. static bool read_device_key(json_object *jobj, uint8_t key_buf[16])
  293. {
  294. json_object *jvalue;
  295. char *str;
  296. if (!key_buf)
  297. return false;
  298. if (!json_object_object_get_ex(jobj, "deviceKey", &jvalue))
  299. return false;
  300. str = (char *)json_object_get_string(jvalue);
  301. if (!str2hex(str, strlen(str), key_buf, 16))
  302. return false;
  303. return true;
  304. }
  305. static bool read_comp_pages(json_object *jobj, struct mesh_config_node *node)
  306. {
  307. json_object *jarray, *jentry;
  308. struct mesh_config_comp_page *page;
  309. int len;
  310. int i;
  311. if (!json_object_object_get_ex(jobj, "pages", &jarray))
  312. return true;
  313. if (json_object_get_type(jarray) != json_type_array)
  314. return false;
  315. len = json_object_array_length(jarray);
  316. for (i = 0; i < len; i++) {
  317. size_t clen;
  318. char *str;
  319. jentry = json_object_array_get_idx(jarray, i);
  320. str = (char *)json_object_get_string(jentry);
  321. clen = strlen(str);
  322. if (clen < ((MIN_COMP_SIZE * 2) + 1))
  323. continue;
  324. clen = (clen / 2) - 1;
  325. page = l_malloc(sizeof(struct mesh_config_comp_page) + clen);
  326. if (!str2hex(str + 2, clen * 2, page->data, clen))
  327. goto parse_fail;
  328. if (sscanf(str, "%02hhx", &page->page_num) != 1)
  329. goto parse_fail;
  330. page->len = clen;
  331. l_queue_push_tail(node->pages, page);
  332. }
  333. return true;
  334. parse_fail:
  335. l_free(page);
  336. return false;
  337. }
  338. static bool read_app_keys(json_object *jobj, struct mesh_config_node *node)
  339. {
  340. json_object *jarray;
  341. int len;
  342. int i;
  343. if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
  344. return true;
  345. if (json_object_get_type(jarray) != json_type_array)
  346. return false;
  347. /* Allow empty AppKey array */
  348. len = json_object_array_length(jarray);
  349. if (!len)
  350. return true;
  351. for (i = 0; i < len; ++i) {
  352. json_object *jtemp, *jvalue;
  353. char *str;
  354. struct mesh_config_appkey *appkey;
  355. appkey = l_new(struct mesh_config_appkey, 1);
  356. l_queue_push_tail(node->appkeys, appkey);
  357. jtemp = json_object_array_get_idx(jarray, i);
  358. if (!get_key_index(jtemp, "index", &appkey->app_idx))
  359. goto fail;
  360. if (!get_key_index(jtemp, "boundNetKey", &appkey->net_idx))
  361. goto fail;
  362. if (!json_object_object_get_ex(jtemp, "key", &jvalue))
  363. goto fail;
  364. str = (char *)json_object_get_string(jvalue);
  365. if (!str2hex(str, strlen(str), appkey->new_key, 16))
  366. goto fail;
  367. if (json_object_object_get_ex(jtemp, "oldKey", &jvalue))
  368. str = (char *)json_object_get_string(jvalue);
  369. if (!str2hex(str, strlen(str), appkey->key, 16))
  370. goto fail;
  371. }
  372. return true;
  373. fail:
  374. l_queue_destroy(node->appkeys, l_free);
  375. node->appkeys = NULL;
  376. return false;
  377. }
  378. static bool read_net_keys(json_object *jobj, struct mesh_config_node *node)
  379. {
  380. json_object *jarray;
  381. int len;
  382. int i;
  383. /* At least one NetKey must be present for a provisioned node */
  384. if (!json_object_object_get_ex(jobj, "netKeys", &jarray))
  385. return false;
  386. if (json_object_get_type(jarray) != json_type_array)
  387. return false;
  388. len = json_object_array_length(jarray);
  389. if (!len)
  390. return false;
  391. for (i = 0; i < len; ++i) {
  392. json_object *jtemp, *jvalue;
  393. char *str;
  394. struct mesh_config_netkey *netkey;
  395. netkey = l_new(struct mesh_config_netkey, 1);
  396. l_queue_push_tail(node->netkeys, netkey);
  397. jtemp = json_object_array_get_idx(jarray, i);
  398. if (!get_key_index(jtemp, "index", &netkey->idx))
  399. goto fail;
  400. if (!json_object_object_get_ex(jtemp, "key", &jvalue))
  401. goto fail;
  402. str = (char *)json_object_get_string(jvalue);
  403. if (!str2hex(str, strlen(str), netkey->new_key, 16))
  404. goto fail;
  405. if (!json_object_object_get_ex(jtemp, "keyRefresh", &jvalue))
  406. netkey->phase = KEY_REFRESH_PHASE_NONE;
  407. else
  408. netkey->phase = (uint8_t) json_object_get_int(jvalue);
  409. if (netkey->phase > KEY_REFRESH_PHASE_TWO)
  410. goto fail;
  411. if (json_object_object_get_ex(jtemp, "oldKey", &jvalue)) {
  412. if (netkey->phase == KEY_REFRESH_PHASE_NONE)
  413. goto fail;
  414. str = (char *)json_object_get_string(jvalue);
  415. }
  416. if (!str2hex(str, strlen(str), netkey->key, 16))
  417. goto fail;
  418. }
  419. return true;
  420. fail:
  421. l_queue_destroy(node->netkeys, l_free);
  422. node->netkeys = NULL;
  423. return false;
  424. }
  425. static bool write_int(json_object *jobj, const char *desc, int val)
  426. {
  427. json_object *jvalue;
  428. jvalue = json_object_new_int(val);
  429. if (!jvalue)
  430. return false;
  431. json_object_object_del(jobj, desc);
  432. json_object_object_add(jobj, desc, jvalue);
  433. return true;
  434. }
  435. bool mesh_config_net_key_add(struct mesh_config *cfg, uint16_t idx,
  436. const uint8_t key[16])
  437. {
  438. json_object *jnode, *jarray = NULL, *jentry = NULL;
  439. if (!cfg)
  440. return false;
  441. jnode = cfg->jnode;
  442. l_debug("netKey %4.4x", idx);
  443. json_object_object_get_ex(jnode, "netKeys", &jarray);
  444. if (jarray)
  445. jentry = get_key_object(jarray, idx);
  446. /* Do not allow direct overwrite */
  447. if (jentry)
  448. return false;
  449. jentry = json_object_new_object();
  450. if (!jentry)
  451. return false;
  452. if (!write_int(jentry, "index", idx))
  453. goto fail;
  454. if (!add_key_value(jentry, "key", key))
  455. goto fail;
  456. json_object_object_add(jentry, "keyRefresh",
  457. json_object_new_int(KEY_REFRESH_PHASE_NONE));
  458. if (!jarray) {
  459. jarray = json_object_new_array();
  460. if (!jarray)
  461. goto fail;
  462. json_object_object_add(jnode, "netKeys", jarray);
  463. }
  464. json_object_array_add(jarray, jentry);
  465. return save_config(jnode, cfg->node_dir_path);
  466. fail:
  467. if (jentry)
  468. json_object_put(jentry);
  469. return false;
  470. }
  471. bool mesh_config_net_key_update(struct mesh_config *cfg, uint16_t idx,
  472. const uint8_t key[16])
  473. {
  474. json_object *jnode, *jarray, *jentry, *jstring;
  475. const char *str;
  476. if (!cfg)
  477. return false;
  478. jnode = cfg->jnode;
  479. if (!json_object_object_get_ex(jnode, "netKeys", &jarray))
  480. return false;
  481. jentry = get_key_object(jarray, idx);
  482. /* Net key must be already recorded */
  483. if (!jentry)
  484. return false;
  485. if (!json_object_object_get_ex(jentry, "key", &jstring))
  486. return false;
  487. str = json_object_get_string(jstring);
  488. jstring = json_object_new_string(str);
  489. json_object_object_add(jentry, "oldKey", jstring);
  490. json_object_object_del(jentry, "key");
  491. if (!add_key_value(jentry, "key", key))
  492. return false;
  493. json_object_object_add(jentry, "keyRefresh",
  494. json_object_new_int(KEY_REFRESH_PHASE_ONE));
  495. return save_config(jnode, cfg->node_dir_path);
  496. }
  497. bool mesh_config_net_key_del(struct mesh_config *cfg, uint16_t idx)
  498. {
  499. json_object *jnode, *jarray;
  500. if (!cfg)
  501. return false;
  502. jnode = cfg->jnode;
  503. if (!json_object_object_get_ex(jnode, "netKeys", &jarray))
  504. return true;
  505. jarray_key_del(jarray, idx);
  506. if (!json_object_array_length(jarray))
  507. json_object_object_del(jnode, "netKeys");
  508. return save_config(jnode, cfg->node_dir_path);
  509. }
  510. bool mesh_config_write_device_key(struct mesh_config *cfg, uint8_t *key)
  511. {
  512. if (!cfg || !add_key_value(cfg->jnode, "deviceKey", key))
  513. return false;
  514. return save_config(cfg->jnode, cfg->node_dir_path);
  515. }
  516. bool mesh_config_write_token(struct mesh_config *cfg, uint8_t *token)
  517. {
  518. if (!cfg || !add_u64_value(cfg->jnode, "token", token))
  519. return false;
  520. return save_config(cfg->jnode, cfg->node_dir_path);
  521. }
  522. bool mesh_config_app_key_add(struct mesh_config *cfg, uint16_t net_idx,
  523. uint16_t app_idx, const uint8_t key[16])
  524. {
  525. json_object *jnode, *jarray = NULL, *jentry = NULL;
  526. if (!cfg)
  527. return false;
  528. jnode = cfg->jnode;
  529. json_object_object_get_ex(jnode, "appKeys", &jarray);
  530. if (jarray)
  531. jentry = get_key_object(jarray, app_idx);
  532. /* Do not allow direct overrwrite */
  533. if (jentry)
  534. return false;
  535. jentry = json_object_new_object();
  536. if (!jentry)
  537. return false;
  538. if (!write_int(jentry, "index", app_idx))
  539. goto fail;
  540. if (!write_int(jentry, "boundNetKey", net_idx))
  541. goto fail;
  542. if (!add_key_value(jentry, "key", key))
  543. goto fail;
  544. if (!jarray) {
  545. jarray = json_object_new_array();
  546. if (!jarray)
  547. goto fail;
  548. json_object_object_add(jnode, "appKeys", jarray);
  549. }
  550. json_object_array_add(jarray, jentry);
  551. return save_config(jnode, cfg->node_dir_path);
  552. fail:
  553. if (jentry)
  554. json_object_put(jentry);
  555. return false;
  556. }
  557. bool mesh_config_app_key_update(struct mesh_config *cfg, uint16_t app_idx,
  558. const uint8_t key[16])
  559. {
  560. json_object *jnode, *jarray, *jentry = NULL, *jstring = NULL;
  561. const char *str;
  562. if (!cfg)
  563. return false;
  564. jnode = cfg->jnode;
  565. if (!json_object_object_get_ex(jnode, "appKeys", &jarray))
  566. return false;
  567. /* The key entry should exist if the key is updated */
  568. jentry = get_key_object(jarray, app_idx);
  569. if (!jentry)
  570. return false;
  571. if (!json_object_object_get_ex(jentry, "key", &jstring))
  572. return false;
  573. str = json_object_get_string(jstring);
  574. jstring = json_object_new_string(str);
  575. json_object_object_add(jentry, "oldKey", jstring);
  576. json_object_object_del(jentry, "key");
  577. /* TODO: "Rewind" if add_key_value fails */
  578. if (!add_key_value(jentry, "key", key))
  579. return false;
  580. return save_config(jnode, cfg->node_dir_path);
  581. }
  582. bool mesh_config_app_key_del(struct mesh_config *cfg, uint16_t net_idx,
  583. uint16_t idx)
  584. {
  585. json_object *jnode, *jarray;
  586. if (!cfg)
  587. return false;
  588. jnode = cfg->jnode;
  589. if (!json_object_object_get_ex(jnode, "appKeys", &jarray))
  590. return true;
  591. jarray_key_del(jarray, idx);
  592. if (!json_object_array_length(jarray))
  593. json_object_object_del(jnode, "appKeys");
  594. return save_config(jnode, cfg->node_dir_path);
  595. }
  596. bool mesh_config_model_binding_add(struct mesh_config *cfg, uint16_t ele_addr,
  597. uint32_t mod_id, bool vendor,
  598. uint16_t app_idx)
  599. {
  600. json_object *jnode, *jmodel, *jstring, *jarray = NULL;
  601. int ele_idx;
  602. char buf[5];
  603. if (!cfg)
  604. return false;
  605. jnode = cfg->jnode;
  606. ele_idx = get_element_index(jnode, ele_addr);
  607. if (ele_idx < 0)
  608. return false;
  609. jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
  610. if (!jmodel)
  611. return false;
  612. snprintf(buf, 5, "%4.4x", app_idx);
  613. json_object_object_get_ex(jmodel, "bind", &jarray);
  614. if (jarray && jarray_has_string(jarray, buf, 4))
  615. return true;
  616. jstring = json_object_new_string(buf);
  617. if (!jstring)
  618. return false;
  619. if (!jarray) {
  620. jarray = json_object_new_array();
  621. if (!jarray) {
  622. json_object_put(jstring);
  623. return false;
  624. }
  625. json_object_object_add(jmodel, "bind", jarray);
  626. }
  627. json_object_array_add(jarray, jstring);
  628. return save_config(jnode, cfg->node_dir_path);
  629. }
  630. bool mesh_config_model_binding_del(struct mesh_config *cfg, uint16_t ele_addr,
  631. uint32_t mod_id, bool vendor,
  632. uint16_t app_idx)
  633. {
  634. json_object *jnode, *jmodel, *jarray;
  635. int ele_idx;
  636. char buf[5];
  637. if (!cfg)
  638. return false;
  639. jnode = cfg->jnode;
  640. ele_idx = get_element_index(jnode, ele_addr);
  641. if (ele_idx < 0)
  642. return false;
  643. jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
  644. if (!jmodel)
  645. return false;
  646. if (!json_object_object_get_ex(jmodel, "bind", &jarray))
  647. return true;
  648. snprintf(buf, 5, "%4.4x", app_idx);
  649. jarray_string_del(jarray, buf, 4);
  650. if (!json_object_array_length(jarray))
  651. json_object_object_del(jmodel, "bind");
  652. return save_config(jnode, cfg->node_dir_path);
  653. }
  654. static void free_model(void *data)
  655. {
  656. struct mesh_config_model *mod = data;
  657. l_free(mod->bindings);
  658. l_free(mod->subs);
  659. l_free(mod->pub);
  660. l_free(mod);
  661. }
  662. static void free_element(void *data)
  663. {
  664. struct mesh_config_element *ele = data;
  665. l_queue_destroy(ele->models, free_model);
  666. l_free(ele);
  667. }
  668. static bool parse_bindings(json_object *jarray, struct mesh_config_model *mod)
  669. {
  670. int cnt;
  671. int i;
  672. cnt = json_object_array_length(jarray);
  673. if (cnt > 0xffff)
  674. return false;
  675. mod->num_bindings = cnt;
  676. /* Allow empty bindings list */
  677. if (!cnt)
  678. return true;
  679. mod->bindings = l_new(uint16_t, cnt);
  680. for (i = 0; i < cnt; ++i) {
  681. uint16_t idx;
  682. const char *str;
  683. json_object *jvalue;
  684. jvalue = json_object_array_get_idx(jarray, i);
  685. if (!jvalue)
  686. return false;
  687. str = json_object_get_string(jvalue);
  688. if (sscanf(str, "%04hx", &idx) != 1)
  689. return false;
  690. if (!CHECK_KEY_IDX_RANGE(idx))
  691. return false;
  692. mod->bindings[i] = (uint16_t) idx;
  693. }
  694. return true;
  695. }
  696. static struct mesh_config_pub *parse_model_publication(json_object *jpub)
  697. {
  698. json_object *jvalue;
  699. struct mesh_config_pub *pub;
  700. int len, value;
  701. char *str;
  702. if (!json_object_object_get_ex(jpub, "address", &jvalue))
  703. return NULL;
  704. str = (char *)json_object_get_string(jvalue);
  705. len = strlen(str);
  706. pub = l_new(struct mesh_config_pub, 1);
  707. switch (len) {
  708. case 4:
  709. if (sscanf(str, "%04hx", &pub->addr) != 1)
  710. goto fail;
  711. break;
  712. case 32:
  713. if (!str2hex(str, len, pub->virt_addr, 16))
  714. goto fail;
  715. pub->virt = true;
  716. break;
  717. default:
  718. goto fail;
  719. }
  720. if (!get_key_index(jpub, "index", &pub->idx))
  721. goto fail;
  722. if (!get_int(jpub, "ttl", &value))
  723. goto fail;
  724. pub->ttl = (uint8_t) value;
  725. if (!get_int(jpub, "period", &value))
  726. goto fail;
  727. pub->period = value;
  728. if (!get_int(jpub, "credentials", &value))
  729. goto fail;
  730. pub->credential = (uint8_t) value;
  731. if (!json_object_object_get_ex(jpub, "retransmit", &jvalue))
  732. goto fail;
  733. if (!get_int(jvalue, "count", &value))
  734. goto fail;
  735. pub->cnt = (uint8_t) value;
  736. if (!get_int(jvalue, "interval", &value))
  737. goto fail;
  738. pub->interval = (uint8_t) value;
  739. return pub;
  740. fail:
  741. l_free(pub);
  742. return NULL;
  743. }
  744. static bool parse_model_subscriptions(json_object *jsubs,
  745. struct mesh_config_model *mod)
  746. {
  747. struct mesh_config_sub *subs;
  748. int i, cnt;
  749. if (json_object_get_type(jsubs) != json_type_array)
  750. return NULL;
  751. cnt = json_object_array_length(jsubs);
  752. /* Allow empty array */
  753. if (!cnt)
  754. return true;
  755. subs = l_new(struct mesh_config_sub, cnt);
  756. for (i = 0; i < cnt; ++i) {
  757. char *str;
  758. int len;
  759. json_object *jvalue;
  760. jvalue = json_object_array_get_idx(jsubs, i);
  761. if (!jvalue)
  762. goto fail;
  763. str = (char *)json_object_get_string(jvalue);
  764. len = strlen(str);
  765. switch (len) {
  766. case 4:
  767. if (sscanf(str, "%04hx", &subs[i].addr.grp) != 1)
  768. goto fail;
  769. break;
  770. case 32:
  771. if (!str2hex(str, len, subs[i].addr.label, 16))
  772. goto fail;
  773. subs[i].virt = true;
  774. break;
  775. default:
  776. goto fail;
  777. }
  778. }
  779. mod->num_subs = cnt;
  780. mod->subs = subs;
  781. return true;
  782. fail:
  783. l_free(subs);
  784. return false;
  785. }
  786. static bool parse_models(json_object *jmodels, struct mesh_config_element *ele)
  787. {
  788. int i, num_models;
  789. num_models = json_object_array_length(jmodels);
  790. if (!num_models)
  791. return true;
  792. for (i = 0; i < num_models; ++i) {
  793. json_object *jmodel, *jarray, *jvalue;
  794. struct mesh_config_model *mod;
  795. uint32_t id;
  796. int len;
  797. char *str;
  798. jmodel = json_object_array_get_idx(jmodels, i);
  799. if (!jmodel)
  800. goto fail;
  801. mod = l_new(struct mesh_config_model, 1);
  802. l_queue_push_tail(ele->models, mod);
  803. if (!json_object_object_get_ex(jmodel, "modelId", &jvalue))
  804. goto fail;
  805. str = (char *)json_object_get_string(jvalue);
  806. len = strlen(str);
  807. if (len == 4) {
  808. if (sscanf(str, "%04x", &id) != 1)
  809. goto fail;
  810. } else if (len == 8) {
  811. if (sscanf(str, "%08x", &id) != 1)
  812. goto fail;
  813. mod->vendor = true;
  814. } else
  815. goto fail;
  816. mod->id = id;
  817. if (json_object_object_get_ex(jmodel, "bind", &jarray)) {
  818. if (json_object_get_type(jarray) != json_type_array ||
  819. !parse_bindings(jarray, mod))
  820. goto fail;
  821. }
  822. if (json_object_object_get_ex(jmodel, "pubEnabled", &jvalue))
  823. mod->pub_enabled = json_object_get_boolean(jvalue);
  824. else
  825. mod->pub_enabled = true;
  826. if (json_object_object_get_ex(jmodel, "subEnabled", &jvalue))
  827. mod->sub_enabled = json_object_get_boolean(jvalue);
  828. else
  829. mod->sub_enabled = true;
  830. if (json_object_object_get_ex(jmodel, "publish", &jvalue)) {
  831. mod->pub = parse_model_publication(jvalue);
  832. if (!mod->pub)
  833. goto fail;
  834. }
  835. if (json_object_object_get_ex(jmodel, "subscribe", &jarray)) {
  836. if (!parse_model_subscriptions(jarray, mod))
  837. goto fail;
  838. }
  839. }
  840. return true;
  841. fail:
  842. l_queue_destroy(ele->models, free_model);
  843. return false;
  844. }
  845. static bool parse_elements(json_object *jelems, struct mesh_config_node *node)
  846. {
  847. int i, num_ele;
  848. if (json_object_get_type(jelems) != json_type_array)
  849. return false;
  850. num_ele = json_object_array_length(jelems);
  851. if (!num_ele)
  852. /* Allow "empty" nodes */
  853. return true;
  854. for (i = 0; i < num_ele; ++i) {
  855. json_object *jelement;
  856. json_object *jmodels;
  857. json_object *jvalue;
  858. struct mesh_config_element *ele;
  859. int index;
  860. char *str;
  861. jelement = json_object_array_get_idx(jelems, i);
  862. if (!jelement)
  863. goto fail;
  864. if (!get_int(jelement, "elementIndex", &index) ||
  865. index > num_ele)
  866. goto fail;
  867. ele = l_new(struct mesh_config_element, 1);
  868. ele->index = index;
  869. ele->models = l_queue_new();
  870. l_queue_push_tail(node->elements, ele);
  871. if (!json_object_object_get_ex(jelement, "location", &jvalue))
  872. goto fail;
  873. str = (char *)json_object_get_string(jvalue);
  874. if (sscanf(str, "%04hx", &(ele->location)) != 1)
  875. goto fail;
  876. if (json_object_object_get_ex(jelement, "models", &jmodels)) {
  877. if (json_object_get_type(jmodels) != json_type_array ||
  878. !parse_models(jmodels, ele))
  879. goto fail;
  880. }
  881. }
  882. return true;
  883. fail:
  884. l_queue_destroy(node->elements, free_element);
  885. node->elements = NULL;
  886. return false;
  887. }
  888. static int get_mode(json_object *jvalue)
  889. {
  890. const char *str;
  891. str = json_object_get_string(jvalue);
  892. if (!str)
  893. return 0xffffffff;
  894. if (!strncasecmp(str, "disabled", strlen("disabled")))
  895. return MESH_MODE_DISABLED;
  896. if (!strncasecmp(str, "enabled", strlen("enabled")))
  897. return MESH_MODE_ENABLED;
  898. if (!strncasecmp(str, "unsupported", strlen("unsupported")))
  899. return MESH_MODE_UNSUPPORTED;
  900. return 0xffffffff;
  901. }
  902. static void parse_features(json_object *jconfig, struct mesh_config_node *node)
  903. {
  904. json_object *jvalue, *jrelay;
  905. int mode, count;
  906. uint16_t interval;
  907. if (json_object_object_get_ex(jconfig, "proxy", &jvalue)) {
  908. mode = get_mode(jvalue);
  909. if (mode <= MESH_MODE_UNSUPPORTED)
  910. node->modes.proxy = mode;
  911. }
  912. if (json_object_object_get_ex(jconfig, "friend", &jvalue)) {
  913. mode = get_mode(jvalue);
  914. if (mode <= MESH_MODE_UNSUPPORTED)
  915. node->modes.friend = mode;
  916. }
  917. if (json_object_object_get_ex(jconfig, "lowPower", &jvalue)) {
  918. mode = get_mode(jvalue);
  919. if (mode <= MESH_MODE_UNSUPPORTED)
  920. node->modes.lpn = mode;
  921. }
  922. if (json_object_object_get_ex(jconfig, "beacon", &jvalue)) {
  923. mode = get_mode(jvalue);
  924. if (mode <= MESH_MODE_UNSUPPORTED)
  925. node->modes.beacon = mode;
  926. }
  927. if (!json_object_object_get_ex(jconfig, "relay", &jrelay))
  928. return;
  929. if (json_object_object_get_ex(jrelay, "mode", &jvalue)) {
  930. mode = get_mode(jvalue);
  931. if (mode <= MESH_MODE_UNSUPPORTED)
  932. node->modes.relay.state = mode;
  933. else
  934. return;
  935. } else
  936. return;
  937. if (!json_object_object_get_ex(jrelay, "count", &jvalue))
  938. return;
  939. /* TODO: check range */
  940. count = json_object_get_int(jvalue);
  941. node->modes.relay.cnt = count;
  942. if (!json_object_object_get_ex(jrelay, "interval", &jvalue))
  943. return;
  944. /* TODO: check range */
  945. interval = json_object_get_int(jvalue);
  946. node->modes.relay.interval = interval;
  947. }
  948. static bool parse_composition(json_object *jcomp, struct mesh_config_node *node)
  949. {
  950. json_object *jvalue;
  951. char *str;
  952. /* All the fields in node composition are mandatory */
  953. if (!json_object_object_get_ex(jcomp, "cid", &jvalue))
  954. return false;
  955. str = (char *)json_object_get_string(jvalue);
  956. if (sscanf(str, "%04hx", &node->cid) != 1)
  957. return false;
  958. if (!json_object_object_get_ex(jcomp, "pid", &jvalue))
  959. return false;
  960. str = (char *)json_object_get_string(jvalue);
  961. if (sscanf(str, "%04hx", &node->pid) != 1)
  962. return false;
  963. if (!json_object_object_get_ex(jcomp, "vid", &jvalue))
  964. return false;
  965. str = (char *)json_object_get_string(jvalue);
  966. if (sscanf(str, "%04hx", &node->vid) != 1)
  967. return false;
  968. if (!json_object_object_get_ex(jcomp, "crpl", &jvalue))
  969. return false;
  970. str = (char *)json_object_get_string(jvalue);
  971. if (sscanf(str, "%04hx", &node->crpl) != 1)
  972. return false;
  973. return true;
  974. }
  975. static bool read_net_transmit(json_object *jobj, struct mesh_config_node *node)
  976. {
  977. json_object *jrtx, *jvalue;
  978. uint16_t interval;
  979. uint8_t cnt;
  980. if (!json_object_object_get_ex(jobj, "retransmit", &jrtx))
  981. return true;
  982. if (!json_object_object_get_ex(jrtx, "count", &jvalue))
  983. return false;
  984. /* TODO: add range checking */
  985. cnt = (uint8_t) json_object_get_int(jvalue);
  986. if (!json_object_object_get_ex(jrtx, "interval", &jvalue))
  987. return false;
  988. interval = (uint16_t) json_object_get_int(jvalue);
  989. node->net_transmit = l_new(struct mesh_config_transmit, 1);
  990. node->net_transmit->count = cnt;
  991. node->net_transmit->interval = interval;
  992. return true;
  993. }
  994. static bool read_node(json_object *jnode, struct mesh_config_node *node)
  995. {
  996. json_object *jvalue;
  997. if (!read_iv_index(jnode, &node->iv_index, &node->iv_update)) {
  998. l_info("Failed to read IV index");
  999. return false;
  1000. }
  1001. if (!read_token(jnode, node->token)) {
  1002. l_info("Failed to read node token");
  1003. return false;
  1004. }
  1005. if (!read_device_key(jnode, node->dev_key)) {
  1006. l_info("Failed to read node device key");
  1007. return false;
  1008. }
  1009. if (!parse_composition(jnode, node)) {
  1010. l_info("Failed to parse local node composition");
  1011. return false;
  1012. }
  1013. parse_features(jnode, node);
  1014. if (!read_unicast_address(jnode, &node->unicast)) {
  1015. l_info("Failed to parse unicast address");
  1016. return false;
  1017. }
  1018. if (!read_default_ttl(jnode, &node->ttl)) {
  1019. l_info("Failed to parse default ttl");
  1020. return false;
  1021. }
  1022. if (!read_seq_number(jnode, &node->seq_number)) {
  1023. l_info("Failed to parse sequence number");
  1024. return false;
  1025. }
  1026. /* Check for required "elements" property */
  1027. if (!json_object_object_get_ex(jnode, "elements", &jvalue))
  1028. return false;
  1029. if (!read_net_transmit(jnode, node)) {
  1030. l_info("Failed to read node net transmit parameters");
  1031. return false;
  1032. }
  1033. if (!read_net_keys(jnode, node)) {
  1034. l_info("Failed to read net keys");
  1035. return false;
  1036. }
  1037. if (!read_app_keys(jnode, node)) {
  1038. l_info("Failed to read app keys");
  1039. return false;
  1040. }
  1041. if (!read_comp_pages(jnode, node)) {
  1042. l_info("Failed to read Composition Pages");
  1043. return false;
  1044. }
  1045. if (!parse_elements(jvalue, node)) {
  1046. l_info("Failed to parse elements");
  1047. return false;
  1048. }
  1049. return true;
  1050. }
  1051. static bool write_uint16_hex(json_object *jobj, const char *desc,
  1052. uint16_t value)
  1053. {
  1054. json_object *jstring;
  1055. char buf[5];
  1056. snprintf(buf, 5, "%4.4x", value);
  1057. jstring = json_object_new_string(buf);
  1058. if (!jstring)
  1059. return false;
  1060. json_object_object_del(jobj, desc);
  1061. json_object_object_add(jobj, desc, jstring);
  1062. return true;
  1063. }
  1064. static bool write_uint32_hex(json_object *jobj, const char *desc, uint32_t val)
  1065. {
  1066. json_object *jstring;
  1067. char buf[9];
  1068. snprintf(buf, 9, "%8.8x", val);
  1069. jstring = json_object_new_string(buf);
  1070. if (!jstring)
  1071. return false;
  1072. json_object_object_del(jobj, desc);
  1073. json_object_object_add(jobj, desc, jstring);
  1074. return true;
  1075. }
  1076. static const char *mode_to_string(int mode)
  1077. {
  1078. switch (mode) {
  1079. case MESH_MODE_DISABLED:
  1080. return "disabled";
  1081. case MESH_MODE_ENABLED:
  1082. return "enabled";
  1083. default:
  1084. return "unsupported";
  1085. }
  1086. }
  1087. static bool write_mode(json_object *jobj, const char *desc, int value)
  1088. {
  1089. json_object *jstring;
  1090. jstring = json_object_new_string(mode_to_string(value));
  1091. if (!jstring)
  1092. return false;
  1093. json_object_object_del(jobj, desc);
  1094. json_object_object_add(jobj, desc, jstring);
  1095. return true;
  1096. }
  1097. bool mesh_config_write_mode(struct mesh_config *cfg, const char *keyword,
  1098. int value)
  1099. {
  1100. if (!cfg || !write_mode(cfg->jnode, keyword, value))
  1101. return false;
  1102. return save_config(cfg->jnode, cfg->node_dir_path);
  1103. }
  1104. static bool write_relay_mode(json_object *jobj, uint8_t mode,
  1105. uint8_t count, uint16_t interval)
  1106. {
  1107. json_object *jrelay;
  1108. json_object_object_del(jobj, "relay");
  1109. jrelay = json_object_new_object();
  1110. if (!jrelay)
  1111. return false;
  1112. if (!write_mode(jrelay, "mode", mode))
  1113. goto fail;
  1114. if (!write_int(jrelay, "count", count))
  1115. goto fail;
  1116. if (!write_int(jrelay, "interval", interval))
  1117. goto fail;
  1118. json_object_object_add(jobj, "relay", jrelay);
  1119. return true;
  1120. fail:
  1121. json_object_put(jrelay);
  1122. return false;
  1123. }
  1124. bool mesh_config_write_unicast(struct mesh_config *cfg, uint16_t unicast)
  1125. {
  1126. if (!cfg || !write_uint16_hex(cfg->jnode, "unicastAddress", unicast))
  1127. return false;
  1128. return save_config(cfg->jnode, cfg->node_dir_path);
  1129. }
  1130. bool mesh_config_write_relay_mode(struct mesh_config *cfg, uint8_t mode,
  1131. uint8_t count, uint16_t interval)
  1132. {
  1133. if (!cfg || !write_relay_mode(cfg->jnode, mode, count, interval))
  1134. return false;
  1135. return save_config(cfg->jnode, cfg->node_dir_path);
  1136. }
  1137. bool mesh_config_write_net_transmit(struct mesh_config *cfg, uint8_t cnt,
  1138. uint16_t interval)
  1139. {
  1140. json_object *jnode, *jrtx;
  1141. if (!cfg)
  1142. return false;
  1143. jnode = cfg->jnode;
  1144. jrtx = json_object_new_object();
  1145. if (!jrtx)
  1146. return false;
  1147. if (!write_int(jrtx, "count", cnt))
  1148. goto fail;
  1149. if (!write_int(jrtx, "interval", interval))
  1150. goto fail;
  1151. json_object_object_del(jnode, "retransmit");
  1152. json_object_object_add(jnode, "retransmit", jrtx);
  1153. return save_config(cfg->jnode, cfg->node_dir_path);
  1154. fail:
  1155. json_object_put(jrtx);
  1156. return false;
  1157. }
  1158. bool mesh_config_write_iv_index(struct mesh_config *cfg, uint32_t idx,
  1159. bool update)
  1160. {
  1161. json_object *jnode;
  1162. int tmp = update ? 1 : 0;
  1163. if (!cfg)
  1164. return false;
  1165. jnode = cfg->jnode;
  1166. if (!write_int(jnode, "IVindex", idx))
  1167. return false;
  1168. if (!write_int(jnode, "IVupdate", tmp))
  1169. return false;
  1170. return save_config(jnode, cfg->node_dir_path);
  1171. }
  1172. static void add_model(void *a, void *b)
  1173. {
  1174. struct mesh_config_model *mod = a;
  1175. json_object *jmodels = b, *jmodel, *jval;
  1176. bool result;
  1177. jmodel = json_object_new_object();
  1178. if (!jmodel)
  1179. return;
  1180. result = (mod->vendor) ? write_uint32_hex(jmodel, "modelId", mod->id) :
  1181. write_uint16_hex(jmodel, "modelId", (uint16_t) mod->id);
  1182. if (!result) {
  1183. json_object_put(jmodel);
  1184. return;
  1185. }
  1186. jval = json_object_new_boolean(mod->sub_enabled);
  1187. json_object_object_add(jmodel, "subEnabled", jval);
  1188. jval = json_object_new_boolean(mod->pub_enabled);
  1189. json_object_object_add(jmodel, "pubEnabled", jval);
  1190. json_object_array_add(jmodels, jmodel);
  1191. }
  1192. /* Add unprovisioned node (local) */
  1193. static struct mesh_config *create_config(const char *cfg_path,
  1194. const uint8_t uuid[16],
  1195. struct mesh_config_node *node)
  1196. {
  1197. struct mesh_config_modes *modes = &node->modes;
  1198. const struct l_queue_entry *entry;
  1199. json_object *jnode, *jelems;
  1200. struct mesh_config *cfg;
  1201. if (!cfg_path || !node)
  1202. return NULL;
  1203. jnode = json_object_new_object();
  1204. /* CID, PID, VID, crpl */
  1205. if (!write_uint16_hex(jnode, "cid", node->cid))
  1206. return NULL;
  1207. if (!write_uint16_hex(jnode, "pid", node->pid))
  1208. return NULL;
  1209. if (!write_uint16_hex(jnode, "vid", node->vid))
  1210. return NULL;
  1211. if (!write_uint16_hex(jnode, "crpl", node->crpl))
  1212. return NULL;
  1213. /* Features: relay, LPN, friend, proxy*/
  1214. if (!write_relay_mode(jnode, modes->relay.state,
  1215. modes->relay.cnt, modes->relay.interval))
  1216. return NULL;
  1217. if (!write_mode(jnode, "lowPower", modes->lpn))
  1218. return NULL;
  1219. if (!write_mode(jnode, "friend", modes->friend))
  1220. return NULL;
  1221. if (!write_mode(jnode, "proxy", modes->proxy))
  1222. return NULL;
  1223. /* Beaconing state */
  1224. if (!write_mode(jnode, "beacon", modes->beacon))
  1225. return NULL;
  1226. /* Sequence number */
  1227. json_object_object_add(jnode, "sequenceNumber",
  1228. json_object_new_int(node->seq_number));
  1229. /* Default TTL */
  1230. json_object_object_add(jnode, "defaultTTL",
  1231. json_object_new_int(node->ttl));
  1232. /* Elements */
  1233. jelems = json_object_new_array();
  1234. if (!jelems)
  1235. return NULL;
  1236. entry = l_queue_get_entries(node->elements);
  1237. for (; entry; entry = entry->next) {
  1238. struct mesh_config_element *ele = entry->data;
  1239. json_object *jelement, *jmodels;
  1240. jelement = json_object_new_object();
  1241. if (!jelement)
  1242. goto fail;
  1243. json_object_array_add(jelems, jelement);
  1244. if (!write_int(jelement, "elementIndex", ele->index))
  1245. goto fail;
  1246. if (!write_uint16_hex(jelement, "location", ele->location))
  1247. goto fail;
  1248. /* Models */
  1249. if (l_queue_isempty(ele->models))
  1250. continue;
  1251. jmodels = json_object_new_array();
  1252. if (!jmodels)
  1253. goto fail;
  1254. json_object_object_add(jelement, "models", jmodels);
  1255. l_queue_foreach(ele->models, add_model, jmodels);
  1256. }
  1257. json_object_object_add(jnode, "elements", jelems);
  1258. cfg = l_new(struct mesh_config, 1);
  1259. cfg->jnode = jnode;
  1260. memcpy(cfg->uuid, uuid, 16);
  1261. cfg->node_dir_path = l_strdup(cfg_path);
  1262. cfg->write_seq = node->seq_number;
  1263. cfg->idles = l_queue_new();
  1264. gettimeofday(&cfg->write_time, NULL);
  1265. return cfg;
  1266. fail:
  1267. json_object_put(jelems);
  1268. return NULL;
  1269. }
  1270. struct mesh_config *mesh_config_create(const char *cfgdir_name,
  1271. const uint8_t uuid[16], struct mesh_config_node *db_node)
  1272. {
  1273. char uuid_buf[33];
  1274. char name_buf[PATH_MAX];
  1275. struct mesh_config *cfg;
  1276. size_t max_len = strlen(cfgnode_name) + strlen(bak_ext);
  1277. if (!hex2str((uint8_t *) uuid, 16, uuid_buf, sizeof(uuid_buf)))
  1278. return NULL;
  1279. snprintf(name_buf, PATH_MAX, "%s/%s", cfgdir_name, uuid_buf);
  1280. if (strlen(name_buf) + max_len >= PATH_MAX)
  1281. return NULL;
  1282. /* Create a new directory and node.json file */
  1283. if (mkdir(name_buf, 0755) != 0)
  1284. return NULL;
  1285. snprintf(name_buf, PATH_MAX, "%s/%s%s", cfgdir_name, uuid_buf,
  1286. cfgnode_name);
  1287. l_debug("New node config %s", name_buf);
  1288. cfg = create_config(name_buf, uuid, db_node);
  1289. if (!cfg)
  1290. return NULL;
  1291. if (!mesh_config_save(cfg, true, NULL, NULL)) {
  1292. mesh_config_release(cfg);
  1293. return NULL;
  1294. }
  1295. return cfg;
  1296. }
  1297. static void finish_key_refresh(json_object *jobj, uint16_t net_idx)
  1298. {
  1299. json_object *jarray;
  1300. int i, len;
  1301. /* Clean up all the bound appkeys */
  1302. if (!json_object_object_get_ex(jobj, "appKeys", &jarray))
  1303. return;
  1304. len = json_object_array_length(jarray);
  1305. for (i = 0; i < len; ++i) {
  1306. json_object *jentry;
  1307. uint16_t idx;
  1308. jentry = json_object_array_get_idx(jarray, i);
  1309. if (!get_key_index(jentry, "boundNetKey", &idx))
  1310. continue;
  1311. if (idx != net_idx)
  1312. continue;
  1313. json_object_object_del(jentry, "oldKey");
  1314. if (!get_key_index(jentry, "index", &idx))
  1315. continue;
  1316. }
  1317. }
  1318. bool mesh_config_net_key_set_phase(struct mesh_config *cfg, uint16_t idx,
  1319. uint8_t phase)
  1320. {
  1321. json_object *jnode, *jarray, *jentry = NULL;
  1322. if (!cfg)
  1323. return false;
  1324. jnode = cfg->jnode;
  1325. if (json_object_object_get_ex(jnode, "netKeys", &jarray))
  1326. jentry = get_key_object(jarray, idx);
  1327. if (!jentry)
  1328. return false;
  1329. json_object_object_del(jentry, "keyRefresh");
  1330. json_object_object_add(jentry, "keyRefresh",
  1331. json_object_new_int(phase));
  1332. if (phase == KEY_REFRESH_PHASE_NONE) {
  1333. json_object_object_del(jentry, "oldKey");
  1334. finish_key_refresh(jnode, idx);
  1335. }
  1336. return save_config(jnode, cfg->node_dir_path);
  1337. }
  1338. bool mesh_config_model_pub_add(struct mesh_config *cfg, uint16_t ele_addr,
  1339. uint32_t mod_id, bool vendor,
  1340. struct mesh_config_pub *pub)
  1341. {
  1342. json_object *jnode, *jmodel, *jpub, *jrtx;
  1343. bool res;
  1344. int ele_idx;
  1345. if (!cfg)
  1346. return false;
  1347. jnode = cfg->jnode;
  1348. ele_idx = get_element_index(jnode, ele_addr);
  1349. if (ele_idx < 0)
  1350. return false;
  1351. jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
  1352. if (!jmodel)
  1353. return false;
  1354. json_object_object_del(jmodel, "publish");
  1355. jpub = json_object_new_object();
  1356. if (!jpub)
  1357. return false;
  1358. if (pub->virt)
  1359. res = add_key_value(jpub, "address", pub->virt_addr);
  1360. else
  1361. res = write_uint16_hex(jpub, "address", pub->addr);
  1362. if (!res)
  1363. goto fail;
  1364. if (!write_int(jpub, "index", pub->idx))
  1365. goto fail;
  1366. if (!write_int(jpub, "ttl", pub->ttl))
  1367. goto fail;
  1368. if (!write_int(jpub, "period", pub->period))
  1369. goto fail;
  1370. if (!write_int(jpub, "credentials", pub->credential ? 1 : 0))
  1371. goto fail;
  1372. jrtx = json_object_new_object();
  1373. if (!jrtx)
  1374. goto fail;
  1375. if (!write_int(jrtx, "count", pub->cnt))
  1376. goto fail;
  1377. if (!write_int(jrtx, "interval", pub->interval))
  1378. goto fail;
  1379. json_object_object_add(jpub, "retransmit", jrtx);
  1380. json_object_object_add(jmodel, "publish", jpub);
  1381. return save_config(jnode, cfg->node_dir_path);
  1382. fail:
  1383. json_object_put(jpub);
  1384. return false;
  1385. }
  1386. static bool delete_model_property(json_object *jnode, uint16_t ele_addr,
  1387. uint32_t mod_id, bool vendor, const char *keyword)
  1388. {
  1389. json_object *jmodel;
  1390. int ele_idx;
  1391. ele_idx = get_element_index(jnode, ele_addr);
  1392. if (ele_idx < 0)
  1393. return false;
  1394. jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
  1395. if (!jmodel)
  1396. return false;
  1397. json_object_object_del(jmodel, keyword);
  1398. return true;
  1399. }
  1400. bool mesh_config_model_pub_del(struct mesh_config *cfg, uint16_t addr,
  1401. uint32_t mod_id, bool vendor)
  1402. {
  1403. if (!cfg || !delete_model_property(cfg->jnode, addr, mod_id, vendor,
  1404. "publish"))
  1405. return false;
  1406. return save_config(cfg->jnode, cfg->node_dir_path);
  1407. }
  1408. static void del_page(json_object *jarray, uint8_t page)
  1409. {
  1410. char buf[3];
  1411. int i, len;
  1412. if (!jarray)
  1413. return;
  1414. snprintf(buf, 3, "%2.2x", page);
  1415. len = json_object_array_length(jarray);
  1416. for (i = 0; i < len; i++) {
  1417. json_object *jentry;
  1418. char *str;
  1419. jentry = json_object_array_get_idx(jarray, i);
  1420. str = (char *)json_object_get_string(jentry);
  1421. /* Delete matching page(s) */
  1422. if (!memcmp(str, buf, 2))
  1423. json_object_array_del_idx(jarray, i, 1);
  1424. }
  1425. }
  1426. bool mesh_config_comp_page_add(struct mesh_config *cfg, uint8_t page,
  1427. uint8_t *data, uint16_t size)
  1428. {
  1429. json_object *jnode, *jstring, *jarray = NULL;
  1430. char *buf;
  1431. int len;
  1432. if (!cfg)
  1433. return false;
  1434. jnode = cfg->jnode;
  1435. json_object_object_get_ex(jnode, "pages", &jarray);
  1436. len = (size * 2) + 3;
  1437. buf = l_malloc(len);
  1438. snprintf(buf, len, "%2.2x", page);
  1439. hex2str(data, size, buf + 2, len - 2);
  1440. if (jarray && jarray_has_string(jarray, buf, len)) {
  1441. l_free(buf);
  1442. return true;
  1443. } else if (!jarray) {
  1444. jarray = json_object_new_array();
  1445. json_object_object_add(jnode, "pages", jarray);
  1446. } else
  1447. del_page(jarray, page);
  1448. jstring = json_object_new_string(buf);
  1449. json_object_array_add(jarray, jstring);
  1450. l_free(buf);
  1451. return save_config(jnode, cfg->node_dir_path);
  1452. }
  1453. bool mesh_config_comp_page_mv(struct mesh_config *cfg, uint8_t old, uint8_t nw)
  1454. {
  1455. json_object *jnode, *jarray = NULL;
  1456. uint8_t *data;
  1457. char *str;
  1458. char old_buf[3];
  1459. int i, len, dlen = 0;
  1460. bool status = true;
  1461. if (!cfg || old == nw)
  1462. return false;
  1463. jnode = cfg->jnode;
  1464. json_object_object_get_ex(jnode, "pages", &jarray);
  1465. if (!jarray)
  1466. return false;
  1467. snprintf(old_buf, 3, "%2.2x", old);
  1468. data = l_malloc(MAX_MSG_LEN);
  1469. len = json_object_array_length(jarray);
  1470. for (i = 0; i < len; i++) {
  1471. json_object *jentry;
  1472. jentry = json_object_array_get_idx(jarray, i);
  1473. str = (char *)json_object_get_string(jentry);
  1474. /* Delete matching page(s) but save data*/
  1475. if (!memcmp(str, old_buf, 2)) {
  1476. dlen = strlen(str + 2);
  1477. str2hex(str + 2, dlen, data, MAX_MSG_LEN);
  1478. dlen /= 2;
  1479. json_object_array_del_idx(jarray, i, 1);
  1480. }
  1481. }
  1482. if (dlen)
  1483. status = mesh_config_comp_page_add(cfg, nw, data, dlen);
  1484. l_free(data);
  1485. return status;
  1486. }
  1487. bool mesh_config_model_sub_add(struct mesh_config *cfg, uint16_t ele_addr,
  1488. uint32_t mod_id, bool vendor,
  1489. struct mesh_config_sub *sub)
  1490. {
  1491. json_object *jnode, *jmodel, *jstring, *jarray = NULL;
  1492. int ele_idx, len;
  1493. char buf[33];
  1494. if (!cfg)
  1495. return false;
  1496. jnode = cfg->jnode;
  1497. ele_idx = get_element_index(jnode, ele_addr);
  1498. if (ele_idx < 0)
  1499. return false;
  1500. jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
  1501. if (!jmodel)
  1502. return false;
  1503. if (!sub->virt) {
  1504. snprintf(buf, 5, "%4.4x", sub->addr.grp);
  1505. len = 4;
  1506. } else {
  1507. hex2str(sub->addr.label, 16, buf, 33);
  1508. len = 32;
  1509. }
  1510. json_object_object_get_ex(jmodel, "subscribe", &jarray);
  1511. if (jarray && jarray_has_string(jarray, buf, len))
  1512. return true;
  1513. jstring = json_object_new_string(buf);
  1514. if (!jstring)
  1515. return false;
  1516. if (!jarray) {
  1517. jarray = json_object_new_array();
  1518. if (!jarray) {
  1519. json_object_put(jstring);
  1520. return false;
  1521. }
  1522. json_object_object_add(jmodel, "subscribe", jarray);
  1523. }
  1524. json_object_array_add(jarray, jstring);
  1525. return save_config(jnode, cfg->node_dir_path);
  1526. }
  1527. bool mesh_config_model_sub_del(struct mesh_config *cfg, uint16_t ele_addr,
  1528. uint32_t mod_id, bool vendor,
  1529. struct mesh_config_sub *sub)
  1530. {
  1531. json_object *jnode, *jmodel, *jarray;
  1532. char buf[33];
  1533. int len, ele_idx;
  1534. if (!cfg)
  1535. return false;
  1536. jnode = cfg->jnode;
  1537. ele_idx = get_element_index(jnode, ele_addr);
  1538. if (ele_idx < 0)
  1539. return false;
  1540. jmodel = get_element_model(jnode, ele_idx, mod_id, vendor);
  1541. if (!jmodel)
  1542. return false;
  1543. if (!json_object_object_get_ex(jmodel, "subscribe", &jarray))
  1544. return true;
  1545. if (!sub->virt) {
  1546. snprintf(buf, 5, "%4.4x", sub->addr.grp);
  1547. len = 4;
  1548. } else {
  1549. hex2str(sub->addr.label, 16, buf, 33);
  1550. len = 32;
  1551. }
  1552. jarray_string_del(jarray, buf, len);
  1553. if (!json_object_array_length(jarray))
  1554. json_object_object_del(jmodel, "subscribe");
  1555. return save_config(jnode, cfg->node_dir_path);
  1556. }
  1557. bool mesh_config_model_sub_del_all(struct mesh_config *cfg, uint16_t addr,
  1558. uint32_t mod_id, bool vendor)
  1559. {
  1560. if (!cfg || !delete_model_property(cfg->jnode, addr, mod_id, vendor,
  1561. "subscribe"))
  1562. return false;
  1563. return save_config(cfg->jnode, cfg->node_dir_path);
  1564. }
  1565. bool mesh_config_model_pub_enable(struct mesh_config *cfg, uint16_t ele_addr,
  1566. uint32_t mod_id, bool vendor,
  1567. bool enable)
  1568. {
  1569. json_object *jmodel, *jval;
  1570. int ele_idx;
  1571. if (!cfg)
  1572. return false;
  1573. ele_idx = get_element_index(cfg->jnode, ele_addr);
  1574. if (ele_idx < 0)
  1575. return false;
  1576. jmodel = get_element_model(cfg->jnode, ele_idx, mod_id, vendor);
  1577. if (!jmodel)
  1578. return false;
  1579. json_object_object_del(jmodel, "pubDisabled");
  1580. jval = json_object_new_boolean(!enable);
  1581. json_object_object_add(jmodel, "pubDisabled", jval);
  1582. if (!enable)
  1583. json_object_object_del(jmodel, "publish");
  1584. return save_config(cfg->jnode, cfg->node_dir_path);
  1585. }
  1586. bool mesh_config_model_sub_enable(struct mesh_config *cfg, uint16_t ele_addr,
  1587. uint32_t mod_id, bool vendor,
  1588. bool enable)
  1589. {
  1590. json_object *jmodel, *jval;
  1591. int ele_idx;
  1592. if (!cfg)
  1593. return false;
  1594. ele_idx = get_element_index(cfg->jnode, ele_addr);
  1595. if (ele_idx < 0)
  1596. return false;
  1597. jmodel = get_element_model(cfg->jnode, ele_idx, mod_id, vendor);
  1598. if (!jmodel)
  1599. return false;
  1600. json_object_object_del(jmodel, "subEnabled");
  1601. jval = json_object_new_boolean(enable);
  1602. json_object_object_add(jmodel, "subEnabled", jval);
  1603. if (!enable)
  1604. json_object_object_del(jmodel, "subscribe");
  1605. return save_config(cfg->jnode, cfg->node_dir_path);
  1606. }
  1607. bool mesh_config_write_seq_number(struct mesh_config *cfg, uint32_t seq,
  1608. bool cache)
  1609. {
  1610. int value = 0;
  1611. uint32_t cached = 0;
  1612. if (!cfg)
  1613. return false;
  1614. if (!cache) {
  1615. if (!write_int(cfg->jnode, "sequenceNumber", seq))
  1616. return false;
  1617. return mesh_config_save(cfg, true, NULL, NULL);
  1618. }
  1619. /* If resetting seq to Zero, make sure cached value reset as well */
  1620. if (seq && get_int(cfg->jnode, "sequenceNumber", &value))
  1621. cached = (uint32_t)value;
  1622. /*
  1623. * When sequence number approaches value stored on disk, calculate
  1624. * average time between sequence number updates, then overcommit the
  1625. * sequence number by MIN_SEQ_CACHE_TIME seconds worth of traffic or
  1626. * MIN_SEQ_CACHE_VALUE (whichever is greater) to avoid frequent writes
  1627. * to disk and to protect against crashes.
  1628. *
  1629. * The real value will be saved when daemon shuts down properly.
  1630. */
  1631. if (seq + MIN_SEQ_CACHE_TRIGGER >= cached) {
  1632. struct timeval now;
  1633. struct timeval elapsed;
  1634. uint64_t elapsed_ms;
  1635. gettimeofday(&now, NULL);
  1636. timersub(&now, &cfg->write_time, &elapsed);
  1637. elapsed_ms = elapsed.tv_sec * 1000 + elapsed.tv_usec / 1000;
  1638. /*
  1639. * If time since last write is zero, this means that
  1640. * idle_save_config is already pending, so we don't need to do
  1641. * anything.
  1642. */
  1643. if (!elapsed_ms)
  1644. return true;
  1645. cached = seq + (seq - cfg->write_seq) *
  1646. 1000 * MIN_SEQ_CACHE_TIME / elapsed_ms;
  1647. if (cached < seq + MIN_SEQ_CACHE_VALUE)
  1648. cached = seq + MIN_SEQ_CACHE_VALUE;
  1649. /* Cap the seq cache maximum to fixed out-of-range value.
  1650. * If daemon restarts with out-of-range value, no packets
  1651. * are to be sent until IV Update procedure completes.
  1652. */
  1653. if (cached > SEQ_MASK)
  1654. cached = SEQ_MASK + 1;
  1655. cfg->write_seq = seq;
  1656. /* Don't rewrite NVM storage if unchanged */
  1657. if (value == (int) cached)
  1658. return true;
  1659. l_debug("Seq Cache: %d -> %d", seq, cached);
  1660. if (!write_int(cfg->jnode, "sequenceNumber", cached))
  1661. return false;
  1662. return mesh_config_save(cfg, false, NULL, NULL);
  1663. }
  1664. return true;
  1665. }
  1666. bool mesh_config_write_ttl(struct mesh_config *cfg, uint8_t ttl)
  1667. {
  1668. if (!cfg || !write_int(cfg->jnode, "defaultTTL", ttl))
  1669. return false;
  1670. return save_config(cfg->jnode, cfg->node_dir_path);
  1671. }
  1672. bool mesh_config_update_company_id(struct mesh_config *cfg, uint16_t cid)
  1673. {
  1674. if (!cfg || !write_uint16_hex(cfg->jnode, "cid", cid))
  1675. return false;
  1676. return save_config(cfg->jnode, cfg->node_dir_path);
  1677. }
  1678. bool mesh_config_update_product_id(struct mesh_config *cfg, uint16_t pid)
  1679. {
  1680. if (!cfg || !write_uint16_hex(cfg->jnode, "pid", pid))
  1681. return false;
  1682. return save_config(cfg->jnode, cfg->node_dir_path);
  1683. }
  1684. bool mesh_config_update_version_id(struct mesh_config *cfg, uint16_t vid)
  1685. {
  1686. if (!cfg || !write_uint16_hex(cfg->jnode, "vid", vid))
  1687. return false;
  1688. return save_config(cfg->jnode, cfg->node_dir_path);
  1689. }
  1690. bool mesh_config_update_crpl(struct mesh_config *cfg, uint16_t crpl)
  1691. {
  1692. if (!cfg || !write_uint16_hex(cfg->jnode, "crpl", crpl))
  1693. return false;
  1694. return save_config(cfg->jnode, cfg->node_dir_path);
  1695. }
  1696. static bool load_node(const char *fname, const uint8_t uuid[16],
  1697. mesh_config_node_func_t cb, void *user_data)
  1698. {
  1699. int fd;
  1700. char *str;
  1701. struct stat st;
  1702. ssize_t sz;
  1703. bool result = false;
  1704. json_object *jnode;
  1705. struct mesh_config_node node;
  1706. if (!cb) {
  1707. l_info("Node read callback is required");
  1708. return false;
  1709. }
  1710. l_info("Loading configuration from %s", fname);
  1711. fd = open(fname, O_RDONLY);
  1712. if (fd < 0)
  1713. return false;
  1714. if (fstat(fd, &st) == -1) {
  1715. close(fd);
  1716. return false;
  1717. }
  1718. str = (char *) l_new(char, st.st_size + 1);
  1719. if (!str) {
  1720. close(fd);
  1721. return false;
  1722. }
  1723. sz = read(fd, str, st.st_size);
  1724. if (sz != st.st_size) {
  1725. l_error("Failed to read configuration file %s", fname);
  1726. goto done;
  1727. }
  1728. jnode = json_tokener_parse(str);
  1729. if (!jnode)
  1730. goto done;
  1731. memset(&node, 0, sizeof(node));
  1732. node.elements = l_queue_new();
  1733. node.netkeys = l_queue_new();
  1734. node.appkeys = l_queue_new();
  1735. node.pages = l_queue_new();
  1736. result = read_node(jnode, &node);
  1737. if (result) {
  1738. struct mesh_config *cfg = l_new(struct mesh_config, 1);
  1739. cfg->jnode = jnode;
  1740. memcpy(cfg->uuid, uuid, 16);
  1741. cfg->node_dir_path = l_strdup(fname);
  1742. cfg->write_seq = node.seq_number;
  1743. cfg->idles = l_queue_new();
  1744. gettimeofday(&cfg->write_time, NULL);
  1745. result = cb(&node, uuid, cfg, user_data);
  1746. if (!result) {
  1747. l_free(cfg->idles);
  1748. l_free(cfg->node_dir_path);
  1749. l_free(cfg);
  1750. }
  1751. }
  1752. /* Done with the node: free resources */
  1753. l_free(node.net_transmit);
  1754. l_queue_destroy(node.netkeys, l_free);
  1755. l_queue_destroy(node.appkeys, l_free);
  1756. l_queue_destroy(node.pages, l_free);
  1757. l_queue_destroy(node.elements, free_element);
  1758. if (!result)
  1759. json_object_put(jnode);
  1760. done:
  1761. close(fd);
  1762. if (str)
  1763. l_free(str);
  1764. return result;
  1765. }
  1766. static void release_idle(void *data)
  1767. {
  1768. struct l_idle *idle = data;
  1769. l_idle_remove(idle);
  1770. }
  1771. void mesh_config_release(struct mesh_config *cfg)
  1772. {
  1773. if (!cfg)
  1774. return;
  1775. l_queue_destroy(cfg->idles, release_idle);
  1776. l_free(cfg->node_dir_path);
  1777. json_object_put(cfg->jnode);
  1778. l_free(cfg);
  1779. }
  1780. static void idle_save_config(struct l_idle *idle, void *user_data)
  1781. {
  1782. struct write_info *info = user_data;
  1783. char *fname_tmp, *fname_bak, *fname_cfg;
  1784. bool result = false;
  1785. fname_cfg = info->cfg->node_dir_path;
  1786. fname_tmp = l_strdup_printf("%s%s", fname_cfg, tmp_ext);
  1787. fname_bak = l_strdup_printf("%s%s", fname_cfg, bak_ext);
  1788. remove(fname_tmp);
  1789. result = save_config(info->cfg->jnode, fname_tmp);
  1790. if (result) {
  1791. remove(fname_bak);
  1792. if (rename(fname_cfg, fname_bak) < 0 ||
  1793. rename(fname_tmp, fname_cfg) < 0)
  1794. result = false;
  1795. }
  1796. remove(fname_tmp);
  1797. l_free(fname_tmp);
  1798. l_free(fname_bak);
  1799. gettimeofday(&info->cfg->write_time, NULL);
  1800. if (info->cb)
  1801. info->cb(info->user_data, result);
  1802. if (idle) {
  1803. l_queue_remove(info->cfg->idles, idle);
  1804. l_idle_remove(idle);
  1805. }
  1806. l_free(info);
  1807. }
  1808. bool mesh_config_save(struct mesh_config *cfg, bool no_wait,
  1809. mesh_config_status_func_t cb, void *user_data)
  1810. {
  1811. struct write_info *info;
  1812. if (!cfg)
  1813. return false;
  1814. info = l_new(struct write_info, 1);
  1815. info->cfg = cfg;
  1816. info->cb = cb;
  1817. info->user_data = user_data;
  1818. if (no_wait) {
  1819. idle_save_config(NULL, info);
  1820. } else {
  1821. struct l_idle *idle;
  1822. idle = l_idle_create(idle_save_config, info, NULL);
  1823. l_queue_push_tail(cfg->idles, idle);
  1824. }
  1825. return true;
  1826. }
  1827. bool mesh_config_load_nodes(const char *cfgdir_name, mesh_config_node_func_t cb,
  1828. void *user_data)
  1829. {
  1830. DIR *cfgdir;
  1831. struct dirent *entry;
  1832. size_t path_len = strlen(cfgdir_name) + strlen(cfgnode_name) +
  1833. strlen(bak_ext);
  1834. create_dir(cfgdir_name);
  1835. cfgdir = opendir(cfgdir_name);
  1836. if (!cfgdir) {
  1837. l_error("Failed to open mesh node storage directory: %s",
  1838. cfgdir_name);
  1839. return false;
  1840. }
  1841. while ((entry = readdir(cfgdir)) != NULL) {
  1842. char *dirname, *fname, *bak;
  1843. uint8_t uuid[16];
  1844. size_t node_len;
  1845. if (entry->d_type != DT_DIR)
  1846. continue;
  1847. /* Check path length */
  1848. node_len = strlen(entry->d_name);
  1849. if (path_len + node_len + 1 >= PATH_MAX)
  1850. continue;
  1851. if (!str2hex(entry->d_name, node_len, uuid, sizeof(uuid)))
  1852. continue;
  1853. dirname = l_strdup_printf("%s/%s", cfgdir_name, entry->d_name);
  1854. fname = l_strdup_printf("%s%s", dirname, cfgnode_name);
  1855. if (!load_node(fname, uuid, cb, user_data)) {
  1856. /* Fall-back to Backup version */
  1857. bak = l_strdup_printf("%s%s", fname, bak_ext);
  1858. if (load_node(bak, uuid, cb, user_data)) {
  1859. remove(fname);
  1860. rename(bak, fname);
  1861. }
  1862. l_free(bak);
  1863. }
  1864. l_free(fname);
  1865. l_free(dirname);
  1866. }
  1867. closedir(cfgdir);
  1868. return true;
  1869. }
  1870. void mesh_config_destroy_nvm(struct mesh_config *cfg)
  1871. {
  1872. char *node_dir, *node_name;
  1873. char uuid[33];
  1874. if (!cfg)
  1875. return;
  1876. node_dir = dirname(cfg->node_dir_path);
  1877. l_debug("Delete node config %s", node_dir);
  1878. if (!hex2str(cfg->uuid, 16, uuid, sizeof(uuid)))
  1879. return;
  1880. node_name = basename(node_dir);
  1881. /* Make sure path name of node follows expected guidelines */
  1882. if (strcmp(node_name, uuid))
  1883. return;
  1884. del_path(node_dir);
  1885. }