1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <errno.h>
9 #include <zephyr/sys/util.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <zephyr/sys/iterable_sections.h>
12 #include <zephyr/net/buf.h>
13 #include <zephyr/bluetooth/bluetooth.h>
14 #include <zephyr/bluetooth/conn.h>
15 #include <zephyr/bluetooth/mesh.h>
16
17 #include "common/bt_str.h"
18
19 #include "adv.h"
20 #include "mesh.h"
21 #include "net.h"
22 #include "prov.h"
23 #include "crypto.h"
24 #include "beacon.h"
25 #include "cfg.h"
26
27 #define LOG_LEVEL CONFIG_BT_MESH_BEACON_LOG_LEVEL
28 #include <zephyr/logging/log.h>
29 LOG_MODULE_REGISTER(bt_mesh_beacon);
30
31 #define PROVISIONED_INTERVAL K_SECONDS(10)
32
33 #define BEACON_TYPE_UNPROVISIONED 0x00
34 #define BEACON_TYPE_SECURE 0x01
35 #define BEACON_TYPE_PRIVATE 0x02
36
37 /* 3 transmissions, 20ms interval */
38 #define UNPROV_XMIT BT_MESH_TRANSMIT(2, 20)
39
40 /* 1 transmission, 20ms interval */
41 #define PROV_XMIT BT_MESH_TRANSMIT(0, 20)
42
43 static struct k_work_delayable beacon_timer;
44 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
45 static struct {
46 /**
47 * Identifier for the current Private beacon random-value.
48 * Each time we regenerate the random-value, we'll update this idx.
49 * Whenever it's time for a subnet to create a beacon, it'll compare
50 * the subnet's beacon idx to determine whether the random value has
51 * changed since the last beacon was sent. If this is the case, we'll
52 * regenerate the beacon based on the new random value.
53 */
54 uint16_t idx;
55 uint8_t val[13];
56 uint64_t timestamp;
57 } priv_random;
58 #endif
59
60 struct beacon_params {
61 bool private;
62 union {
63 const uint8_t *net_id;
64 struct {
65 const uint8_t *data;
66 const uint8_t *random;
67 };
68 };
69 const uint8_t *auth;
70 uint32_t iv_index;
71 uint8_t flags;
72
73 bool new_key;
74 };
75
76 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
77 static int private_beacon_create(struct bt_mesh_subnet *sub,
78 struct net_buf_simple *buf);
79 static int private_beacon_update(struct bt_mesh_subnet *sub);
80 #endif
81
subnet_beacon_get_by_type(struct bt_mesh_subnet * sub,bool priv)82 static struct bt_mesh_beacon *subnet_beacon_get_by_type(struct bt_mesh_subnet *sub, bool priv)
83 {
84 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
85 return priv ? &sub->priv_beacon : &sub->secure_beacon;
86 #else
87 return &sub->secure_beacon;
88 #endif
89 }
90
beacon_cache_match(struct bt_mesh_subnet * sub,void * data)91 static bool beacon_cache_match(struct bt_mesh_subnet *sub, void *data)
92 {
93 struct beacon_params *params;
94 struct bt_mesh_beacon *beacon;
95
96 params = data;
97 beacon = subnet_beacon_get_by_type(sub, params->private);
98
99 return !memcmp(beacon->cache, params->auth, sizeof(beacon->cache));
100 }
101
cache_add(const uint8_t auth[8],struct bt_mesh_beacon * beacon)102 static void cache_add(const uint8_t auth[8], struct bt_mesh_beacon *beacon)
103 {
104 memcpy(beacon->cache, auth, sizeof(beacon->cache));
105 }
106
bt_mesh_beacon_cache_clear(struct bt_mesh_subnet * sub)107 void bt_mesh_beacon_cache_clear(struct bt_mesh_subnet *sub)
108 {
109 (void)memset(sub->secure_beacon.cache, 0, sizeof(sub->secure_beacon.cache));
110 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
111 (void)memset(sub->priv_beacon.cache, 0, sizeof(sub->priv_beacon.cache));
112 #endif
113 }
114
beacon_complete(int err,void * user_data)115 static void beacon_complete(int err, void *user_data)
116 {
117 struct bt_mesh_beacon *beacon = user_data;
118
119 LOG_DBG("err %d", err);
120
121 beacon->sent = k_uptime_get_32();
122 }
123
secure_beacon_create(struct bt_mesh_subnet * sub,struct net_buf_simple * buf)124 static int secure_beacon_create(struct bt_mesh_subnet *sub,
125 struct net_buf_simple *buf)
126 {
127 uint8_t flags = bt_mesh_net_flags(sub);
128 struct bt_mesh_subnet_keys *keys;
129
130 net_buf_simple_add_u8(buf, BEACON_TYPE_SECURE);
131
132 keys = &sub->keys[SUBNET_KEY_TX_IDX(sub)];
133
134 net_buf_simple_add_u8(buf, flags);
135
136 /* Network ID */
137 net_buf_simple_add_mem(buf, keys->net_id, 8);
138
139 /* IV Index */
140 net_buf_simple_add_be32(buf, bt_mesh.iv_index);
141
142 net_buf_simple_add_mem(buf, sub->secure_beacon.auth, 8);
143
144 LOG_DBG("net_idx 0x%04x flags 0x%02x NetID %s", sub->net_idx, flags,
145 bt_hex(keys->net_id, 8));
146 LOG_DBG("IV Index 0x%08x Auth %s", bt_mesh.iv_index, bt_hex(sub->secure_beacon.auth, 8));
147
148 return 0;
149 }
150
151 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
private_random_update(void)152 static int private_random_update(void)
153 {
154 uint8_t interval = bt_mesh_priv_beacon_update_interval_get();
155 uint64_t uptime = k_uptime_get();
156 int err;
157
158 /* The Private beacon random value should change every N seconds to maintain privacy.
159 * N = (10 * interval) seconds, or on every beacon creation, if the interval is 0.
160 */
161 if (bt_mesh_priv_beacon_get() == BT_MESH_FEATURE_ENABLED &&
162 interval &&
163 uptime - priv_random.timestamp < (10 * interval * MSEC_PER_SEC) &&
164 priv_random.timestamp != 0) {
165 /* Not time yet */
166 return 0;
167 }
168
169 err = bt_rand(priv_random.val, sizeof(priv_random.val));
170 if (err) {
171 return err;
172 }
173
174 /* Update the index to indicate to all subnets that the private beacon must be regenerated.
175 * Each subnet maintains the random index their private beacon data was generated with.
176 */
177 priv_random.idx++;
178 priv_random.timestamp = uptime;
179
180 return 0;
181 }
182
private_beacon_update(struct bt_mesh_subnet * sub)183 static int private_beacon_update(struct bt_mesh_subnet *sub)
184 {
185 struct bt_mesh_subnet_keys *keys = &sub->keys[SUBNET_KEY_TX_IDX(sub)];
186 uint8_t flags = bt_mesh_net_flags(sub);
187 int err;
188
189 err = bt_mesh_beacon_encrypt(&keys->priv_beacon, flags, bt_mesh.iv_index,
190 priv_random.val, sub->priv_beacon_ctx.data,
191 sub->priv_beacon.auth);
192 if (err) {
193 LOG_ERR("Can't encrypt private beacon");
194 return err;
195 }
196
197 sub->priv_beacon_ctx.idx = priv_random.idx;
198 return 0;
199 }
200
private_beacon_create(struct bt_mesh_subnet * sub,struct net_buf_simple * buf)201 static int private_beacon_create(struct bt_mesh_subnet *sub,
202 struct net_buf_simple *buf)
203 {
204 int err;
205
206 /* Refresh beacon data */
207 err = private_random_update();
208 if (err) {
209 return err;
210 }
211
212 if (sub->priv_beacon_ctx.idx != priv_random.idx) {
213 err = private_beacon_update(sub);
214 if (err) {
215 return err;
216 }
217 }
218
219 net_buf_simple_add_u8(buf, BEACON_TYPE_PRIVATE);
220 net_buf_simple_add_mem(buf, priv_random.val, 13);
221 net_buf_simple_add_mem(buf, sub->priv_beacon_ctx.data, 5);
222 net_buf_simple_add_mem(buf, sub->priv_beacon.auth, 8);
223
224 LOG_DBG("0x%03x", sub->net_idx);
225 return 0;
226 }
227 #endif
228
bt_mesh_beacon_create(struct bt_mesh_subnet * sub,struct net_buf_simple * buf,bool priv)229 int bt_mesh_beacon_create(struct bt_mesh_subnet *sub, struct net_buf_simple *buf, bool priv)
230 {
231 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
232 if (priv) {
233 return private_beacon_create(sub, buf);
234 }
235 #endif
236
237 secure_beacon_create(sub, buf);
238 return 0;
239 }
240
241 /* If the interval has passed or is within 5 seconds from now send a beacon */
242 #define BEACON_THRESHOLD(beacon) \
243 ((10 * ((beacon)->last + 1)) * MSEC_PER_SEC - (5 * MSEC_PER_SEC))
244
secure_beacon_is_running(void)245 static bool secure_beacon_is_running(void)
246 {
247 return bt_mesh_beacon_enabled() ||
248 atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR);
249 }
250
net_beacon_send(struct bt_mesh_subnet * sub,struct bt_mesh_beacon * beacon,void * cb_data,int (* beacon_create)(struct bt_mesh_subnet * sub,struct net_buf_simple * buf))251 static bool net_beacon_send(struct bt_mesh_subnet *sub, struct bt_mesh_beacon *beacon,
252 void *cb_data, int (*beacon_create)(struct bt_mesh_subnet *sub,
253 struct net_buf_simple *buf))
254 {
255 static const struct bt_mesh_send_cb send_cb = {
256 .end = beacon_complete,
257 };
258 uint32_t now = k_uptime_get_32();
259 struct net_buf *buf;
260 uint32_t time_diff;
261 uint32_t time_since_last_recv;
262 int err;
263
264 LOG_DBG("");
265
266 time_diff = now - beacon->sent;
267 time_since_last_recv = now - beacon->recv;
268 if (time_diff < (600 * MSEC_PER_SEC) &&
269 (time_diff < BEACON_THRESHOLD(beacon) ||
270 time_since_last_recv < (10 * MSEC_PER_SEC))) {
271 return false;
272 }
273
274 buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_LOCAL_ADV,
275 PROV_XMIT, K_NO_WAIT);
276 if (!buf) {
277 LOG_ERR("Unable to allocate beacon buffer");
278 return true; /* Bail out */
279 }
280
281 err = beacon_create(sub, &buf->b);
282 if (!err) {
283 bt_mesh_adv_send(buf, &send_cb, beacon);
284 }
285
286 net_buf_unref(buf);
287
288 return err != 0;
289 }
290
net_beacon_for_subnet_send(struct bt_mesh_subnet * sub,void * cb_data)291 static bool net_beacon_for_subnet_send(struct bt_mesh_subnet *sub, void *cb_data)
292 {
293 bool res = true;
294
295 struct {
296 struct bt_mesh_beacon *beacon;
297 bool enabled;
298 int (*create_fn)(struct bt_mesh_subnet *sub, struct net_buf_simple *buf);
299 } beacons[] = {
300 [0] = {
301 .beacon = &sub->secure_beacon,
302 .enabled = secure_beacon_is_running(),
303 .create_fn = secure_beacon_create,
304 },
305 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
306 [1] = {
307 .beacon = &sub->priv_beacon,
308 .enabled = bt_mesh_priv_beacon_get() == BT_MESH_FEATURE_ENABLED,
309 .create_fn = private_beacon_create,
310 },
311 #endif
312 };
313
314 for (int i = 0; i < ARRAY_SIZE(beacons); i++) {
315 if (!beacons[i].enabled) {
316 continue;
317 }
318
319 res = net_beacon_send(sub, beacons[i].beacon, cb_data, beacons[i].create_fn);
320 if (res) {
321 /* Bail out */
322 break;
323 }
324 }
325
326 return res;
327 }
328
unprovisioned_beacon_send(void)329 static int unprovisioned_beacon_send(void)
330 {
331 const struct bt_mesh_prov *prov;
332 uint8_t uri_hash[16] = { 0 };
333 struct net_buf *buf;
334 uint16_t oob_info;
335
336 LOG_DBG("");
337
338 buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_LOCAL_ADV,
339 UNPROV_XMIT, K_NO_WAIT);
340 if (!buf) {
341 LOG_ERR("Unable to allocate beacon buffer");
342 return -ENOBUFS;
343 }
344
345 prov = bt_mesh_prov_get();
346
347 net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED);
348 net_buf_add_mem(buf, prov->uuid, 16);
349
350 if (prov->uri && bt_mesh_s1_str(prov->uri, uri_hash) == 0) {
351 oob_info = prov->oob_info | BT_MESH_PROV_OOB_URI;
352 } else {
353 oob_info = prov->oob_info;
354 }
355
356 net_buf_add_be16(buf, oob_info);
357 net_buf_add_mem(buf, uri_hash, 4);
358
359 bt_mesh_adv_send(buf, NULL, NULL);
360 net_buf_unref(buf);
361
362 if (prov->uri) {
363 size_t len;
364
365 buf = bt_mesh_adv_create(BT_MESH_ADV_URI, BT_MESH_LOCAL_ADV,
366 UNPROV_XMIT, K_NO_WAIT);
367 if (!buf) {
368 LOG_ERR("Unable to allocate URI buffer");
369 return -ENOBUFS;
370 }
371
372 len = strlen(prov->uri);
373 if (net_buf_tailroom(buf) < len) {
374 LOG_WRN("Too long URI to fit advertising data");
375 } else {
376 net_buf_add_mem(buf, prov->uri, len);
377 bt_mesh_adv_send(buf, NULL, NULL);
378 }
379
380 net_buf_unref(buf);
381 }
382
383 return 0;
384 }
385
unprovisioned_beacon_recv(struct net_buf_simple * buf)386 static void unprovisioned_beacon_recv(struct net_buf_simple *buf)
387 {
388 const struct bt_mesh_prov *prov;
389 uint8_t *uuid;
390 uint16_t oob_info;
391 uint32_t uri_hash_val;
392 uint32_t *uri_hash = NULL;
393
394 prov = bt_mesh_prov_get();
395
396 if (!prov->unprovisioned_beacon) {
397 return;
398 }
399
400 if (buf->len != 18 && buf->len != 22) {
401 LOG_ERR("Invalid unprovisioned beacon length (%u)", buf->len);
402 return;
403 }
404
405 uuid = net_buf_simple_pull_mem(buf, 16);
406 oob_info = net_buf_simple_pull_be16(buf);
407
408 if (buf->len == 4) {
409 uri_hash_val = net_buf_simple_pull_be32(buf);
410 uri_hash = &uri_hash_val;
411 }
412
413 LOG_DBG("uuid %s", bt_hex(uuid, 16));
414
415 prov->unprovisioned_beacon(uuid,
416 (bt_mesh_prov_oob_info_t)oob_info,
417 uri_hash);
418 }
419
sub_update_beacon_observation(struct bt_mesh_subnet * sub)420 static void sub_update_beacon_observation(struct bt_mesh_subnet *sub)
421 {
422 sub->secure_beacon.last = sub->secure_beacon.cur;
423 sub->secure_beacon.cur = 0U;
424
425 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
426 sub->priv_beacon.last = sub->priv_beacon.cur;
427 sub->priv_beacon.cur = 0U;
428 #endif
429 }
430
update_beacon_observation(void)431 static void update_beacon_observation(void)
432 {
433 static bool first_half;
434
435 /* Observation period is 20 seconds, whereas the beacon timer
436 * runs every 10 seconds. We process what's happened during the
437 * window only after the second half.
438 */
439 first_half = !first_half;
440 if (first_half) {
441 return;
442 }
443
444 bt_mesh_subnet_foreach(sub_update_beacon_observation);
445 }
446
net_beacon_is_running(void)447 static bool net_beacon_is_running(void)
448 {
449 return secure_beacon_is_running() ||
450 (bt_mesh_priv_beacon_get() == BT_MESH_FEATURE_ENABLED);
451 }
452
beacon_send(struct k_work * work)453 static void beacon_send(struct k_work *work)
454 {
455 LOG_DBG("");
456
457 if (bt_mesh_is_provisioned()) {
458 if (!net_beacon_is_running()) {
459 return;
460 }
461
462 update_beacon_observation();
463 (void)bt_mesh_subnet_find(net_beacon_for_subnet_send, NULL);
464
465 k_work_schedule(&beacon_timer, PROVISIONED_INTERVAL);
466 return;
467 }
468
469 if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) {
470 /* Don't send anything if we have an active provisioning link */
471 if (!bt_mesh_prov_active()) {
472 unprovisioned_beacon_send();
473 }
474
475 k_work_schedule(&beacon_timer, K_SECONDS(CONFIG_BT_MESH_UNPROV_BEACON_INT));
476 }
477
478 }
479
auth_match(struct bt_mesh_subnet_keys * keys,const struct beacon_params * params)480 static bool auth_match(struct bt_mesh_subnet_keys *keys,
481 const struct beacon_params *params)
482 {
483 uint8_t net_auth[8];
484
485 if (memcmp(params->net_id, keys->net_id, 8)) {
486 return false;
487 }
488
489 if (bt_mesh_beacon_auth(&keys->beacon, params->flags, keys->net_id, params->iv_index,
490 net_auth)) {
491 return false;
492 }
493
494 if (memcmp(params->auth, net_auth, 8)) {
495 LOG_WRN("Invalid auth value. Received auth: %s", bt_hex(params->auth, 8));
496 LOG_WRN("Calculated auth: %s", bt_hex(net_auth, 8));
497 return false;
498 }
499
500 return true;
501 }
502
secure_beacon_authenticate(struct bt_mesh_subnet * sub,void * cb_data)503 static bool secure_beacon_authenticate(struct bt_mesh_subnet *sub, void *cb_data)
504 {
505 struct beacon_params *params = cb_data;
506
507 for (int i = 0; i < ARRAY_SIZE(sub->keys); i++) {
508 if (sub->keys[i].valid && auth_match(&sub->keys[i], params)) {
509 params->new_key = (i > 0);
510 #if defined(CONFIG_BT_TESTING)
511 struct bt_mesh_snb beacon_info;
512
513 beacon_info.flags = params->flags;
514 memcpy(&beacon_info.net_id, params->net_id, 8);
515 beacon_info.iv_idx = params->iv_index;
516 memcpy(&beacon_info.auth_val, params->auth, 8);
517
518 STRUCT_SECTION_FOREACH(bt_mesh_beacon_cb, cb) {
519 if (cb->snb_received) {
520 cb->snb_received(&beacon_info);
521 }
522 }
523 #endif
524
525 return true;
526 }
527 }
528
529 return false;
530 }
531
532 #if defined(CONFIG_BT_MESH_V1d1)
priv_beacon_decrypt(struct bt_mesh_subnet * sub,void * cb_data)533 static bool priv_beacon_decrypt(struct bt_mesh_subnet *sub, void *cb_data)
534 {
535 struct beacon_params *params = cb_data;
536 uint8_t out[5];
537 int err;
538
539 for (int i = 0; i < ARRAY_SIZE(sub->keys); i++) {
540 if (!sub->keys[i].valid) {
541 continue;
542 }
543
544 err = bt_mesh_beacon_decrypt(&sub->keys[i].priv_beacon, params->random,
545 params->data, params->auth, out);
546 if (!err) {
547 params->new_key = (i > 0);
548 params->flags = out[0];
549 params->iv_index = sys_get_be32(&out[1]);
550
551 #if defined(CONFIG_BT_TESTING)
552 struct bt_mesh_prb beacon_info;
553
554 memcpy(beacon_info.random, params->random, 13);
555 beacon_info.flags = params->flags;
556 beacon_info.iv_idx = params->iv_index;
557 memcpy(&beacon_info.auth_tag, params->auth, 8);
558
559 STRUCT_SECTION_FOREACH(bt_mesh_beacon_cb, cb) {
560 if (cb->priv_received) {
561 cb->priv_received(&beacon_info);
562 }
563 }
564 #endif
565 return true;
566 }
567 }
568
569 return false;
570 }
571 #endif
572
net_beacon_register(struct bt_mesh_beacon * beacon,bool priv)573 static void net_beacon_register(struct bt_mesh_beacon *beacon, bool priv)
574 {
575 if (((priv && bt_mesh_priv_beacon_get() == BT_MESH_PRIV_GATT_PROXY_ENABLED) ||
576 bt_mesh_beacon_enabled()) && beacon->cur < 0xff) {
577 beacon->cur++;
578 beacon->recv = k_uptime_get_32();
579 }
580 }
581
net_beacon_recv(struct bt_mesh_subnet * sub,const struct beacon_params * params)582 static void net_beacon_recv(struct bt_mesh_subnet *sub,
583 const struct beacon_params *params)
584 {
585 bt_mesh_kr_update(sub, BT_MESH_KEY_REFRESH(params->flags),
586 params->new_key);
587
588 /* If we have NetKey0 accept IV index initiation only from it */
589 if (bt_mesh_subnet_get(BT_MESH_KEY_PRIMARY) &&
590 sub->net_idx != BT_MESH_KEY_PRIMARY) {
591 LOG_WRN("Ignoring secure beacon on non-primary subnet");
592 return;
593 }
594
595 LOG_DBG("net_idx 0x%04x flags %u iv_index 0x%08x, "
596 "current iv_index 0x%08x",
597 sub->net_idx, params->flags, params->iv_index, bt_mesh.iv_index);
598
599 if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR) &&
600 (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) ==
601 BT_MESH_IV_UPDATE(params->flags))) {
602 bt_mesh_beacon_ivu_initiator(false);
603 }
604
605 bt_mesh_net_iv_update(params->iv_index,
606 BT_MESH_IV_UPDATE(params->flags));
607 }
608
net_beacon_resolve(struct beacon_params * params,bool (* matcher)(struct bt_mesh_subnet * sub,void * cb_data))609 static void net_beacon_resolve(struct beacon_params *params,
610 bool (*matcher)(struct bt_mesh_subnet *sub,
611 void *cb_data))
612 {
613 struct bt_mesh_subnet *sub;
614 struct bt_mesh_beacon *beacon;
615
616 sub = bt_mesh_subnet_find(beacon_cache_match, (void *)params);
617 if (sub) {
618 beacon = subnet_beacon_get_by_type(sub, params->private);
619
620 /* We've seen this beacon before - just update the stats */
621 net_beacon_register(beacon, params->private);
622 return;
623 }
624
625 sub = bt_mesh_subnet_find(matcher, params);
626 if (!sub) {
627 LOG_DBG("No subnet that matched beacon");
628 return;
629 }
630
631 if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !params->new_key) {
632 LOG_WRN("Ignoring Phase 2 KR Update secured using old key");
633 return;
634 }
635
636 beacon = subnet_beacon_get_by_type(sub, params->private);
637
638 cache_add(params->auth, beacon);
639
640 net_beacon_recv(sub, params);
641 net_beacon_register(beacon, params->private);
642 }
643
secure_beacon_recv(struct net_buf_simple * buf)644 static void secure_beacon_recv(struct net_buf_simple *buf)
645 {
646 struct beacon_params params;
647
648 if (buf->len < 21) {
649 LOG_ERR("Too short secure beacon (len %u)", buf->len);
650 return;
651 }
652
653 params.private = false;
654 params.flags = net_buf_simple_pull_u8(buf);
655 params.net_id = net_buf_simple_pull_mem(buf, 8);
656 params.iv_index = net_buf_simple_pull_be32(buf);
657 params.auth = buf->data;
658
659 net_beacon_resolve(¶ms, secure_beacon_authenticate);
660 }
661
662 #if defined(CONFIG_BT_MESH_V1d1)
private_beacon_recv(struct net_buf_simple * buf)663 static void private_beacon_recv(struct net_buf_simple *buf)
664 {
665 struct beacon_params params;
666
667 if (buf->len < 26) {
668 LOG_ERR("Too short private beacon (len %u)", buf->len);
669 return;
670 }
671
672 params.private = true;
673 params.random = net_buf_simple_pull_mem(buf, 13);
674 params.data = net_buf_simple_pull_mem(buf, 5);
675 params.auth = buf->data;
676
677 net_beacon_resolve(¶ms, priv_beacon_decrypt);
678 }
679 #endif
680
bt_mesh_beacon_recv(struct net_buf_simple * buf)681 void bt_mesh_beacon_recv(struct net_buf_simple *buf)
682 {
683 uint8_t type;
684
685 LOG_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));
686
687 if (buf->len < 1) {
688 LOG_ERR("Too short beacon");
689 return;
690 }
691
692 type = net_buf_simple_pull_u8(buf);
693 switch (type) {
694 case BEACON_TYPE_UNPROVISIONED:
695 if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) {
696 unprovisioned_beacon_recv(buf);
697 }
698 break;
699 case BEACON_TYPE_SECURE:
700 secure_beacon_recv(buf);
701 break;
702 case BEACON_TYPE_PRIVATE:
703 #if defined(CONFIG_BT_MESH_V1d1)
704 private_beacon_recv(buf);
705 #endif
706 break;
707 default:
708 LOG_WRN("Unknown beacon type 0x%02x", type);
709 break;
710 }
711 }
712
bt_mesh_beacon_update(struct bt_mesh_subnet * sub)713 void bt_mesh_beacon_update(struct bt_mesh_subnet *sub)
714 {
715 uint8_t flags = bt_mesh_net_flags(sub);
716 struct bt_mesh_subnet_keys *keys;
717
718 keys = &sub->keys[SUBNET_KEY_TX_IDX(sub)];
719
720 LOG_DBG("NetIndex 0x%03x Using %s key", sub->net_idx,
721 SUBNET_KEY_TX_IDX(sub) ? "new" : "current");
722 LOG_DBG("flags 0x%02x, IVI 0x%08x", flags, bt_mesh.iv_index);
723
724 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
725 /* Invalidate private beacon to force regeneration: */
726 sub->priv_beacon_ctx.idx = priv_random.idx - 1;
727 priv_random.timestamp = 0;
728 #endif
729
730 bt_mesh_beacon_auth(&keys->beacon, flags, keys->net_id, bt_mesh.iv_index,
731 sub->secure_beacon.auth);
732 }
733
subnet_evt(struct bt_mesh_subnet * sub,enum bt_mesh_key_evt evt)734 static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt)
735 {
736 if (evt != BT_MESH_KEY_DELETED) {
737 bt_mesh_beacon_update(sub);
738 }
739 }
740
741 BT_MESH_SUBNET_CB_DEFINE(beacon) = {
742 .evt_handler = subnet_evt,
743 };
744
bt_mesh_beacon_init(void)745 void bt_mesh_beacon_init(void)
746 {
747 k_work_init_delayable(&beacon_timer, beacon_send);
748
749 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
750 private_random_update();
751 #endif
752 }
753
bt_mesh_beacon_ivu_initiator(bool enable)754 void bt_mesh_beacon_ivu_initiator(bool enable)
755 {
756 atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_INITIATOR, enable);
757
758 /* Fire the beacon handler straight away if it's not already pending -
759 * in which case we'll fire according to the ongoing periodic sending.
760 * If beacons are disabled, the handler will exit early.
761 *
762 * An alternative solution would be to check whether beacons are enabled
763 * here, and cancel if not. As the cancel operation may fail, we would
764 * still have to implement an early exit mechanism, so we might as well
765 * just use this every time.
766 */
767 k_work_schedule(&beacon_timer, K_NO_WAIT);
768 }
769
subnet_beacon_enable(struct bt_mesh_subnet * sub)770 static void subnet_beacon_enable(struct bt_mesh_subnet *sub)
771 {
772 sub->secure_beacon.last = 0U;
773 sub->secure_beacon.cur = 0U;
774
775 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
776 sub->priv_beacon.last = 0U;
777 sub->priv_beacon.cur = 0U;
778 #endif
779
780 bt_mesh_beacon_update(sub);
781 }
782
bt_mesh_beacon_enable(void)783 void bt_mesh_beacon_enable(void)
784 {
785 if (bt_mesh_is_provisioned()) {
786 bt_mesh_subnet_foreach(subnet_beacon_enable);
787 }
788
789 k_work_reschedule(&beacon_timer, K_NO_WAIT);
790 }
791
bt_mesh_beacon_disable(void)792 void bt_mesh_beacon_disable(void)
793 {
794 /* If this fails, we'll do an early exit in the work handler. */
795 (void)k_work_cancel_delayable(&beacon_timer);
796 }
797