1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <zephyr/sys/atomic.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/sys/byteorder.h>
14
15 #include <zephyr/net/buf.h>
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/conn.h>
18 #include <zephyr/bluetooth/mesh.h>
19
20 #include "common/bt_str.h"
21
22 #include "crypto.h"
23 #include "mesh.h"
24 #include "net.h"
25 #include "rpl.h"
26 #include "lpn.h"
27 #include "friend.h"
28 #include "proxy.h"
29 #include "proxy_cli.h"
30 #include "transport.h"
31 #include "access.h"
32 #include "foundation.h"
33 #include "beacon.h"
34 #include "settings.h"
35 #include "prov.h"
36 #include "cfg.h"
37 #include "statistic.h"
38 #include "sar_cfg_internal.h"
39
40 #define LOG_LEVEL CONFIG_BT_MESH_NET_LOG_LEVEL
41 #include <zephyr/logging/log.h>
42 LOG_MODULE_REGISTER(bt_mesh_net);
43
44 #define LOOPBACK_MAX_PDU_LEN (BT_MESH_NET_HDR_LEN + 16)
45
46 /* Seq limit after IV Update is triggered */
47 #define IV_UPDATE_SEQ_LIMIT CONFIG_BT_MESH_IV_UPDATE_SEQ_LIMIT
48
49 #define IVI(pdu) ((pdu)[0] >> 7)
50 #define NID(pdu) ((pdu)[0] & 0x7f)
51 #define CTL(pdu) ((pdu)[1] >> 7)
52 #define TTL(pdu) ((pdu)[1] & 0x7f)
53 #define SEQ(pdu) (sys_get_be24(&pdu[2]))
54 #define SRC(pdu) (sys_get_be16(&(pdu)[5]))
55 #define DST(pdu) (sys_get_be16(&(pdu)[7]))
56
57 /* Mesh network information for persistent storage. */
58 struct net_val {
59 uint16_t primary_addr;
60 struct bt_mesh_key dev_key;
61 } __packed;
62
63 /* Sequence number information for persistent storage. */
64 struct seq_val {
65 uint8_t val[3];
66 } __packed;
67
68 /* IV Index & IV Update information for persistent storage. */
69 struct iv_val {
70 uint32_t iv_index;
71 uint8_t iv_update:1,
72 iv_duration:7;
73 } __packed;
74
75 static struct {
76 uint32_t src : 15, /* MSb of source is always 0 */
77 seq : 17;
78 } msg_cache[CONFIG_BT_MESH_MSG_CACHE_SIZE];
79 static uint16_t msg_cache_next;
80
81 /* Singleton network context (the implementation only supports one) */
82 struct bt_mesh_net bt_mesh = {
83 .local_queue = SYS_SLIST_STATIC_INIT(&bt_mesh.local_queue),
84 .sar_tx = BT_MESH_SAR_TX_INIT,
85 .sar_rx = BT_MESH_SAR_RX_INIT,
86
87 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
88 .priv_beacon_int = 0x3c,
89 #endif
90 };
91
92 /* MshPRTv1.1: 3.11.5:
93 * "A node shall not start an IV Update procedure more often than once every 192 hours."
94 *
95 * Mark that the IV Index Recovery has been done to prevent two recoveries to be
96 * done before a normal IV Index update has been completed within 96h+96h.
97 */
98 static bool ivi_was_recovered;
99
100 struct loopback_buf {
101 sys_snode_t node;
102 struct bt_mesh_subnet *sub;
103 uint8_t len;
104 uint8_t data[LOOPBACK_MAX_PDU_LEN];
105 };
106
107 K_MEM_SLAB_DEFINE(loopback_buf_pool,
108 sizeof(struct loopback_buf),
109 CONFIG_BT_MESH_LOOPBACK_BUFS, __alignof__(struct loopback_buf));
110
111 static uint32_t dup_cache[CONFIG_BT_MESH_MSG_CACHE_SIZE];
112 static int dup_cache_next;
113
check_dup(struct net_buf_simple * data)114 static bool check_dup(struct net_buf_simple *data)
115 {
116 const uint8_t *tail = net_buf_simple_tail(data);
117 uint32_t val;
118 int i;
119
120 val = sys_get_be32(tail - 4) ^ sys_get_be32(tail - 8);
121
122 for (i = dup_cache_next; i > 0;) {
123 if (dup_cache[--i] == val) {
124 return true;
125 }
126 }
127
128 for (i = ARRAY_SIZE(dup_cache); i > dup_cache_next;) {
129 if (dup_cache[--i] == val) {
130 return true;
131 }
132 }
133
134 dup_cache_next %= ARRAY_SIZE(dup_cache);
135 dup_cache[dup_cache_next++] = val;
136
137 return false;
138 }
139
msg_cache_match(struct net_buf_simple * pdu)140 static bool msg_cache_match(struct net_buf_simple *pdu)
141 {
142 uint16_t i;
143
144 for (i = msg_cache_next; i > 0U;) {
145 if (msg_cache[--i].src == SRC(pdu->data) &&
146 msg_cache[i].seq == (SEQ(pdu->data) & BIT_MASK(17))) {
147 return true;
148 }
149 }
150
151 for (i = ARRAY_SIZE(msg_cache); i > msg_cache_next;) {
152 if (msg_cache[--i].src == SRC(pdu->data) &&
153 msg_cache[i].seq == (SEQ(pdu->data) & BIT_MASK(17))) {
154 return true;
155 }
156 }
157
158 return false;
159 }
160
msg_cache_add(struct bt_mesh_net_rx * rx)161 static void msg_cache_add(struct bt_mesh_net_rx *rx)
162 {
163 msg_cache_next %= ARRAY_SIZE(msg_cache);
164 msg_cache[msg_cache_next].src = rx->ctx.addr;
165 msg_cache[msg_cache_next].seq = rx->seq;
166 msg_cache_next++;
167 }
168
store_iv(bool only_duration)169 static void store_iv(bool only_duration)
170 {
171 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_IV_PENDING);
172
173 if (!only_duration) {
174 /* Always update Seq whenever IV changes */
175 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING);
176 }
177 }
178
bt_mesh_net_seq_store(bool force)179 void bt_mesh_net_seq_store(bool force)
180 {
181 if (!force &&
182 CONFIG_BT_MESH_SEQ_STORE_RATE > 1 &&
183 (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)) {
184 return;
185 }
186
187 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING);
188 }
189
bt_mesh_net_create(uint16_t idx,uint8_t flags,const struct bt_mesh_key * key,uint32_t iv_index)190 int bt_mesh_net_create(uint16_t idx, uint8_t flags, const struct bt_mesh_key *key,
191 uint32_t iv_index)
192 {
193 int err;
194
195 LOG_DBG("idx %u flags 0x%02x iv_index %u", idx, flags, iv_index);
196
197 LOG_DBG("NetKey %s", bt_hex(key, sizeof(struct bt_mesh_key)));
198
199 if (BT_MESH_KEY_REFRESH(flags)) {
200 err = bt_mesh_subnet_set(idx, BT_MESH_KR_PHASE_2, NULL, key);
201 } else {
202 err = bt_mesh_subnet_set(idx, BT_MESH_KR_NORMAL, key, NULL);
203 }
204
205 if (err) {
206 LOG_ERR("Failed creating subnet");
207 return err;
208 }
209
210 (void)memset(msg_cache, 0, sizeof(msg_cache));
211 msg_cache_next = 0U;
212
213 bt_mesh.iv_index = iv_index;
214 atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS,
215 BT_MESH_IV_UPDATE(flags));
216
217 /* If the node is added to a network when the network is in Normal
218 * operation, then it shall operate in Normal operation for at least
219 * 96 hours. If a node is added to a network while the network is
220 * in the IV Update in Progress state, then the node shall be given
221 * the new IV Index value and operate in IV Update in Progress
222 * operation without the restriction of being in this state for at
223 * least 96 hours.
224 */
225 if (BT_MESH_IV_UPDATE(flags)) {
226 bt_mesh.ivu_duration = BT_MESH_IVU_MIN_HOURS;
227 } else {
228 bt_mesh.ivu_duration = 0U;
229 }
230
231 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
232 LOG_DBG("Storing network information persistently");
233 bt_mesh_subnet_store(idx);
234 store_iv(false);
235 }
236
237 return 0;
238 }
239
240 #if defined(CONFIG_BT_MESH_IV_UPDATE_TEST)
bt_mesh_iv_update_test(bool enable)241 void bt_mesh_iv_update_test(bool enable)
242 {
243 atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_TEST, enable);
244 /* Reset the duration variable - needed for some PTS tests */
245 bt_mesh.ivu_duration = 0U;
246 }
247
bt_mesh_iv_update(void)248 bool bt_mesh_iv_update(void)
249 {
250 if (!bt_mesh_is_provisioned()) {
251 LOG_ERR("Not yet provisioned");
252 return false;
253 }
254
255 if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS)) {
256 bt_mesh_net_iv_update(bt_mesh.iv_index, false);
257 } else {
258 bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true);
259 }
260
261 return atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS);
262 }
263 #endif /* CONFIG_BT_MESH_IV_UPDATE_TEST */
264
bt_mesh_net_iv_update(uint32_t iv_index,bool iv_update)265 bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update)
266 {
267 /* Check if IV index should to be recovered. */
268 if (iv_index < bt_mesh.iv_index ||
269 iv_index > bt_mesh.iv_index + 42) {
270 LOG_ERR("IV Index out of sync: 0x%08x != 0x%08x", iv_index, bt_mesh.iv_index);
271 return false;
272 }
273
274 /* Discard [iv, false] --> [iv, true] */
275 if (iv_index == bt_mesh.iv_index && iv_update) {
276 LOG_DBG("Ignore previous IV update procedure");
277 return false;
278 }
279
280 if ((iv_index > bt_mesh.iv_index + 1) ||
281 (iv_index == bt_mesh.iv_index + 1 &&
282 (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) || !iv_update))) {
283 if (ivi_was_recovered &&
284 (bt_mesh.ivu_duration < (2 * BT_MESH_IVU_MIN_HOURS))) {
285 LOG_ERR("IV Index Recovery before minimum delay");
286 return false;
287 }
288
289 /* MshPRTv1.1 allows to initiate an
290 * IV Index Recovery procedure if previous IV update has
291 * been missed. This allows the node to remain
292 * functional.
293 *
294 * Upon receiving and successfully authenticating a
295 * Secure Network beacon for a primary subnet whose
296 * IV Index is 1 or more higher than the current known IV
297 * Index, the node shall set its current IV Index and its
298 * current IV Update procedure state from the values in
299 * this Secure Network beacon.
300 */
301 LOG_WRN("Performing IV Index Recovery");
302 ivi_was_recovered = true;
303 bt_mesh_rpl_clear();
304 bt_mesh.iv_index = iv_index;
305 bt_mesh.seq = 0U;
306
307 goto do_update;
308 }
309
310 if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) == iv_update) {
311 LOG_DBG("No change for IV Update procedure");
312 return false;
313 }
314
315 if (!(IS_ENABLED(CONFIG_BT_MESH_IV_UPDATE_TEST) &&
316 atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_TEST))) {
317 if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) {
318 LOG_WRN("IV Update before minimum duration");
319 return false;
320 }
321 }
322
323 /* Defer change to Normal Operation if there are pending acks */
324 if (!iv_update && bt_mesh_tx_in_progress()) {
325 LOG_WRN("IV Update deferred because of pending transfer");
326 atomic_set_bit(bt_mesh.flags, BT_MESH_IVU_PENDING);
327 return false;
328 }
329
330 if (iv_update) {
331 bt_mesh.iv_index = iv_index;
332 LOG_DBG("IV Update state entered. New index 0x%08x", bt_mesh.iv_index);
333
334 bt_mesh_rpl_reset();
335 ivi_was_recovered = false;
336 } else {
337 LOG_DBG("Normal mode entered");
338 bt_mesh.seq = 0U;
339 }
340
341 do_update:
342 atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, iv_update);
343 bt_mesh.ivu_duration = 0U;
344
345 k_work_reschedule(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT);
346
347 /* Notify other modules */
348 if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
349 bt_mesh_friend_sec_update(BT_MESH_KEY_ANY);
350 }
351
352 bt_mesh_subnet_foreach(bt_mesh_beacon_update);
353
354 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) &&
355 (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED ||
356 bt_mesh_priv_gatt_proxy_get() == BT_MESH_PRIV_GATT_PROXY_ENABLED)) {
357 bt_mesh_proxy_beacon_send(NULL);
358 }
359
360 if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
361 bt_mesh_cdb_iv_update(iv_index, iv_update);
362 }
363
364 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
365 store_iv(false);
366 }
367
368 return true;
369 }
370
bt_mesh_next_seq(void)371 uint32_t bt_mesh_next_seq(void)
372 {
373 uint32_t seq = bt_mesh.seq++;
374
375 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
376 bt_mesh_net_seq_store(false);
377 }
378
379 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) &&
380 bt_mesh.seq > IV_UPDATE_SEQ_LIMIT &&
381 bt_mesh_subnet_get(BT_MESH_KEY_PRIMARY)) {
382 bt_mesh_beacon_ivu_initiator(true);
383 bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true);
384 }
385
386 return seq;
387 }
388
bt_mesh_net_local(struct k_work * work)389 static void bt_mesh_net_local(struct k_work *work)
390 {
391 struct net_buf_simple sbuf;
392 sys_snode_t *node;
393
394 while ((node = sys_slist_get(&bt_mesh.local_queue))) {
395 struct loopback_buf *buf = CONTAINER_OF(node, struct loopback_buf, node);
396 struct bt_mesh_net_rx rx = {
397 .ctx = {
398 .net_idx = buf->sub->net_idx,
399 /* Initialize AppIdx to a sane value */
400 .app_idx = BT_MESH_KEY_UNUSED,
401 .recv_ttl = TTL(buf->data),
402 /* TTL=1 only goes to local IF */
403 .send_ttl = 1U,
404 .addr = SRC(buf->data),
405 .recv_dst = DST(buf->data),
406 .recv_rssi = 0,
407 },
408 .net_if = BT_MESH_NET_IF_LOCAL,
409 .sub = buf->sub,
410 .old_iv = (IVI(buf->data) != (bt_mesh.iv_index & 0x01)),
411 .ctl = CTL(buf->data),
412 .seq = SEQ(buf->data),
413 .new_key = SUBNET_KEY_TX_IDX(buf->sub),
414 .local_match = 1U,
415 .friend_match = 0U,
416 };
417
418 LOG_DBG("src: 0x%04x dst: 0x%04x seq 0x%06x sub %p", rx.ctx.addr, rx.ctx.addr,
419 rx.seq, buf->sub);
420
421 net_buf_simple_init_with_data(&sbuf, buf->data, buf->len);
422 (void)bt_mesh_trans_recv(&sbuf, &rx);
423 k_mem_slab_free(&loopback_buf_pool, (void *)buf);
424 }
425 }
426
net_tx_cred_get(struct bt_mesh_net_tx * tx)427 static const struct bt_mesh_net_cred *net_tx_cred_get(struct bt_mesh_net_tx *tx)
428 {
429 #if defined(CONFIG_BT_MESH_LOW_POWER)
430 if (tx->friend_cred && bt_mesh.lpn.frnd) {
431 return &bt_mesh.lpn.cred[SUBNET_KEY_TX_IDX(tx->sub)];
432 }
433 #endif
434
435 tx->friend_cred = 0U;
436 return &tx->sub->keys[SUBNET_KEY_TX_IDX(tx->sub)].msg;
437 }
438
net_header_encode(struct bt_mesh_net_tx * tx,uint8_t nid,struct net_buf_simple * buf)439 static int net_header_encode(struct bt_mesh_net_tx *tx, uint8_t nid,
440 struct net_buf_simple *buf)
441 {
442 const bool ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED);
443
444 if (ctl && net_buf_simple_tailroom(buf) < 8) {
445 LOG_ERR("Insufficient MIC space for CTL PDU");
446 return -EINVAL;
447 } else if (net_buf_simple_tailroom(buf) < 4) {
448 LOG_ERR("Insufficient MIC space for PDU");
449 return -EINVAL;
450 }
451
452 LOG_DBG("src 0x%04x dst 0x%04x ctl %u seq 0x%06x", tx->src, tx->ctx->addr, ctl,
453 bt_mesh.seq);
454
455 net_buf_simple_push_be16(buf, tx->ctx->addr);
456 net_buf_simple_push_be16(buf, tx->src);
457 net_buf_simple_push_be24(buf, bt_mesh_next_seq());
458
459 if (ctl) {
460 net_buf_simple_push_u8(buf, tx->ctx->send_ttl | 0x80);
461 } else {
462 net_buf_simple_push_u8(buf, tx->ctx->send_ttl);
463 }
464
465 net_buf_simple_push_u8(buf, (nid | (BT_MESH_NET_IVI_TX & 1) << 7));
466
467 return 0;
468 }
469
net_encrypt(struct net_buf_simple * buf,const struct bt_mesh_net_cred * cred,uint32_t iv_index,enum bt_mesh_nonce_type proxy)470 static int net_encrypt(struct net_buf_simple *buf,
471 const struct bt_mesh_net_cred *cred, uint32_t iv_index,
472 enum bt_mesh_nonce_type proxy)
473 {
474 int err;
475
476 err = bt_mesh_net_encrypt(&cred->enc, buf, iv_index, proxy);
477 if (err) {
478 return err;
479 }
480
481 return bt_mesh_net_obfuscate(buf->data, iv_index, &cred->privacy);
482 }
483
bt_mesh_net_encode(struct bt_mesh_net_tx * tx,struct net_buf_simple * buf,enum bt_mesh_nonce_type type)484 int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf,
485 enum bt_mesh_nonce_type type)
486 {
487 const struct bt_mesh_net_cred *cred;
488 int err;
489
490 cred = net_tx_cred_get(tx);
491 err = net_header_encode(tx, cred->nid, buf);
492 if (err) {
493 return err;
494 }
495
496 return net_encrypt(buf, cred, BT_MESH_NET_IVI_TX, type);
497 }
498
net_loopback(const struct bt_mesh_net_tx * tx,const uint8_t * data,size_t len)499 static int net_loopback(const struct bt_mesh_net_tx *tx, const uint8_t *data,
500 size_t len)
501 {
502 int err;
503 struct loopback_buf *buf;
504
505 err = k_mem_slab_alloc(&loopback_buf_pool, (void **)&buf, K_NO_WAIT);
506 if (err) {
507 LOG_WRN("Unable to allocate loopback");
508 return -ENOMEM;
509 }
510
511 buf->sub = tx->sub;
512
513 (void)memcpy(buf->data, data, len);
514 buf->len = len;
515
516 sys_slist_append(&bt_mesh.local_queue, &buf->node);
517
518 k_work_submit(&bt_mesh.local_work);
519
520 return 0;
521 }
522
bt_mesh_net_send(struct bt_mesh_net_tx * tx,struct bt_mesh_adv * adv,const struct bt_mesh_send_cb * cb,void * cb_data)523 int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct bt_mesh_adv *adv,
524 const struct bt_mesh_send_cb *cb, void *cb_data)
525 {
526 const struct bt_mesh_net_cred *cred;
527 int err;
528
529 LOG_DBG("src 0x%04x dst 0x%04x len %u headroom %zu tailroom %zu", tx->src, tx->ctx->addr,
530 adv->b.len, net_buf_simple_headroom(&adv->b), net_buf_simple_tailroom(&adv->b));
531 LOG_DBG("Payload len %u: %s", adv->b.len, bt_hex(adv->b.data, adv->b.len));
532 LOG_DBG("Seq 0x%06x", bt_mesh.seq);
533
534 cred = net_tx_cred_get(tx);
535 err = net_header_encode(tx, cred->nid, &adv->b);
536 if (err) {
537 goto done;
538 }
539
540 /* Deliver to local network interface if necessary */
541 if (bt_mesh_fixed_group_match(tx->ctx->addr) ||
542 bt_mesh_has_addr(tx->ctx->addr)) {
543 err = net_loopback(tx, adv->b.data, adv->b.len);
544
545 /* Local unicast messages should not go out to network */
546 if (BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr) ||
547 tx->ctx->send_ttl == 1U) {
548 if (!err) {
549 send_cb_finalize(cb, cb_data);
550 }
551
552 goto done;
553 }
554 }
555
556 /* MshPRTv1.1: 3.4.5.2: "The output filter of the interface connected to
557 * advertising or GATT bearers shall drop all messages with TTL value
558 * set to 1." If a TTL=1 packet wasn't for a local interface, it is
559 * invalid.
560 */
561 if (tx->ctx->send_ttl == 1U) {
562 err = -EINVAL;
563 goto done;
564 }
565
566 err = net_encrypt(&adv->b, cred, BT_MESH_NET_IVI_TX, BT_MESH_NONCE_NETWORK);
567 if (err) {
568 goto done;
569 }
570
571 adv->ctx.cb = cb;
572 adv->ctx.cb_data = cb_data;
573
574 /* Deliver to GATT Proxy Clients if necessary. */
575 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
576 (void)bt_mesh_proxy_relay(adv, tx->ctx->addr);
577 }
578
579 /* Deliver to GATT Proxy Servers if necessary. */
580 if (IS_ENABLED(CONFIG_BT_MESH_PROXY_CLIENT)) {
581 (void)bt_mesh_proxy_cli_relay(adv);
582 }
583
584 bt_mesh_adv_send(adv, cb, cb_data);
585
586 done:
587 bt_mesh_adv_unref(adv);
588 return err;
589 }
590
bt_mesh_net_loopback_clear(uint16_t net_idx)591 void bt_mesh_net_loopback_clear(uint16_t net_idx)
592 {
593 sys_slist_t new_list;
594 sys_snode_t *node;
595
596 LOG_DBG("0x%04x", net_idx);
597
598 sys_slist_init(&new_list);
599
600 while ((node = sys_slist_get(&bt_mesh.local_queue))) {
601 struct loopback_buf *buf = CONTAINER_OF(node, struct loopback_buf, node);
602
603 if (net_idx == BT_MESH_KEY_ANY || net_idx == buf->sub->net_idx) {
604 LOG_DBG("Dropped 0x%06x", SEQ(buf->data));
605 k_mem_slab_free(&loopback_buf_pool, (void *)buf);
606 } else {
607 sys_slist_append(&new_list, &buf->node);
608 }
609 }
610
611 bt_mesh.local_queue = new_list;
612 }
613
net_decrypt(struct bt_mesh_net_rx * rx,struct net_buf_simple * in,struct net_buf_simple * out,const struct bt_mesh_net_cred * cred)614 static bool net_decrypt(struct bt_mesh_net_rx *rx, struct net_buf_simple *in,
615 struct net_buf_simple *out,
616 const struct bt_mesh_net_cred *cred)
617 {
618 bool proxy = (rx->net_if == BT_MESH_NET_IF_PROXY_CFG);
619
620 if (NID(in->data) != cred->nid) {
621 return false;
622 }
623
624 LOG_DBG("NID 0x%02x", NID(in->data));
625 LOG_DBG("IVI %u net->iv_index 0x%08x", IVI(in->data), bt_mesh.iv_index);
626
627 rx->old_iv = (IVI(in->data) != (bt_mesh.iv_index & 0x01));
628
629 net_buf_simple_reset(out);
630 net_buf_simple_add_mem(out, in->data, in->len);
631
632 if (bt_mesh_net_obfuscate(out->data, BT_MESH_NET_IVI_RX(rx),
633 &cred->privacy)) {
634 return false;
635 }
636
637 rx->ctx.addr = SRC(out->data);
638 if (!BT_MESH_ADDR_IS_UNICAST(rx->ctx.addr)) {
639 LOG_DBG("Ignoring non-unicast src addr 0x%04x", rx->ctx.addr);
640 return false;
641 }
642
643 if (bt_mesh_has_addr(rx->ctx.addr)) {
644 LOG_DBG("Dropping locally originated packet");
645 return false;
646 }
647
648 if (rx->net_if == BT_MESH_NET_IF_ADV && msg_cache_match(out)) {
649 LOG_DBG("Duplicate found in Network Message Cache");
650 return false;
651 }
652
653 LOG_DBG("src 0x%04x", rx->ctx.addr);
654
655 return bt_mesh_net_decrypt(&cred->enc, out, BT_MESH_NET_IVI_RX(rx),
656 proxy) == 0;
657 }
658
659 /* Relaying from advertising to the advertising bearer should only happen
660 * if the Relay state is set to enabled. Locally originated packets always
661 * get sent to the advertising bearer. If the packet came in through GATT,
662 * then we should only relay it if the GATT Proxy state is enabled.
663 */
relay_to_adv(enum bt_mesh_net_if net_if)664 static bool relay_to_adv(enum bt_mesh_net_if net_if)
665 {
666 switch (net_if) {
667 case BT_MESH_NET_IF_ADV:
668 return (bt_mesh_relay_get() == BT_MESH_RELAY_ENABLED);
669 case BT_MESH_NET_IF_PROXY:
670 return (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) ||
671 (bt_mesh_priv_gatt_proxy_get() == BT_MESH_PRIV_GATT_PROXY_ENABLED);
672 default:
673 return false;
674 }
675 }
676
bt_mesh_net_relay(struct net_buf_simple * sbuf,struct bt_mesh_net_rx * rx)677 static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
678 struct bt_mesh_net_rx *rx)
679 {
680 const struct bt_mesh_net_cred *cred;
681 struct bt_mesh_adv *adv;
682 uint8_t transmit;
683
684 if (rx->ctx.recv_ttl <= 1U) {
685 return;
686 }
687
688 if (rx->net_if == BT_MESH_NET_IF_ADV &&
689 !rx->friend_cred &&
690 bt_mesh_relay_get() != BT_MESH_RELAY_ENABLED &&
691 bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_ENABLED &&
692 bt_mesh_priv_gatt_proxy_get() != BT_MESH_PRIV_GATT_PROXY_ENABLED) {
693 return;
694 }
695
696 LOG_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, rx->ctl, rx->ctx.recv_dst);
697
698 /* The Relay Retransmit state is only applied to adv-adv relaying.
699 * Anything else (like GATT to adv, or locally originated packets)
700 * use the Network Transmit state.
701 */
702 if (rx->net_if == BT_MESH_NET_IF_ADV && !rx->friend_cred) {
703 transmit = bt_mesh_relay_retransmit_get();
704 } else {
705 transmit = bt_mesh_net_transmit_get();
706 }
707
708 adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_RELAY,
709 transmit, K_NO_WAIT);
710 if (!adv) {
711 LOG_DBG("Out of relay advs");
712 return;
713 }
714
715 /* Leave CTL bit intact */
716 sbuf->data[1] &= 0x80;
717 sbuf->data[1] |= rx->ctx.recv_ttl - 1U;
718
719 net_buf_simple_add_mem(&adv->b, sbuf->data, sbuf->len);
720
721 cred = &rx->sub->keys[SUBNET_KEY_TX_IDX(rx->sub)].msg;
722
723 LOG_DBG("Relaying packet. TTL is now %u", TTL(adv->b.data));
724
725 /* Update NID if RX or RX was with friend credentials */
726 if (rx->friend_cred) {
727 adv->b.data[0] &= 0x80; /* Clear everything except IVI */
728 adv->b.data[0] |= cred->nid;
729 }
730
731 /* We re-encrypt and obfuscate using the received IVI rather than
732 * the normal TX IVI (which may be different) since the transport
733 * layer nonce includes the IVI.
734 */
735 if (net_encrypt(&adv->b, cred, BT_MESH_NET_IVI_RX(rx), BT_MESH_NONCE_NETWORK)) {
736 LOG_ERR("Re-encrypting failed");
737 goto done;
738 }
739
740 /* When the Friend node relays message for lpn, the message will be
741 * retransmitted using the managed flooding security credentials and
742 * the Network PDU shall be retransmitted to all network interfaces.
743 */
744 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) &&
745 (rx->friend_cred ||
746 bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED ||
747 bt_mesh_priv_gatt_proxy_get() == BT_MESH_PRIV_GATT_PROXY_ENABLED)) {
748 bt_mesh_proxy_relay(adv, rx->ctx.recv_dst);
749 }
750
751 if (relay_to_adv(rx->net_if) || rx->friend_cred) {
752 bt_mesh_adv_send(adv, NULL, NULL);
753 }
754
755 done:
756 bt_mesh_adv_unref(adv);
757 }
758
bt_mesh_net_header_parse(struct net_buf_simple * buf,struct bt_mesh_net_rx * rx)759 void bt_mesh_net_header_parse(struct net_buf_simple *buf,
760 struct bt_mesh_net_rx *rx)
761 {
762 rx->old_iv = (IVI(buf->data) != (bt_mesh.iv_index & 0x01));
763 rx->ctl = CTL(buf->data);
764 rx->ctx.recv_ttl = TTL(buf->data);
765 rx->seq = SEQ(buf->data);
766 rx->ctx.addr = SRC(buf->data);
767 rx->ctx.recv_dst = DST(buf->data);
768 }
769
bt_mesh_net_decode(struct net_buf_simple * in,enum bt_mesh_net_if net_if,struct bt_mesh_net_rx * rx,struct net_buf_simple * out)770 int bt_mesh_net_decode(struct net_buf_simple *in, enum bt_mesh_net_if net_if,
771 struct bt_mesh_net_rx *rx, struct net_buf_simple *out)
772 {
773 if (in->len < BT_MESH_NET_MIN_PDU_LEN) {
774 LOG_WRN("Dropping too short mesh packet (len %u)", in->len);
775 LOG_WRN("%s", bt_hex(in->data, in->len));
776 return -EINVAL;
777 }
778
779 if (in->len > BT_MESH_NET_MAX_PDU_LEN) {
780 LOG_WRN("Dropping too long mesh packet (len %u)", in->len);
781 return -EINVAL;
782 }
783
784 if (net_if == BT_MESH_NET_IF_ADV && check_dup(in)) {
785 return -EINVAL;
786 }
787
788 LOG_DBG("%u bytes: %s", in->len, bt_hex(in->data, in->len));
789
790 rx->net_if = net_if;
791
792 if (!bt_mesh_net_cred_find(rx, in, out, net_decrypt)) {
793 LOG_DBG("Unable to find matching net for packet");
794 return -ENOENT;
795 }
796
797 /* Initialize AppIdx to a sane value */
798 rx->ctx.app_idx = BT_MESH_KEY_UNUSED;
799
800 rx->ctx.recv_ttl = TTL(out->data);
801
802 /* Default to responding with TTL 0 for non-routed messages */
803 if (rx->ctx.recv_ttl == 0U) {
804 rx->ctx.send_ttl = 0U;
805 } else {
806 rx->ctx.send_ttl = BT_MESH_TTL_DEFAULT;
807 }
808
809 rx->ctl = CTL(out->data);
810 rx->seq = SEQ(out->data);
811 rx->ctx.recv_dst = DST(out->data);
812
813 LOG_DBG("Decryption successful. Payload len %u", out->len);
814
815 if (net_if != BT_MESH_NET_IF_PROXY_CFG &&
816 rx->ctx.recv_dst == BT_MESH_ADDR_UNASSIGNED) {
817 LOG_ERR("Destination address is unassigned; dropping packet");
818 return -EBADMSG;
819 }
820
821 LOG_DBG("src 0x%04x dst 0x%04x ttl %u", rx->ctx.addr, rx->ctx.recv_dst, rx->ctx.recv_ttl);
822 LOG_DBG("PDU: %s", bt_hex(out->data, out->len));
823
824 msg_cache_add(rx);
825
826 return 0;
827 }
828
bt_mesh_net_recv(struct net_buf_simple * data,int8_t rssi,enum bt_mesh_net_if net_if)829 void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
830 enum bt_mesh_net_if net_if)
831 {
832 NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_NET_MAX_PDU_LEN);
833 struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
834 struct net_buf_simple_state state;
835 int err;
836
837 LOG_DBG("rssi %d net_if %u", rssi, net_if);
838
839 if (!bt_mesh_is_provisioned()) {
840 return;
841 }
842
843 if (bt_mesh_net_decode(data, net_if, &rx, &buf)) {
844 return;
845 }
846
847 if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) {
848 bt_mesh_stat_rx(net_if);
849 }
850
851 /* Save the state so the buffer can later be relayed */
852 net_buf_simple_save(&buf, &state);
853
854 rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) ||
855 bt_mesh_has_addr(rx.ctx.recv_dst));
856
857 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) &&
858 net_if == BT_MESH_NET_IF_PROXY) {
859 bt_mesh_proxy_addr_add(data, rx.ctx.addr);
860
861 if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_DISABLED &&
862 bt_mesh_priv_gatt_proxy_get() == BT_MESH_PRIV_GATT_PROXY_DISABLED &&
863 !rx.local_match) {
864 LOG_INF("Proxy is disabled; ignoring message");
865 return;
866 }
867 }
868
869 err = bt_mesh_trans_recv(&buf, &rx);
870 if (err == -EAGAIN) {
871 /* The transport layer has indicated that it has rejected the message,
872 * but would like to see it again if it is received in the future.
873 * This can happen if a message is received when the device is in
874 * Low Power mode, but the message was not encrypted with the friend
875 * credentials. Remove it from the message cache so that we accept
876 * it again in the future.
877 */
878 LOG_WRN("Removing rejected message from Network Message Cache");
879 /* Rewind the next index now that we're not using this entry */
880 msg_cache[--msg_cache_next].src = BT_MESH_ADDR_UNASSIGNED;
881 dup_cache[--dup_cache_next] = 0;
882 return;
883 } else if (err == -EBADMSG) {
884 LOG_DBG("Not relaying message rejected by the Transport layer");
885 return;
886 }
887
888 /* Relay if this was a group/virtual address, or if the destination
889 * was neither a local element nor an LPN we're Friends for.
890 */
891 if (!BT_MESH_ADDR_IS_UNICAST(rx.ctx.recv_dst) ||
892 (!rx.local_match && !rx.friend_match)) {
893 net_buf_simple_restore(&buf, &state);
894 bt_mesh_net_relay(&buf, &rx);
895 }
896 }
897
ivu_refresh(struct k_work * work)898 static void ivu_refresh(struct k_work *work)
899 {
900 if (!bt_mesh_is_provisioned()) {
901 return;
902 }
903
904 bt_mesh.ivu_duration = MIN(UINT8_MAX,
905 bt_mesh.ivu_duration + BT_MESH_IVU_HOURS);
906
907 LOG_DBG("%s for %u hour%s",
908 atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) ? "IVU in Progress"
909 : "IVU Normal mode",
910 bt_mesh.ivu_duration, bt_mesh.ivu_duration == 1U ? "" : "s");
911
912 if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) {
913 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
914 store_iv(true);
915 }
916
917 goto end;
918 }
919
920 /* Because the beacon may be cached, iv update or iv recovery
921 * cannot be performed after 96 hours or 192 hours.
922 * So we need clear beacon cache.
923 */
924 if (!(bt_mesh.ivu_duration % BT_MESH_IVU_MIN_HOURS)) {
925 bt_mesh_subnet_foreach(bt_mesh_beacon_cache_clear);
926 }
927
928 if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS)) {
929 bt_mesh_beacon_ivu_initiator(true);
930 bt_mesh_net_iv_update(bt_mesh.iv_index, false);
931 } else if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
932 store_iv(true);
933 }
934
935 end:
936 k_work_reschedule(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT);
937 }
938
bt_mesh_net_init(void)939 void bt_mesh_net_init(void)
940 {
941 k_work_init_delayable(&bt_mesh.ivu_timer, ivu_refresh);
942
943 k_work_init(&bt_mesh.local_work, bt_mesh_net_local);
944 }
945
net_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)946 static int net_set(const char *name, size_t len_rd, settings_read_cb read_cb,
947 void *cb_arg)
948 {
949 struct net_val net;
950 struct bt_mesh_key key;
951 int err;
952
953 if (len_rd == 0) {
954 LOG_DBG("val (null)");
955
956 bt_mesh_comp_unprovision();
957 bt_mesh_key_destroy(&bt_mesh.dev_key);
958 memset(&bt_mesh.dev_key, 0, sizeof(struct bt_mesh_key));
959 return 0;
960 }
961
962 err = bt_mesh_settings_set(read_cb, cb_arg, &net, sizeof(net));
963 if (err) {
964 LOG_ERR("Failed to set \'net\'");
965 return err;
966 }
967
968 /* One extra copying since net.dev_key is from packed structure
969 * and might be unaligned.
970 */
971 memcpy(&key, &net.dev_key, sizeof(struct bt_mesh_key));
972
973 bt_mesh_key_assign(&bt_mesh.dev_key, &key);
974 bt_mesh_comp_provision(net.primary_addr);
975
976 LOG_DBG("Provisioned with primary address 0x%04x", net.primary_addr);
977 LOG_DBG("Recovered DevKey %s", bt_hex(&bt_mesh.dev_key, sizeof(struct bt_mesh_key)));
978
979 return 0;
980 }
981
982 BT_MESH_SETTINGS_DEFINE(net, "Net", net_set);
983
iv_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)984 static int iv_set(const char *name, size_t len_rd, settings_read_cb read_cb,
985 void *cb_arg)
986 {
987 struct iv_val iv;
988 int err;
989
990 if (len_rd == 0) {
991 LOG_DBG("IV deleted");
992
993 bt_mesh.iv_index = 0U;
994 atomic_clear_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS);
995 return 0;
996 }
997
998 err = bt_mesh_settings_set(read_cb, cb_arg, &iv, sizeof(iv));
999 if (err) {
1000 LOG_ERR("Failed to set \'iv\'");
1001 return err;
1002 }
1003
1004 bt_mesh.iv_index = iv.iv_index;
1005 atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, iv.iv_update);
1006 bt_mesh.ivu_duration = iv.iv_duration;
1007
1008 LOG_DBG("IV Index 0x%04x (IV Update Flag %u) duration %u hours", iv.iv_index, iv.iv_update,
1009 iv.iv_duration);
1010
1011 return 0;
1012 }
1013
1014 BT_MESH_SETTINGS_DEFINE(iv, "IV", iv_set);
1015
seq_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1016 static int seq_set(const char *name, size_t len_rd, settings_read_cb read_cb,
1017 void *cb_arg)
1018 {
1019 struct seq_val seq;
1020 int err;
1021
1022 if (len_rd == 0) {
1023 LOG_DBG("val (null)");
1024
1025 bt_mesh.seq = 0U;
1026 return 0;
1027 }
1028
1029 err = bt_mesh_settings_set(read_cb, cb_arg, &seq, sizeof(seq));
1030 if (err) {
1031 LOG_ERR("Failed to set \'seq\'");
1032 return err;
1033 }
1034
1035 bt_mesh.seq = sys_get_le24(seq.val);
1036
1037 if (CONFIG_BT_MESH_SEQ_STORE_RATE > 0) {
1038 /* Make sure we have a large enough sequence number. We
1039 * subtract 1 so that the first transmission causes a write
1040 * to the settings storage.
1041 */
1042 bt_mesh.seq += (CONFIG_BT_MESH_SEQ_STORE_RATE -
1043 (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE));
1044 bt_mesh.seq--;
1045 }
1046
1047 LOG_DBG("Sequence Number 0x%06x", bt_mesh.seq);
1048
1049 return 0;
1050 }
1051
1052 BT_MESH_SETTINGS_DEFINE(seq, "Seq", seq_set);
1053
1054 #if defined(CONFIG_BT_MESH_RPR_SRV)
dev_key_cand_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)1055 static int dev_key_cand_set(const char *name, size_t len_rd, settings_read_cb read_cb,
1056 void *cb_arg)
1057 { int err;
1058
1059 if (len_rd < 16) {
1060 return -EINVAL;
1061 }
1062
1063 err = bt_mesh_settings_set(read_cb, cb_arg, &bt_mesh.dev_key_cand,
1064 sizeof(struct bt_mesh_key));
1065 if (!err) {
1066 LOG_DBG("DevKey candidate recovered from storage");
1067 atomic_set_bit(bt_mesh.flags, BT_MESH_DEVKEY_CAND);
1068 }
1069
1070 return err;
1071 }
1072
1073 BT_MESH_SETTINGS_DEFINE(dev_key, "DevKeyC", dev_key_cand_set);
1074 #endif
1075
bt_mesh_net_pending_dev_key_cand_store(void)1076 void bt_mesh_net_pending_dev_key_cand_store(void)
1077 {
1078 #if defined(CONFIG_BT_MESH_RPR_SRV)
1079 int err;
1080
1081 if (atomic_test_bit(bt_mesh.flags, BT_MESH_DEVKEY_CAND)) {
1082 err = settings_save_one("bt/mesh/DevKeyC", &bt_mesh.dev_key_cand,
1083 sizeof(struct bt_mesh_key));
1084 } else {
1085 err = settings_delete("bt/mesh/DevKeyC");
1086 }
1087
1088 if (err) {
1089 LOG_ERR("Failed to update DevKey candidate value");
1090 } else {
1091 LOG_DBG("Stored DevKey candidate value");
1092 }
1093 #endif
1094 }
1095
bt_mesh_net_dev_key_cand_store(void)1096 void bt_mesh_net_dev_key_cand_store(void)
1097 {
1098 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING);
1099 }
1100
clear_iv(void)1101 static void clear_iv(void)
1102 {
1103 int err;
1104
1105 err = settings_delete("bt/mesh/IV");
1106 if (err) {
1107 LOG_ERR("Failed to clear IV");
1108 } else {
1109 LOG_DBG("Cleared IV");
1110 }
1111 }
1112
store_pending_iv(void)1113 static void store_pending_iv(void)
1114 {
1115 struct iv_val iv;
1116 int err;
1117
1118 iv.iv_index = bt_mesh.iv_index;
1119 iv.iv_update = atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS);
1120 iv.iv_duration = bt_mesh.ivu_duration;
1121
1122 err = settings_save_one("bt/mesh/IV", &iv, sizeof(iv));
1123 if (err) {
1124 LOG_ERR("Failed to store IV value");
1125 } else {
1126 LOG_DBG("Stored IV value");
1127 }
1128 }
1129
bt_mesh_net_pending_iv_store(void)1130 void bt_mesh_net_pending_iv_store(void)
1131 {
1132 if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
1133 store_pending_iv();
1134 } else {
1135 clear_iv();
1136 }
1137 }
1138
clear_net(void)1139 static void clear_net(void)
1140 {
1141 int err;
1142
1143 err = settings_delete("bt/mesh/Net");
1144 if (err) {
1145 LOG_ERR("Failed to clear Network");
1146 } else {
1147 LOG_DBG("Cleared Network");
1148 }
1149 }
1150
store_pending_net(void)1151 static void store_pending_net(void)
1152 {
1153 struct net_val net;
1154 int err;
1155
1156 LOG_DBG("addr 0x%04x DevKey %s", bt_mesh_primary_addr(),
1157 bt_hex(&bt_mesh.dev_key, sizeof(struct bt_mesh_key)));
1158
1159 net.primary_addr = bt_mesh_primary_addr();
1160 memcpy(&net.dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key));
1161
1162 err = settings_save_one("bt/mesh/Net", &net, sizeof(net));
1163 if (err) {
1164 LOG_ERR("Failed to store Network value");
1165 } else {
1166 LOG_DBG("Stored Network value");
1167 }
1168 }
1169
bt_mesh_net_pending_net_store(void)1170 void bt_mesh_net_pending_net_store(void)
1171 {
1172 if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
1173 store_pending_net();
1174 } else {
1175 clear_net();
1176 }
1177 }
1178
bt_mesh_net_pending_seq_store(void)1179 void bt_mesh_net_pending_seq_store(void)
1180 {
1181 struct seq_val seq;
1182 int err;
1183
1184 if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
1185 sys_put_le24(bt_mesh.seq, seq.val);
1186
1187 err = settings_save_one("bt/mesh/Seq", &seq, sizeof(seq));
1188 if (err) {
1189 LOG_ERR("Failed to stor Seq value");
1190 } else {
1191 LOG_DBG("Stored Seq value");
1192 }
1193 } else {
1194 err = settings_delete("bt/mesh/Seq");
1195 if (err) {
1196 LOG_ERR("Failed to clear Seq value");
1197 } else {
1198 LOG_DBG("Cleared Seq value");
1199 }
1200 }
1201 }
1202
bt_mesh_net_store(void)1203 void bt_mesh_net_store(void)
1204 {
1205 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING);
1206 }
1207
bt_mesh_net_clear(void)1208 void bt_mesh_net_clear(void)
1209 {
1210 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING);
1211 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_IV_PENDING);
1212 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING);
1213 bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING);
1214 }
1215
bt_mesh_net_settings_commit(void)1216 void bt_mesh_net_settings_commit(void)
1217 {
1218 if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) {
1219 k_work_reschedule(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT);
1220 }
1221 }
1222