1 /* Bluetooth Mesh */
2
3 /*
4 * SPDX-FileCopyrightText: 2017 Intel Corporation
5 * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #include <string.h>
11 #include <errno.h>
12
13 #include "adv.h"
14 #include "mesh.h"
15 #include "prov.h"
16 #include "crypto.h"
17 #include "beacon.h"
18 #include "access.h"
19 #include "foundation.h"
20 #include "proxy_client.h"
21 #include "mesh_main.h"
22 #include "provisioner_prov.h"
23 #include "provisioner_main.h"
24
25 #if defined(CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL)
26 #define UNPROVISIONED_INTERVAL K_SECONDS(CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL)
27 #else
28 #define UNPROVISIONED_INTERVAL K_SECONDS(5)
29 #endif
30
31 #if CONFIG_BLE_MESH_BQB_TEST
32 #define PROVISIONED_INTERVAL K_SECONDS(3)
33 #else
34 #define PROVISIONED_INTERVAL K_SECONDS(10)
35 #endif
36
37 #define BEACON_TYPE_UNPROVISIONED 0x00
38 #define BEACON_TYPE_SECURE 0x01
39
40 /* 3 transmissions, 20ms interval */
41 #define UNPROV_XMIT BLE_MESH_TRANSMIT(2, 20)
42
43 /* 1 transmission, 20ms interval */
44 #define PROV_XMIT BLE_MESH_TRANSMIT(0, 20)
45
46 #define SNB_NET_IDX_SET(_val) ((void *)((uint32_t)(_val)))
47 #define SNB_NET_IDX_GET(_ptr) ((uint32_t)(_ptr))
48
49 static struct k_delayed_work beacon_timer;
50
cache_check(uint8_t data[21])51 static struct bt_mesh_subnet *cache_check(uint8_t data[21])
52 {
53 size_t subnet_size = 0U;
54 int i = 0;
55
56 subnet_size = bt_mesh_rx_netkey_size();
57
58 for (i = 0; i < subnet_size; i++) {
59 struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i);
60
61 if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) {
62 continue;
63 }
64
65 if (!memcmp(sub->beacon_cache, data, 21)) {
66 return sub;
67 }
68 }
69
70 return NULL;
71 }
72
cache_add(uint8_t data[21],struct bt_mesh_subnet * sub)73 static void cache_add(uint8_t data[21], struct bt_mesh_subnet *sub)
74 {
75 memcpy(sub->beacon_cache, data, 21);
76 }
77
beacon_complete(int err,void * user_data)78 static void beacon_complete(int err, void *user_data)
79 {
80 struct bt_mesh_subnet *sub = NULL;
81 uint16_t net_idx = BLE_MESH_KEY_UNUSED;
82
83 BT_DBG("err %d", err);
84
85 net_idx = (uint16_t)SNB_NET_IDX_GET(user_data);
86
87 /* For node, directly updating the "beacon_sent" timestamp is fine,
88 * since the subnet is pre-allocated.
89 * For Provisioner, before updating the "beacon_sent" timestamp, we
90 * need to make sure that the subnet still exists, because there is
91 * a chance that the subnet is removed just before the completion of
92 * sending the Secure Network Beacon.
93 */
94 if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
95 sub = bt_mesh_subnet_get(net_idx);
96 } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) &&
97 bt_mesh_is_provisioner_en()) {
98 sub = bt_mesh_provisioner_subnet_get(net_idx);
99 }
100
101 if (sub) {
102 sub->beacon_sent = k_uptime_get_32();
103 }
104 }
105
bt_mesh_beacon_create(struct bt_mesh_subnet * sub,struct net_buf_simple * buf)106 void bt_mesh_beacon_create(struct bt_mesh_subnet *sub,
107 struct net_buf_simple *buf)
108 {
109 uint8_t flags = bt_mesh_net_flags(sub);
110 struct bt_mesh_subnet_keys *keys = NULL;
111
112 net_buf_simple_add_u8(buf, BEACON_TYPE_SECURE);
113
114 if (sub->kr_flag) {
115 keys = &sub->keys[1];
116 } else {
117 keys = &sub->keys[0];
118 }
119
120 net_buf_simple_add_u8(buf, flags);
121
122 /* Network ID */
123 net_buf_simple_add_mem(buf, keys->net_id, 8);
124
125 /* IV Index */
126 net_buf_simple_add_be32(buf, bt_mesh.iv_index);
127
128 net_buf_simple_add_mem(buf, sub->auth, 8);
129
130 BT_INFO("net_idx 0x%03x iv_index 0x%08x flags 0x%02x",
131 sub->net_idx, bt_mesh.iv_index, flags);
132 BT_DBG("NetID %s Auth %s", bt_hex(keys->net_id, 8),
133 bt_hex(sub->auth, 8));
134 }
135
136 /* If the interval has passed or is within 5 seconds from now send a beacon */
137 #define BEACON_THRESHOLD(sub) (K_SECONDS(10 * ((sub)->beacons_last + 1)) - K_SECONDS(5))
138
secure_beacon_send(void)139 static int secure_beacon_send(void)
140 {
141 static const struct bt_mesh_send_cb send_cb = {
142 .end = beacon_complete,
143 };
144 uint32_t now = k_uptime_get_32();
145 size_t subnet_size = 0U;
146 int i = 0;
147
148 BT_DBG("%s", __func__);
149
150 subnet_size = bt_mesh_rx_netkey_size();
151
152 for (i = 0; i < subnet_size; i++) {
153 struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i);
154 struct net_buf *buf;
155 uint32_t time_diff;
156
157 if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) {
158 continue;
159 }
160
161 time_diff = now - sub->beacon_sent;
162 if (time_diff < K_SECONDS(600) &&
163 time_diff < BEACON_THRESHOLD(sub)) {
164 continue;
165 }
166
167 /**
168 * If a node enables the Proxy Client functionality, and it
169 * succeeds to send Secure Network Beacon with GATT bearer,
170 * here we will continue to send Secure Network Beacon of
171 * other subnets.
172 */
173 #if defined(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)
174 if (bt_mesh_proxy_client_beacon_send(sub)) {
175 continue;
176 }
177 #endif
178
179 buf = bt_mesh_adv_create(BLE_MESH_ADV_BEACON, PROV_XMIT,
180 K_NO_WAIT);
181 if (!buf) {
182 BT_ERR("Out of beacon buffer");
183 return -ENOBUFS;
184 }
185
186 bt_mesh_beacon_create(sub, &buf->b);
187
188 /* Care should be taken here. Previously the user_data is the
189 * pointer of a subnet. When the device is a Provisioner, its
190 * subnet is created dynamically. If the corresponding subnet
191 * is removed right after the Secure Network Beacon is sent,
192 * update its "beacon_sent" timestamp in beacon_complete() will
193 * cause exception.
194 * Here we use the "net_idx" of the subnet instead. And in the
195 * beacon_complete(), we will try to get the subnet before
196 * updating its "beacon_sent" timestamp.
197 */
198 bt_mesh_adv_send(buf, &send_cb, SNB_NET_IDX_SET(sub->net_idx));
199 net_buf_unref(buf);
200 }
201
202 return 0;
203 }
204
205 #if defined(CONFIG_BLE_MESH_NODE)
unprovisioned_beacon_send(void)206 static int unprovisioned_beacon_send(void)
207 {
208 #if defined(CONFIG_BLE_MESH_PB_ADV)
209 const struct bt_mesh_prov *prov = NULL;
210 uint8_t uri_hash[16] = { 0 };
211 struct net_buf *buf = NULL;
212 uint16_t oob_info = 0U;
213
214 BT_DBG("%s", __func__);
215
216 buf = bt_mesh_adv_create(BLE_MESH_ADV_BEACON, UNPROV_XMIT, K_NO_WAIT);
217 if (!buf) {
218 BT_ERR("Out of beacon buffer");
219 return -ENOBUFS;
220 }
221
222 prov = bt_mesh_prov_get();
223
224 net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED);
225 net_buf_add_mem(buf, prov->uuid, 16);
226
227 if (prov->uri && bt_mesh_s1(prov->uri, uri_hash) == 0) {
228 oob_info = prov->oob_info | BLE_MESH_PROV_OOB_URI;
229 } else {
230 oob_info = prov->oob_info;
231 }
232
233 net_buf_add_be16(buf, oob_info);
234 net_buf_add_mem(buf, uri_hash, 4);
235
236 bt_mesh_adv_send(buf, NULL, NULL);
237 net_buf_unref(buf);
238
239 if (prov->uri) {
240 size_t len;
241
242 buf = bt_mesh_adv_create(BLE_MESH_ADV_URI, UNPROV_XMIT,
243 K_NO_WAIT);
244 if (!buf) {
245 BT_ERR("Unable to allocate URI buffer");
246 return -ENOBUFS;
247 }
248
249 len = strlen(prov->uri);
250 if (net_buf_tailroom(buf) < len) {
251 BT_WARN("Too long URI to fit advertising data");
252 } else {
253 net_buf_add_mem(buf, prov->uri, len);
254 bt_mesh_adv_send(buf, NULL, NULL);
255 }
256
257 net_buf_unref(buf);
258 }
259
260 #endif /* CONFIG_BLE_MESH_PB_ADV */
261 return 0;
262 }
263 #else /* CONFIG_BLE_MESH_NODE */
unprovisioned_beacon_send(void)264 static int unprovisioned_beacon_send(void)
265 {
266 return 0;
267 }
268 #endif /* CONFIG_BLE_MESH_NODE */
269
update_beacon_observation(void)270 static void update_beacon_observation(void)
271 {
272 static bool first_half;
273 size_t subnet_size = 0U;
274 int i = 0;
275
276 /* Observation period is 20 seconds, whereas the beacon timer
277 * runs every 10 seconds. We process what's happened during the
278 * window only after the second half.
279 */
280 first_half = !first_half;
281 if (first_half) {
282 return;
283 }
284
285 subnet_size = bt_mesh_rx_netkey_size();
286
287 for (i = 0; i < subnet_size; i++) {
288 struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i);
289
290 if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) {
291 continue;
292 }
293
294 sub->beacons_last = sub->beacons_cur;
295 sub->beacons_cur = 0U;
296 }
297 }
298
ready_to_send(void)299 static bool ready_to_send(void)
300 {
301 if (bt_mesh_is_provisioned() || bt_mesh_is_provisioner_en()) {
302 return true;
303 }
304 return false;
305 }
306
beacon_send(struct k_work * work)307 static void beacon_send(struct k_work *work)
308 {
309 /* Don't send anything if we have an active provisioning link */
310 if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() &&
311 IS_ENABLED(CONFIG_BLE_MESH_PROV) && bt_prov_active()) {
312 k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL);
313 return;
314 }
315
316 BT_DBG("%s", __func__);
317
318 if (ready_to_send()) {
319 update_beacon_observation();
320 secure_beacon_send();
321
322 /* Only resubmit if beaconing is still enabled */
323 if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED ||
324 bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR)) {
325 k_delayed_work_submit(&beacon_timer,
326 PROVISIONED_INTERVAL);
327 }
328 } else {
329 if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node()) {
330 unprovisioned_beacon_send();
331 k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL);
332 }
333 }
334
335 }
336
secure_beacon_recv(struct net_buf_simple * buf)337 static void secure_beacon_recv(struct net_buf_simple *buf)
338 {
339 uint8_t *data = NULL, *net_id = NULL, *auth = NULL;
340 struct bt_mesh_subnet *sub = NULL;
341 uint32_t iv_index = 0U;
342 bool kr_change = false;
343 bool iv_change = false;
344 bool new_key = false;
345 uint8_t flags = 0U;
346
347 if (buf->len < 21) {
348 BT_ERR("Too short secure beacon (len %u)", buf->len);
349 return;
350 }
351
352 sub = cache_check(buf->data);
353 if (sub) {
354 /* We've seen this beacon before - just update the stats */
355 goto update_stats;
356 }
357
358 /* So we can add to the cache if auth matches */
359 data = buf->data;
360
361 flags = net_buf_simple_pull_u8(buf);
362 net_id = net_buf_simple_pull_mem(buf, 8);
363 iv_index = net_buf_simple_pull_be32(buf);
364 auth = buf->data;
365
366 BT_DBG("flags 0x%02x id %s iv_index 0x%08x",
367 flags, bt_hex(net_id, 8), iv_index);
368
369 sub = bt_mesh_subnet_find(net_id, flags, iv_index, auth, &new_key);
370 if (!sub) {
371 BT_DBG("No subnet that matched beacon");
372 return;
373 }
374
375 if (sub->kr_phase == BLE_MESH_KR_PHASE_2 && !new_key) {
376 BT_WARN("Ignoring Phase 2 KR Update secured using old key");
377 return;
378 }
379
380 cache_add(data, sub);
381
382 /* Spec v1.0.1, Section 3.8.4:
383 * If a node on a primary subnet receives an update on
384 * the primary subnet, it shall propagate the IV update
385 * to all other subnets. If a node on a primary subnet
386 * receives an IV update on any other subnet, the update
387 * shall be ignored.
388 * If a node on a primary subnet receives an key update
389 * on any other subnet, the update shall not be ignored.
390 */
391 if (bt_mesh_primary_subnet_exist() &&
392 sub->net_idx != BLE_MESH_KEY_PRIMARY &&
393 BLE_MESH_IV_UPDATE(flags) &&
394 !BLE_MESH_KEY_REFRESH(flags)) {
395 BT_WARN("Ignoring secure beacon on non-primary subnet");
396 goto update_stats;
397 }
398
399 BT_INFO("net_idx 0x%03x iv_index 0x%08x current iv_index 0x%08x",
400 sub->net_idx, iv_index, bt_mesh.iv_index);
401
402 if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR) &&
403 (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS) ==
404 BLE_MESH_IV_UPDATE(flags))) {
405 bt_mesh_beacon_ivu_initiator(false);
406 }
407
408 /* If a node on a primary subnet receives an IV update on any other subnet,
409 * the IV update shall be ignored. And if a node on a non-primary subnet
410 * receives an IV update on primary subnet, the IV update shall be ignored,
411 * because it doesn't have a primary network key.
412 */
413 if ((bt_mesh_primary_subnet_exist() && sub->net_idx == BLE_MESH_KEY_PRIMARY) ||
414 (!bt_mesh_primary_subnet_exist() && sub->net_idx != BLE_MESH_KEY_PRIMARY)) {
415 iv_change = bt_mesh_net_iv_update(iv_index, BLE_MESH_IV_UPDATE(flags));
416 }
417
418 kr_change = bt_mesh_kr_update(sub, BLE_MESH_KEY_REFRESH(flags), new_key);
419 if (kr_change) {
420 bt_mesh_net_beacon_update(sub);
421 }
422
423 if (iv_change) {
424 /* Update all subnets */
425 bt_mesh_net_sec_update(NULL);
426 } else if (kr_change) {
427 /* Key Refresh without IV Update only impacts one subnet */
428 bt_mesh_net_sec_update(sub);
429 }
430
431 update_stats:
432 if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED &&
433 sub->beacons_cur < 0xff) {
434 sub->beacons_cur++;
435 }
436 }
437
bt_mesh_beacon_recv(struct net_buf_simple * buf,int8_t rssi)438 void bt_mesh_beacon_recv(struct net_buf_simple *buf, int8_t rssi)
439 {
440 uint8_t type = 0U;
441
442 BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));
443
444 if (buf->len < 1) {
445 BT_ERR("Too short beacon");
446 return;
447 }
448
449 type = net_buf_simple_pull_u8(buf);
450 switch (type) {
451 case BEACON_TYPE_UNPROVISIONED:
452 BT_DBG("Unprovisioned device beacon received");
453 if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) &&
454 bt_mesh_is_provisioner_en()) {
455 bt_mesh_provisioner_unprov_beacon_recv(buf, rssi);
456 }
457 break;
458 case BEACON_TYPE_SECURE:
459 secure_beacon_recv(buf);
460 break;
461 default:
462 BT_DBG("Unknown beacon type 0x%02x", type);
463 break;
464 }
465 }
466
bt_mesh_beacon_init(void)467 void bt_mesh_beacon_init(void)
468 {
469 k_delayed_work_init(&beacon_timer, beacon_send);
470 }
471
472 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_beacon_deinit(void)473 void bt_mesh_beacon_deinit(void)
474 {
475 k_delayed_work_free(&beacon_timer);
476 }
477 #endif /* CONFIG_BLE_MESH_DEINIT */
478
bt_mesh_beacon_ivu_initiator(bool enable)479 void bt_mesh_beacon_ivu_initiator(bool enable)
480 {
481 bt_mesh_atomic_set_bit_to(bt_mesh.flags, BLE_MESH_IVU_INITIATOR, enable);
482
483 if (enable) {
484 k_work_submit(&beacon_timer.work);
485 } else if (bt_mesh_beacon_get() == BLE_MESH_BEACON_DISABLED) {
486 k_delayed_work_cancel(&beacon_timer);
487 }
488 }
489
bt_mesh_beacon_enable(void)490 void bt_mesh_beacon_enable(void)
491 {
492 size_t subnet_size = 0U;
493 int i = 0;
494
495 if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node() &&
496 !bt_mesh_is_provisioned()) {
497 k_work_submit(&beacon_timer.work);
498 return;
499 }
500
501 subnet_size = bt_mesh_rx_netkey_size();
502
503 for (i = 0; i < subnet_size; i++) {
504 struct bt_mesh_subnet *sub = bt_mesh_rx_netkey_get(i);
505
506 if (sub == NULL || sub->net_idx == BLE_MESH_KEY_UNUSED) {
507 continue;
508 }
509
510 sub->beacons_last = 0U;
511 sub->beacons_cur = 0U;
512
513 bt_mesh_net_beacon_update(sub);
514 }
515
516 k_work_submit(&beacon_timer.work);
517 }
518
bt_mesh_beacon_disable(void)519 void bt_mesh_beacon_disable(void)
520 {
521 if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR)) {
522 k_delayed_work_cancel(&beacon_timer);
523 }
524 }
525