node.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2017 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <stdio.h>
  14. #include <errno.h>
  15. #include <unistd.h>
  16. #include <stdlib.h>
  17. #include <stdbool.h>
  18. #include <sys/uio.h>
  19. #include <wordexp.h>
  20. #include <inttypes.h>
  21. #include <glib.h>
  22. #include "src/shared/util.h"
  23. #include "src/shared/shell.h"
  24. #include "gdbus/gdbus.h"
  25. #include "tools/mesh/config-model.h"
  26. #include "tools/mesh-gatt/mesh-net.h"
  27. #include "tools/mesh-gatt/node.h"
  28. #include "tools/mesh-gatt/keys.h"
  29. #include "tools/mesh-gatt/gatt.h"
  30. #include "tools/mesh-gatt/net.h"
  31. #include "tools/mesh-gatt/prov-db.h"
  32. #include "tools/mesh-gatt/util.h"
  33. struct mesh_model {
  34. struct mesh_model_ops cbs;
  35. void *user_data;
  36. GList *bindings;
  37. GList *subscriptions;
  38. uint32_t id;
  39. struct mesh_publication *pub;
  40. };
  41. struct mesh_element {
  42. GList *models;
  43. uint16_t loc;
  44. uint8_t index;
  45. };
  46. struct mesh_node {
  47. const char *name;
  48. GList *net_keys;
  49. GList *app_keys;
  50. void *prov;
  51. GList *elements;
  52. uint32_t iv_index;
  53. uint32_t seq_number;
  54. uint16_t primary_net_idx;
  55. uint16_t primary;
  56. uint16_t oob;
  57. uint16_t features;
  58. uint8_t dev_uuid[16];
  59. uint8_t dev_key[16];
  60. uint8_t num_ele;
  61. uint8_t ttl;
  62. bool provisioner;
  63. struct mesh_node_composition *comp;
  64. };
  65. static GList *nodes;
  66. static struct mesh_node *local_node;
  67. static int match_node_unicast(const void *a, const void *b)
  68. {
  69. const struct mesh_node *node = a;
  70. uint16_t dst = GPOINTER_TO_UINT(b);
  71. if (dst >= node->primary &&
  72. dst <= (node->primary + node->num_ele - 1))
  73. return 0;
  74. return -1;
  75. }
  76. static int match_device_uuid(const void *a, const void *b)
  77. {
  78. const struct mesh_node *node = a;
  79. const uint8_t *uuid = b;
  80. return memcmp(node->dev_uuid, uuid, 16);
  81. }
  82. static int match_element_idx(const void *a, const void *b)
  83. {
  84. const struct mesh_element *element = a;
  85. uint32_t index = GPOINTER_TO_UINT(b);
  86. return (element->index == index) ? 0 : -1;
  87. }
  88. static int match_model_id(const void *a, const void *b)
  89. {
  90. const struct mesh_model *model = a;
  91. uint32_t id = GPOINTER_TO_UINT(b);
  92. return (model->id == id) ? 0 : -1;
  93. }
  94. struct mesh_node *node_find_by_addr(uint16_t addr)
  95. {
  96. GList *l;
  97. if (!IS_UNICAST(addr))
  98. return NULL;
  99. l = g_list_find_custom(nodes, GUINT_TO_POINTER(addr),
  100. match_node_unicast);
  101. if (l)
  102. return l->data;
  103. else
  104. return NULL;
  105. }
  106. struct mesh_node *node_find_by_uuid(uint8_t uuid[16])
  107. {
  108. GList *l;
  109. l = g_list_find_custom(nodes, uuid, match_device_uuid);
  110. if (l)
  111. return l->data;
  112. else
  113. return NULL;
  114. }
  115. struct mesh_node *node_create_new(struct prov_svc_data *prov)
  116. {
  117. struct mesh_node *node;
  118. if (node_find_by_uuid(prov->dev_uuid))
  119. return NULL;
  120. node = g_malloc0(sizeof(struct mesh_node));
  121. if (!node)
  122. return NULL;
  123. memcpy(node->dev_uuid, prov->dev_uuid, 16);
  124. node->oob = prov->oob;
  125. nodes = g_list_append(nodes, node);
  126. return node;
  127. }
  128. struct mesh_node *node_new(void)
  129. {
  130. struct mesh_node *node;
  131. node = g_malloc0(sizeof(struct mesh_node));
  132. if (!node)
  133. return NULL;
  134. nodes = g_list_append(nodes, node);
  135. return node;
  136. }
  137. static void model_free(void *data)
  138. {
  139. struct mesh_model *model = data;
  140. g_list_free(model->bindings);
  141. g_list_free(model->subscriptions);
  142. g_free(model->pub);
  143. g_free(model);
  144. }
  145. static void element_free(void *data)
  146. {
  147. struct mesh_element *element = data;
  148. g_list_free_full(element->models, model_free);
  149. g_free(element);
  150. }
  151. static void free_node_resources(void *data)
  152. {
  153. struct mesh_node *node = data;
  154. g_list_free(node->net_keys);
  155. g_list_free(node->app_keys);
  156. g_list_free_full(node->elements, element_free);
  157. if(node->comp)
  158. g_free(node->comp);
  159. g_free(node);
  160. }
  161. void node_free(struct mesh_node *node)
  162. {
  163. if (!node)
  164. return;
  165. nodes = g_list_remove(nodes, node);
  166. free_node_resources(node);
  167. }
  168. void node_cleanup(void)
  169. {
  170. g_list_free_full(nodes, free_node_resources);
  171. local_node = NULL;
  172. }
  173. bool node_is_provisioned(struct mesh_node *node)
  174. {
  175. return (!IS_UNASSIGNED(node->primary));
  176. }
  177. void *node_get_prov(struct mesh_node *node)
  178. {
  179. return node->prov;
  180. }
  181. void node_set_prov(struct mesh_node *node, void *prov)
  182. {
  183. node->prov = prov;
  184. }
  185. bool node_app_key_add(struct mesh_node *node, uint16_t idx)
  186. {
  187. uint32_t index;
  188. uint16_t net_idx;
  189. if (!node)
  190. return false;
  191. net_idx = keys_app_key_get_bound(idx);
  192. if (net_idx == NET_IDX_INVALID)
  193. return false;
  194. if (!g_list_find(node->net_keys, GUINT_TO_POINTER(net_idx)))
  195. return false;
  196. index = (net_idx << 16) + idx;
  197. if (g_list_find(node->app_keys, GUINT_TO_POINTER(index)))
  198. return false;
  199. node->app_keys = g_list_append(node->app_keys, GUINT_TO_POINTER(index));
  200. return true;
  201. }
  202. bool node_net_key_add(struct mesh_node *node, uint16_t index)
  203. {
  204. if(!node)
  205. return false;
  206. if (g_list_find(node->net_keys, GUINT_TO_POINTER(index)))
  207. return false;
  208. node->net_keys = g_list_append(node->net_keys, GUINT_TO_POINTER(index));
  209. return true;
  210. }
  211. bool node_net_key_delete(struct mesh_node *node, uint16_t index)
  212. {
  213. GList *l;
  214. if(!node)
  215. return false;
  216. l = g_list_find(node->net_keys, GUINT_TO_POINTER(index));
  217. if (!l)
  218. return false;
  219. node->net_keys = g_list_remove(node->net_keys,
  220. GUINT_TO_POINTER(index));
  221. /* TODO: remove all associated app keys and bindings */
  222. return true;
  223. }
  224. bool node_app_key_delete(struct mesh_node *node, uint16_t net_idx,
  225. uint16_t idx)
  226. {
  227. GList *l;
  228. uint32_t index;
  229. if(!node)
  230. return false;
  231. index = (net_idx << 16) + idx;
  232. l = g_list_find(node->app_keys, GUINT_TO_POINTER(index));
  233. if (!l)
  234. return false;
  235. node->app_keys = g_list_remove(node->app_keys,
  236. GUINT_TO_POINTER(index));
  237. /* TODO: remove all associated bindings */
  238. return true;
  239. }
  240. void node_set_primary(struct mesh_node *node, uint16_t unicast)
  241. {
  242. node->primary = unicast;
  243. }
  244. uint16_t node_get_primary(struct mesh_node *node)
  245. {
  246. if (!node)
  247. return UNASSIGNED_ADDRESS;
  248. else
  249. return node->primary;
  250. }
  251. void node_set_device_key(struct mesh_node *node, uint8_t *key)
  252. {
  253. if (!node || !key)
  254. return;
  255. memcpy(node->dev_key, key, 16);
  256. }
  257. uint8_t *node_get_device_key(struct mesh_node *node)
  258. {
  259. if (!node)
  260. return NULL;
  261. else
  262. return node->dev_key;
  263. }
  264. void node_set_num_elements(struct mesh_node *node, uint8_t num_ele)
  265. {
  266. node->num_ele = num_ele;
  267. }
  268. uint8_t node_get_num_elements(struct mesh_node *node)
  269. {
  270. return node->num_ele;
  271. }
  272. GList *node_get_net_keys(struct mesh_node *node)
  273. {
  274. if (!node)
  275. return NULL;
  276. else
  277. return node->net_keys;
  278. }
  279. GList *node_get_app_keys(struct mesh_node *node)
  280. {
  281. if (!node)
  282. return NULL;
  283. else
  284. return node->app_keys;
  285. }
  286. bool node_parse_composition(struct mesh_node *node, uint8_t *data, uint16_t len)
  287. {
  288. struct mesh_node_composition *comp;
  289. uint16_t features;
  290. int i;
  291. comp = g_malloc0(sizeof(struct mesh_node_composition));
  292. if (!comp)
  293. return false;
  294. /* skip page -- We only support Page Zero */
  295. data++;
  296. len--;
  297. comp->cid = get_le16(&data[0]);
  298. comp->pid = get_le16(&data[2]);
  299. comp->vid = get_le16(&data[4]);
  300. comp->crpl = get_le16(&data[6]);
  301. features = get_le16(&data[8]);
  302. data += 10;
  303. len -= 10;
  304. comp->relay = !!(features & MESH_FEATURE_RELAY);
  305. comp->proxy = !!(features & MESH_FEATURE_PROXY);
  306. comp->friend = !!(features & MESH_FEATURE_FRIEND);
  307. comp->lpn = !!(features & MESH_FEATURE_LPN);
  308. for (i = 0; i< node->num_ele; i++) {
  309. uint8_t m, v;
  310. uint32_t mod_id;
  311. uint16_t vendor_id;
  312. struct mesh_element *ele;
  313. ele = g_malloc0(sizeof(struct mesh_element));
  314. if (!ele) {
  315. g_free(comp);
  316. return false;
  317. }
  318. ele->index = i;
  319. ele->loc = get_le16(data);
  320. data += 2;
  321. node->elements = g_list_append(node->elements, ele);
  322. m = *data++;
  323. v = *data++;
  324. len -= 2;
  325. while (len >= 2 && m--) {
  326. mod_id = get_le16(data);
  327. /* initialize uppper 16 bits to 0xffff for SIG models */
  328. mod_id |= 0xffff0000;
  329. if (!node_set_model(node, ele->index, mod_id)) {
  330. g_free(comp);
  331. return false;
  332. }
  333. data += 2;
  334. len -= 2;
  335. }
  336. while (len >= 4 && v--) {
  337. mod_id = get_le16(data + 2);
  338. vendor_id = get_le16(data);
  339. mod_id |= (vendor_id << 16);
  340. if (!node_set_model(node, ele->index, mod_id)) {
  341. g_free(comp);
  342. return false;
  343. }
  344. data += 4;
  345. len -= 4;
  346. }
  347. }
  348. node->comp = comp;
  349. return true;
  350. }
  351. bool node_set_local_node(struct mesh_node *node)
  352. {
  353. if (local_node) {
  354. bt_shell_printf("Local node already registered\n");
  355. return false;
  356. }
  357. net_register_unicast(node->primary, node->num_ele);
  358. local_node = node;
  359. local_node->provisioner = true;
  360. return true;
  361. }
  362. struct mesh_node *node_get_local_node()
  363. {
  364. return local_node;
  365. }
  366. uint16_t node_get_primary_net_idx(struct mesh_node *node)
  367. {
  368. if (node == NULL)
  369. return NET_IDX_INVALID;
  370. return node->primary_net_idx;
  371. }
  372. static bool deliver_model_data(struct mesh_element* element, uint16_t src,
  373. uint16_t app_idx, uint8_t *data, uint16_t len)
  374. {
  375. GList *l;
  376. for(l = element->models; l; l = l->next) {
  377. struct mesh_model *model = l->data;
  378. if (!g_list_find(model->bindings, GUINT_TO_POINTER(app_idx)))
  379. continue;
  380. if (model->cbs.recv &&
  381. model->cbs.recv(src, data, len, model->user_data))
  382. return true;
  383. }
  384. return false;
  385. }
  386. void node_local_data_handler(uint16_t src, uint32_t dst,
  387. uint32_t iv_index, uint32_t seq_num,
  388. uint16_t app_idx, uint8_t *data, uint16_t len)
  389. {
  390. GList *l;
  391. bool res;
  392. uint64_t iv_seq;
  393. uint64_t iv_seq_remote;
  394. uint8_t ele_idx;
  395. struct mesh_element *element;
  396. struct mesh_node *remote;
  397. bool loopback;
  398. if (!local_node || seq_num > 0xffffff)
  399. return;
  400. iv_seq = iv_index << 24;
  401. iv_seq |= seq_num;
  402. remote = node_find_by_addr(src);
  403. if (!remote) {
  404. if (local_node->provisioner) {
  405. bt_shell_printf("Remote node unknown (%4.4x)\n", src);
  406. return;
  407. }
  408. remote = g_new0(struct mesh_node, 1);
  409. if (!remote)
  410. return;
  411. /* Not Provisioner; Assume all SRC elements stand alone */
  412. remote->primary = src;
  413. remote->num_ele = 1;
  414. nodes = g_list_append(nodes, remote);
  415. }
  416. loopback = (src < (local_node->primary + local_node->num_ele) &&
  417. src >= local_node->primary);
  418. if (!loopback) {
  419. iv_seq_remote = remote->iv_index << 24;
  420. iv_seq |= remote->seq_number;
  421. if (iv_seq_remote >= iv_seq) {
  422. bt_shell_printf("Replayed message detected "
  423. "(%016" PRIx64 " >= %016" PRIx64 ")\n",
  424. iv_seq_remote, iv_seq);
  425. return;
  426. }
  427. }
  428. if (IS_GROUP(dst) || IS_VIRTUAL(dst)) {
  429. /* TODO: if subscription address, deliver to subscribers */
  430. return;
  431. }
  432. if (IS_ALL_NODES(dst)) {
  433. ele_idx = 0;
  434. } else {
  435. if (dst >= (local_node->primary + local_node->num_ele) ||
  436. dst < local_node->primary)
  437. return;
  438. ele_idx = dst - local_node->primary;
  439. }
  440. l = g_list_find_custom(local_node->elements,
  441. GUINT_TO_POINTER(ele_idx), match_element_idx);
  442. /* This should not happen */
  443. if (!l)
  444. return;
  445. element = l->data;
  446. res = deliver_model_data(element, src, app_idx, data, len);
  447. if (res && !loopback) {
  448. /* TODO: Save remote in Replay Protection db */
  449. remote->iv_index = iv_index;
  450. remote->seq_number = seq_num;
  451. prov_db_node_set_iv_seq(remote, iv_index, seq_num);
  452. }
  453. }
  454. static gboolean restore_model_state(gpointer data)
  455. {
  456. struct mesh_model *model = data;
  457. GList *l;
  458. struct mesh_model_ops *ops;
  459. ops = &model->cbs;
  460. if (model->bindings && ops->bind) {
  461. for (l = model->bindings; l; l = l->next) {
  462. if (ops->bind(GPOINTER_TO_UINT(l->data), ACTION_ADD) !=
  463. MESH_STATUS_SUCCESS)
  464. break;
  465. }
  466. }
  467. if (model->pub && ops->pub)
  468. ops->pub(model->pub);
  469. g_idle_remove_by_data(data);
  470. return true;
  471. }
  472. bool node_local_model_register(uint8_t ele_idx, uint16_t model_id,
  473. struct mesh_model_ops *ops, void *user_data)
  474. {
  475. uint32_t id = 0xffff0000 | model_id;
  476. return node_local_vendor_model_register(ele_idx, id, ops, user_data);
  477. }
  478. bool node_local_vendor_model_register(uint8_t ele_idx, uint32_t model_id,
  479. struct mesh_model_ops *ops, void *user_data)
  480. {
  481. struct mesh_element *ele;
  482. struct mesh_model *model;
  483. GList *l;
  484. if (!local_node)
  485. return false;
  486. l = g_list_find_custom(local_node->elements, GUINT_TO_POINTER(ele_idx),
  487. match_element_idx);
  488. if (!l)
  489. return false;
  490. ele = l->data;
  491. l = g_list_find_custom(ele->models, GUINT_TO_POINTER(model_id),
  492. match_model_id);
  493. if (!l)
  494. return false;
  495. model = l->data;
  496. model->cbs = *ops;
  497. model->user_data = user_data;
  498. if (model_id >= 0xffff0000)
  499. model_id = model_id & 0xffff;
  500. /* Silently assign device key binding to configuration models */
  501. if (model_id == CONFIG_SERVER_MODEL_ID ||
  502. model_id == CONFIG_CLIENT_MODEL_ID) {
  503. model->bindings = g_list_append(model->bindings,
  504. GUINT_TO_POINTER(APP_IDX_DEV));
  505. } else {
  506. g_idle_add(restore_model_state, model);
  507. }
  508. return true;
  509. }
  510. bool node_set_element(struct mesh_node *node, uint8_t ele_idx)
  511. {
  512. struct mesh_element *ele;
  513. GList *l;
  514. if (!node)
  515. return false;
  516. l = g_list_find_custom(node->elements, GUINT_TO_POINTER(ele_idx),
  517. match_element_idx);
  518. if (l)
  519. return false;
  520. ele = g_malloc0(sizeof(struct mesh_element));
  521. if (!ele)
  522. return false;
  523. ele->index = ele_idx;
  524. node->elements = g_list_append(node->elements, ele);
  525. return true;
  526. }
  527. bool node_set_model(struct mesh_node *node, uint8_t ele_idx, uint32_t id)
  528. {
  529. struct mesh_element *ele;
  530. struct mesh_model *model;
  531. GList *l;
  532. if (!node)
  533. return false;
  534. l = g_list_find_custom(node->elements, GUINT_TO_POINTER(ele_idx),
  535. match_element_idx);
  536. if (!l)
  537. return false;
  538. ele = l->data;
  539. l = g_list_find_custom(ele->models, GUINT_TO_POINTER(id),
  540. match_model_id);
  541. if (l)
  542. return true;
  543. model = g_malloc0(sizeof(struct mesh_model));
  544. if (!model)
  545. return false;
  546. model->id = id;
  547. ele->models = g_list_append(ele->models, model);
  548. return true;
  549. }
  550. bool node_set_composition(struct mesh_node *node,
  551. struct mesh_node_composition *comp)
  552. {
  553. if (!node || !comp || node->comp)
  554. return false;
  555. node->comp = g_malloc0(sizeof(struct mesh_node_composition));
  556. if (!node->comp)
  557. return false;
  558. *(node->comp) = *comp;
  559. return true;
  560. }
  561. struct mesh_node_composition *node_get_composition(struct mesh_node *node)
  562. {
  563. if (!node)
  564. return NULL;
  565. return node->comp;
  566. }
  567. static struct mesh_model *get_model(struct mesh_node *node, uint8_t ele_idx,
  568. uint32_t model_id)
  569. {
  570. struct mesh_element *ele;
  571. GList *l;
  572. if (!node)
  573. return NULL;
  574. l = g_list_find_custom(node->elements, GUINT_TO_POINTER(ele_idx),
  575. match_element_idx);
  576. if (!l)
  577. return NULL;
  578. ele = l->data;
  579. l = g_list_find_custom(ele->models, GUINT_TO_POINTER(model_id),
  580. match_model_id);
  581. if (!l)
  582. return NULL;
  583. return l->data;
  584. }
  585. bool node_add_binding(struct mesh_node *node, uint8_t ele_idx,
  586. uint32_t model_id, uint16_t app_idx)
  587. {
  588. struct mesh_model *model;
  589. GList *l;
  590. model = get_model(node, ele_idx, model_id);
  591. if (!model)
  592. return false;
  593. l = g_list_find(model->bindings, GUINT_TO_POINTER(app_idx));
  594. if (l)
  595. return false;
  596. if ((node == local_node) && model->cbs.bind) {
  597. if (!model->cbs.bind(app_idx, ACTION_ADD))
  598. return false;
  599. }
  600. model->bindings = g_list_append(model->bindings,
  601. GUINT_TO_POINTER(app_idx));
  602. return true;
  603. }
  604. bool node_add_subscription(struct mesh_node *node, uint8_t ele_idx,
  605. uint32_t model_id, uint16_t addr)
  606. {
  607. struct mesh_model *model;
  608. GList *l;
  609. model = get_model(node, ele_idx, model_id);
  610. if (!model)
  611. return false;
  612. l = g_list_find(model->subscriptions, GUINT_TO_POINTER(addr));
  613. if (l)
  614. return false;
  615. model->subscriptions = g_list_append(model->subscriptions,
  616. GUINT_TO_POINTER(addr));
  617. return true;
  618. }
  619. uint8_t node_get_default_ttl(struct mesh_node *node)
  620. {
  621. if (!node)
  622. return DEFAULT_TTL;
  623. else if (node == local_node)
  624. return net_get_default_ttl();
  625. else
  626. return node->ttl;
  627. }
  628. bool node_set_default_ttl(struct mesh_node *node, uint8_t ttl)
  629. {
  630. if (!node)
  631. return false;
  632. node->ttl = ttl;
  633. if (node == local_node || local_node == NULL)
  634. return net_set_default_ttl(ttl);
  635. return true;
  636. }
  637. bool node_set_sequence_number(struct mesh_node *node, uint32_t seq)
  638. {
  639. if (!node)
  640. return false;
  641. node->seq_number = seq;
  642. if (node == local_node || local_node == NULL)
  643. return net_set_seq_num(seq);
  644. return true;
  645. }
  646. uint32_t node_get_sequence_number(struct mesh_node *node)
  647. {
  648. if (!node)
  649. return 0xffffffff;
  650. else if (node == local_node)
  651. return net_get_seq_num();
  652. return node->seq_number;
  653. }
  654. bool node_set_iv_index(struct mesh_node *node, uint32_t iv_index)
  655. {
  656. if (!node)
  657. return false;
  658. node->iv_index = iv_index;
  659. return true;
  660. }
  661. uint32_t node_get_iv_index(struct mesh_node *node)
  662. {
  663. bool update;
  664. if (!node)
  665. return 0xffffffff;
  666. else if (node == local_node)
  667. return net_get_iv_index(&update);
  668. return node->iv_index;
  669. }
  670. bool node_model_pub_set(struct mesh_node *node, uint8_t ele, uint32_t model_id,
  671. struct mesh_publication *pub)
  672. {
  673. struct mesh_model *model;
  674. model = get_model(node, ele, model_id);
  675. if(!model)
  676. return false;
  677. if (!model->pub)
  678. model->pub = g_malloc0(sizeof(struct mesh_publication));
  679. if (!model)
  680. return false;
  681. memcpy(model->pub, pub, (sizeof(struct mesh_publication)));
  682. if((node == local_node) && model->cbs.pub)
  683. model->cbs.pub(pub);
  684. return true;
  685. }
  686. struct mesh_publication *node_model_pub_get(struct mesh_node *node, uint8_t ele,
  687. uint32_t model_id)
  688. {
  689. struct mesh_model *model;
  690. model = get_model(node, ele, model_id);
  691. if(!model)
  692. return NULL;
  693. else
  694. return model->pub;
  695. }