1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdlib.h>
8 #include <zephyr/sys/slist.h>
9 #include <zephyr/sys/byteorder.h>
10 #include <zephyr/bluetooth/hci.h>
11 #include <zephyr/bluetooth/crypto.h>
12 #include <zephyr/bluetooth/mesh/rpr_srv.h>
13 #include <common/bt_str.h>
14 #include <zephyr/bluetooth/mesh/sar_cfg.h>
15 #include <zephyr/bluetooth/mesh/keys.h>
16 #include "access.h"
17 #include "prov.h"
18 #include "crypto.h"
19 #include "rpr.h"
20 #include "net.h"
21 #include "mesh.h"
22
23 #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
24 #include <zephyr/logging/log.h>
25 LOG_MODULE_REGISTER(bt_mesh_rpr_srv);
26
27 #define LINK_OPEN_TIMEOUT_DEFAULT 10
28
29 #define LINK_CTX(_cli, _send_rel) \
30 { \
31 .net_idx = (_cli)->net_idx, .app_idx = BT_MESH_KEY_DEV_LOCAL, \
32 .addr = (_cli)->addr, .send_ttl = (_cli)->ttl, \
33 .send_rel = (_send_rel) \
34 }
35
36 enum {
37 SCANNING,
38 SCAN_REPORT_PENDING,
39 SCAN_EXT_HAS_ADDR,
40 NODE_REFRESH,
41 URI_MATCHED,
42 URI_REQUESTED,
43
44 RPR_SRV_NUM_FLAGS,
45 };
46
47 /** Remote provisioning server instance. */
48 static struct {
49 const struct bt_mesh_model *mod;
50
51 ATOMIC_DEFINE(flags, RPR_SRV_NUM_FLAGS);
52
53 struct {
54 struct bt_mesh_rpr_unprov
55 devs[CONFIG_BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX];
56 uint8_t max_devs;
57 enum bt_mesh_rpr_scan state;
58 struct k_work_delayable report;
59 struct k_work_delayable timeout;
60 /* Extended scanning */
61 bt_addr_le_t addr;
62 uint8_t ad[CONFIG_BT_MESH_RPR_AD_TYPES_MAX];
63 uint8_t ad_count;
64 /* Time to do regular scanning after extended scanning ends: */
65 uint32_t additional_time;
66 struct net_buf_simple *adv_data;
67 struct bt_mesh_rpr_node cli;
68 struct bt_mesh_rpr_unprov *dev;
69 } scan;
70 struct {
71 struct k_work report;
72 enum bt_mesh_rpr_link_state state;
73 enum bt_mesh_rpr_status status;
74 uint8_t close_reason;
75 uint8_t tx_pdu;
76 uint8_t rx_pdu;
77 struct bt_mesh_rpr_node cli;
78 struct bt_mesh_rpr_unprov *dev;
79 } link;
80 struct {
81 const struct prov_bearer_cb *cb;
82 enum bt_mesh_rpr_node_refresh procedure;
83 void *cb_data;
84 struct {
85 prov_bearer_send_complete_t cb;
86 void *cb_data;
87 } tx;
88 } refresh;
89 } srv = {
90 .scan = {
91 .adv_data = NET_BUF_SIMPLE(CONFIG_BT_MESH_RPR_SRV_AD_DATA_MAX)
92 }
93 };
94
bt_mesh_node_refresh_get(void)95 enum bt_mesh_rpr_node_refresh bt_mesh_node_refresh_get(void)
96 {
97 return srv.refresh.procedure;
98 }
99
unprov_get(const uint8_t uuid[16])100 static struct bt_mesh_rpr_unprov *unprov_get(const uint8_t uuid[16])
101 {
102 int i;
103
104 for (i = 0; i < srv.scan.max_devs; ++i) {
105 if (uuid) {
106 if ((srv.scan.devs[i].flags & BT_MESH_RPR_UNPROV_ACTIVE) &&
107 !memcmp(srv.scan.devs[i].uuid, uuid, 16)) {
108 return &srv.scan.devs[i];
109 }
110 } else if (!(srv.scan.devs[i].flags & BT_MESH_RPR_UNPROV_ACTIVE)) {
111 return &srv.scan.devs[i];
112 }
113 }
114
115 return NULL;
116 }
117
get_ad_type(uint8_t * list,size_t count,uint8_t ad)118 static uint8_t *get_ad_type(uint8_t *list, size_t count, uint8_t ad)
119 {
120 int i;
121
122 for (i = 0; i < count; ++i) {
123 if (ad == list[i] || (ad == BT_DATA_NAME_SHORTENED &&
124 list[i] == BT_DATA_NAME_COMPLETE)) {
125 return &list[i];
126 }
127 }
128
129 return NULL;
130 }
131
cli_scan_clear(void)132 static void cli_scan_clear(void)
133 {
134 srv.scan.cli.addr = BT_MESH_ADDR_UNASSIGNED;
135 srv.scan.cli.net_idx = BT_MESH_KEY_UNUSED;
136 }
137
cli_link_clear(void)138 static void cli_link_clear(void)
139 {
140 srv.link.cli.addr = BT_MESH_ADDR_UNASSIGNED;
141 srv.link.cli.net_idx = BT_MESH_KEY_UNUSED;
142 }
143
scan_status_send(struct bt_mesh_msg_ctx * ctx,enum bt_mesh_rpr_status status)144 static void scan_status_send(struct bt_mesh_msg_ctx *ctx,
145 enum bt_mesh_rpr_status status)
146 {
147 uint8_t timeout = 0;
148
149 if (atomic_test_bit(srv.flags, SCANNING)) {
150 timeout = k_ticks_to_ms_floor32(
151 k_work_delayable_remaining_get(&srv.scan.timeout)) /
152 MSEC_PER_SEC;
153 }
154
155 BT_MESH_MODEL_BUF_DEFINE(rsp, RPR_OP_SCAN_STATUS, 4);
156 bt_mesh_model_msg_init(&rsp, RPR_OP_SCAN_STATUS);
157 net_buf_simple_add_u8(&rsp, status);
158 net_buf_simple_add_u8(&rsp, srv.scan.state);
159 net_buf_simple_add_u8(&rsp, srv.scan.max_devs);
160 net_buf_simple_add_u8(&rsp, timeout);
161
162 bt_mesh_model_send(srv.mod, ctx, &rsp, NULL, NULL);
163 }
164
link_status_send(struct bt_mesh_msg_ctx * ctx,enum bt_mesh_rpr_status status)165 static void link_status_send(struct bt_mesh_msg_ctx *ctx,
166 enum bt_mesh_rpr_status status)
167 {
168 BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_LINK_STATUS, 2);
169 bt_mesh_model_msg_init(&buf, RPR_OP_LINK_STATUS);
170 net_buf_simple_add_u8(&buf, status);
171 net_buf_simple_add_u8(&buf, srv.link.state);
172
173 bt_mesh_model_send(srv.mod, ctx, &buf, NULL, NULL);
174 }
175
link_report_send(void)176 static void link_report_send(void)
177 {
178 struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.link.cli, true);
179
180 BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_LINK_REPORT, 3);
181 bt_mesh_model_msg_init(&buf, RPR_OP_LINK_REPORT);
182 net_buf_simple_add_u8(&buf, srv.link.status);
183 net_buf_simple_add_u8(&buf, srv.link.state);
184 if (srv.link.status == BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER ||
185 srv.link.status == BT_MESH_RPR_ERR_LINK_CLOSED_BY_DEVICE) {
186 net_buf_simple_add_u8(&buf, srv.link.close_reason);
187 }
188
189 LOG_DBG("%u %u", srv.link.status, srv.link.state);
190
191 bt_mesh_model_send(srv.mod, &ctx, &buf, NULL, NULL);
192 }
193
scan_report_schedule(void)194 static void scan_report_schedule(void)
195 {
196 uint32_t delay = 0;
197
198 if (k_work_delayable_remaining_get(&srv.scan.report) ||
199 atomic_test_bit(srv.flags, SCAN_REPORT_PENDING)) {
200 return;
201 }
202
203 (void)bt_rand(&delay, sizeof(uint32_t));
204 delay = (delay % 480) + 20;
205
206 k_work_reschedule(&srv.scan.report, K_MSEC(delay));
207 }
208
scan_report_sent(int err,void * cb_data)209 static void scan_report_sent(int err, void *cb_data)
210 {
211 atomic_clear_bit(srv.flags, SCAN_REPORT_PENDING);
212 k_work_reschedule(&srv.scan.report, K_NO_WAIT);
213 }
214
215 static const struct bt_mesh_send_cb report_cb = {
216 .end = scan_report_sent,
217 };
218
scan_report_send(void)219 static void scan_report_send(void)
220 {
221 struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.scan.cli, true);
222 int i, err;
223
224 if (atomic_test_bit(srv.flags, SCAN_REPORT_PENDING)) {
225 return;
226 }
227
228 for (i = 0; i < srv.scan.max_devs; ++i) {
229 struct bt_mesh_rpr_unprov *dev = &srv.scan.devs[i];
230
231 if (!(dev->flags & BT_MESH_RPR_UNPROV_FOUND) ||
232 (dev->flags & BT_MESH_RPR_UNPROV_REPORTED)) {
233 continue;
234 }
235
236 BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_SCAN_REPORT, 23);
237 bt_mesh_model_msg_init(&buf, RPR_OP_SCAN_REPORT);
238 net_buf_simple_add_u8(&buf, dev->rssi);
239 net_buf_simple_add_mem(&buf, dev->uuid, 16);
240 net_buf_simple_add_le16(&buf, dev->oob);
241 if (dev->flags & BT_MESH_RPR_UNPROV_HASH) {
242 net_buf_simple_add_mem(&buf, &dev->hash, 4);
243 }
244
245 atomic_set_bit(srv.flags, SCAN_REPORT_PENDING);
246
247 err = bt_mesh_model_send(srv.mod, &ctx, &buf, &report_cb, NULL);
248 if (err) {
249 atomic_clear_bit(srv.flags, SCAN_REPORT_PENDING);
250 LOG_DBG("tx failed: %d", err);
251 break;
252 }
253
254 LOG_DBG("Reported unprov #%u", i);
255 dev->flags |= BT_MESH_RPR_UNPROV_REPORTED;
256 break;
257 }
258 }
259
scan_ext_report_send(void)260 static void scan_ext_report_send(void)
261 {
262 struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.scan.cli, true);
263 int err;
264
265 BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_EXTENDED_SCAN_REPORT,
266 19 + CONFIG_BT_MESH_RPR_SRV_AD_DATA_MAX);
267 bt_mesh_model_msg_init(&buf, RPR_OP_EXTENDED_SCAN_REPORT);
268 net_buf_simple_add_u8(&buf, BT_MESH_RPR_SUCCESS);
269 net_buf_simple_add_mem(&buf, srv.scan.dev->uuid, 16);
270
271 if (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_FOUND) {
272 net_buf_simple_add_le16(&buf, srv.scan.dev->oob);
273 } else {
274 LOG_DBG("not found");
275 goto send;
276 }
277
278 if (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_EXT_ADV_RXD) {
279 net_buf_simple_add_mem(&buf, srv.scan.adv_data->data,
280 srv.scan.adv_data->len);
281 LOG_DBG("adv data: %s",
282 bt_hex(srv.scan.adv_data->data, srv.scan.adv_data->len));
283 }
284
285 srv.scan.dev->flags &= ~BT_MESH_RPR_UNPROV_EXT_ADV_RXD;
286 send:
287 err = bt_mesh_model_send(srv.mod, &ctx, &buf, NULL, NULL);
288 if (!err) {
289 srv.scan.dev->flags |= BT_MESH_RPR_UNPROV_REPORTED;
290 }
291 }
292
scan_stop(void)293 static void scan_stop(void)
294 {
295 LOG_DBG("");
296
297 k_work_cancel_delayable(&srv.scan.report);
298 k_work_cancel_delayable(&srv.scan.timeout);
299 srv.scan.state = BT_MESH_RPR_SCAN_IDLE;
300 cli_scan_clear();
301 atomic_clear_bit(srv.flags, SCANNING);
302 }
303
scan_report_timeout(struct k_work * work)304 static void scan_report_timeout(struct k_work *work)
305 {
306 scan_report_send();
307 }
308
scan_ext_stop(uint32_t remaining_time)309 static void scan_ext_stop(uint32_t remaining_time)
310 {
311 atomic_clear_bit(srv.flags, URI_MATCHED);
312 atomic_clear_bit(srv.flags, URI_REQUESTED);
313
314 if ((remaining_time + srv.scan.additional_time) &&
315 srv.scan.state != BT_MESH_RPR_SCAN_IDLE) {
316 k_work_reschedule(
317 &srv.scan.timeout,
318 K_MSEC(remaining_time + srv.scan.additional_time));
319 } else if (srv.scan.state == BT_MESH_RPR_SCAN_MULTI) {
320 /* Extended scan might have finished early */
321 scan_ext_report_send();
322 } else if (srv.scan.state != BT_MESH_RPR_SCAN_IDLE) {
323 scan_report_send();
324 scan_stop();
325 } else {
326 atomic_clear_bit(srv.flags, SCANNING);
327 }
328
329 if (!(srv.scan.dev->flags & BT_MESH_RPR_UNPROV_REPORTED)) {
330 scan_ext_report_send();
331 }
332
333 bt_mesh_scan_active_set(false);
334 srv.scan.dev = NULL;
335 }
336
337 static void adv_handle_ext_scan(const struct bt_le_scan_recv_info *info,
338 struct net_buf_simple *buf);
339
scan_timeout(struct k_work * work)340 static void scan_timeout(struct k_work *work)
341 {
342 LOG_DBG("%s", (srv.scan.dev ? "Extended scanning" : "Normal scanning"));
343
344 if (srv.scan.dev) {
345 scan_ext_stop(0);
346 } else {
347 scan_report_send();
348 scan_stop();
349 }
350 }
351
link_close(enum bt_mesh_rpr_status status,enum prov_bearer_link_status reason)352 static void link_close(enum bt_mesh_rpr_status status,
353 enum prov_bearer_link_status reason)
354 {
355 srv.link.status = status;
356 srv.link.close_reason = reason;
357 srv.link.state = BT_MESH_RPR_LINK_CLOSING;
358
359 LOG_DBG("status: %u reason: %u", status, reason);
360
361 if (atomic_test_and_clear_bit(srv.flags, NODE_REFRESH)) {
362 /* Link closing is an atomic operation: */
363 srv.link.state = BT_MESH_RPR_LINK_IDLE;
364 link_report_send();
365 srv.refresh.cb->link_closed(&pb_remote_srv, srv.refresh.cb_data,
366 srv.link.close_reason);
367
368 cli_link_clear();
369 } else {
370 bt_mesh_pb_adv.link_close(reason);
371 }
372 }
373
outbound_pdu_report_send(void)374 static void outbound_pdu_report_send(void)
375 {
376 struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.link.cli, true);
377
378 BT_MESH_MODEL_BUF_DEFINE(buf, RPR_OP_PDU_OUTBOUND_REPORT, 1);
379 bt_mesh_model_msg_init(&buf, RPR_OP_PDU_OUTBOUND_REPORT);
380 net_buf_simple_add_u8(&buf, srv.link.tx_pdu);
381
382 LOG_DBG("%u", srv.link.tx_pdu);
383
384 bt_mesh_model_send(srv.mod, &ctx, &buf, NULL, NULL);
385 }
386
pdu_send_complete(int err,void * cb_data)387 static void pdu_send_complete(int err, void *cb_data)
388 {
389 if (err) {
390 link_close(BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU,
391 PROV_BEARER_LINK_STATUS_FAIL);
392 } else if (srv.link.state == BT_MESH_RPR_LINK_SENDING) {
393 srv.link.state = BT_MESH_RPR_LINK_ACTIVE;
394 srv.link.tx_pdu++;
395 outbound_pdu_report_send();
396 }
397 }
398
inbound_pdu_send(struct net_buf_simple * buf,const struct bt_mesh_send_cb * cb)399 static int inbound_pdu_send(struct net_buf_simple *buf,
400 const struct bt_mesh_send_cb *cb)
401 {
402 struct bt_mesh_msg_ctx ctx = LINK_CTX(&srv.link.cli, true);
403
404 BT_MESH_MODEL_BUF_DEFINE(msg, RPR_OP_PDU_REPORT, 66);
405 bt_mesh_model_msg_init(&msg, RPR_OP_PDU_REPORT);
406 net_buf_simple_add_u8(&msg, srv.link.rx_pdu);
407 net_buf_simple_add_mem(&msg, buf->data, buf->len);
408
409 return bt_mesh_model_send(srv.mod, &ctx, &msg, cb, NULL);
410 }
411
subnet_evt_handler(struct bt_mesh_subnet * subnet,enum bt_mesh_key_evt evt)412 static void subnet_evt_handler(struct bt_mesh_subnet *subnet,
413 enum bt_mesh_key_evt evt)
414 {
415 if (!srv.mod || evt != BT_MESH_KEY_DELETED) {
416 return;
417 }
418
419 LOG_DBG("Subnet deleted");
420
421 if (srv.link.state != BT_MESH_RPR_LINK_IDLE &&
422 subnet->net_idx == srv.link.cli.net_idx) {
423 link_close(BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER,
424 PROV_BEARER_LINK_STATUS_FAIL);
425 /* Skip the link closing stage, as specified in the Bluetooth
426 * MshPRTv1.1: 4.4.5.4.
427 */
428 srv.link.state = BT_MESH_RPR_LINK_IDLE;
429 } else if (atomic_test_bit(srv.flags, SCANNING) &&
430 subnet->net_idx == srv.scan.cli.net_idx) {
431 scan_stop();
432 }
433 }
434
435 BT_MESH_SUBNET_CB_DEFINE(rpr_srv) = {
436 .evt_handler = subnet_evt_handler
437 };
438
439 /*******************************************************************************
440 * Prov bearer interface
441 ******************************************************************************/
pb_link_opened(const struct prov_bearer * bearer,void * cb_data)442 static void pb_link_opened(const struct prov_bearer *bearer, void *cb_data)
443 {
444 LOG_DBG("");
445
446 srv.link.state = BT_MESH_RPR_LINK_ACTIVE;
447 srv.link.status = BT_MESH_RPR_SUCCESS;
448 link_report_send();
449 }
450
link_report_send_and_clear(struct k_work * work)451 static void link_report_send_and_clear(struct k_work *work)
452 {
453 link_report_send();
454 cli_link_clear();
455 }
456
pb_link_closed(const struct prov_bearer * bearer,void * cb_data,enum prov_bearer_link_status reason)457 static void pb_link_closed(const struct prov_bearer *bearer, void *cb_data,
458 enum prov_bearer_link_status reason)
459 {
460 if (srv.link.state == BT_MESH_RPR_LINK_IDLE) {
461 return;
462 }
463
464 LOG_DBG("%u", reason);
465
466 if (srv.link.state == BT_MESH_RPR_LINK_OPENING) {
467 srv.link.status = BT_MESH_RPR_ERR_LINK_OPEN_FAILED;
468 } else if (reason == PROV_BEARER_LINK_STATUS_TIMEOUT) {
469 if (srv.link.state == BT_MESH_RPR_LINK_SENDING) {
470 srv.link.status =
471 BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU;
472 } else {
473 srv.link.status = BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER;
474 }
475 } else if (reason == PROV_BEARER_LINK_STATUS_FAIL &&
476 srv.link.status != BT_MESH_RPR_ERR_LINK_CLOSED_BY_CLIENT &&
477 srv.link.status != BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER) {
478 srv.link.status = BT_MESH_RPR_ERR_LINK_CLOSED_BY_DEVICE;
479 }
480
481 if (reason == PROV_BEARER_LINK_STATUS_SUCCESS) {
482 srv.link.close_reason = PROV_BEARER_LINK_STATUS_SUCCESS;
483 } else {
484 srv.link.close_reason = PROV_BEARER_LINK_STATUS_FAIL;
485 }
486
487 srv.link.state = BT_MESH_RPR_LINK_IDLE;
488 k_work_submit(&srv.link.report);
489 }
490
pb_error(const struct prov_bearer * bearer,void * cb_data,uint8_t err)491 static void pb_error(const struct prov_bearer *bearer, void *cb_data,
492 uint8_t err)
493 {
494 if (srv.link.state == BT_MESH_RPR_LINK_IDLE) {
495 return;
496 }
497
498 LOG_DBG("%d", err);
499 srv.link.close_reason = err;
500 srv.link.state = BT_MESH_RPR_LINK_IDLE;
501 srv.link.status = BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_RECEIVE_PDU;
502 link_report_send();
503 cli_link_clear();
504 }
505
pb_rx(const struct prov_bearer * bearer,void * cb_data,struct net_buf_simple * buf)506 static void pb_rx(const struct prov_bearer *bearer, void *cb_data,
507 struct net_buf_simple *buf)
508 {
509 int err;
510
511 if (srv.link.state != BT_MESH_RPR_LINK_ACTIVE &&
512 srv.link.state != BT_MESH_RPR_LINK_SENDING) {
513 return;
514 }
515
516 srv.link.rx_pdu++;
517 LOG_DBG("");
518
519 err = inbound_pdu_send(buf, NULL);
520 if (err) {
521 LOG_ERR("PDU send fail: %d", err);
522 link_close(BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU,
523 PROV_BEARER_LINK_STATUS_FAIL);
524 bt_mesh_pb_adv.link_close(PROV_ERR_RESOURCES);
525 }
526 }
527
528 static const struct prov_bearer_cb prov_bearer_cb = {
529 .link_opened = pb_link_opened,
530 .link_closed = pb_link_closed,
531 .error = pb_error,
532 .recv = pb_rx,
533 };
534
535 /*******************************************************************************
536 * Message handlers
537 ******************************************************************************/
538
handle_scan_caps_get(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)539 static int handle_scan_caps_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
540 struct net_buf_simple *buf)
541 {
542 BT_MESH_MODEL_BUF_DEFINE(rsp, RPR_OP_SCAN_CAPS_STATUS, 2);
543 bt_mesh_model_msg_init(&rsp, RPR_OP_SCAN_CAPS_STATUS);
544 net_buf_simple_add_u8(&rsp, CONFIG_BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX);
545 net_buf_simple_add_u8(&rsp, true);
546
547 bt_mesh_model_send(srv.mod, ctx, &rsp, NULL, NULL);
548
549 return 0;
550 }
551
handle_scan_get(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)552 static int handle_scan_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
553 struct net_buf_simple *buf)
554 {
555 scan_status_send(ctx, BT_MESH_RPR_SUCCESS);
556
557 return 0;
558 }
559
handle_scan_start(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)560 static int handle_scan_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
561 struct net_buf_simple *buf)
562 {
563 struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
564 enum bt_mesh_rpr_status status;
565 const uint8_t *uuid = NULL;
566 uint8_t max_devs;
567 uint8_t timeout;
568 int i;
569
570 max_devs = net_buf_simple_pull_u8(buf);
571 timeout = net_buf_simple_pull_u8(buf);
572 if (!timeout) {
573 return -EINVAL;
574 }
575
576 if (buf->len == 16) {
577 uuid = net_buf_simple_pull_mem(buf, 16);
578 } else if (buf->len) {
579 return -EINVAL;
580 }
581
582 LOG_DBG("max %u devs, %u s %s", max_devs, timeout,
583 uuid ? bt_hex(uuid, 16) : "");
584
585 if (max_devs > CONFIG_BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX) {
586 status = BT_MESH_RPR_ERR_SCANNING_CANNOT_START;
587 goto rsp;
588 }
589
590 if (srv.scan.state != BT_MESH_RPR_SCAN_IDLE &&
591 !rpr_node_equal(&cli, &srv.scan.cli)) {
592 status = BT_MESH_RPR_ERR_INVALID_STATE;
593 goto rsp;
594 }
595
596 for (i = 0; i < ARRAY_SIZE(srv.scan.devs); ++i) {
597 srv.scan.devs[i].flags = 0;
598 }
599
600 if (uuid) {
601 srv.scan.state = BT_MESH_RPR_SCAN_SINGLE;
602
603 srv.scan.devs[0].flags = BT_MESH_RPR_UNPROV_ACTIVE;
604 memcpy(srv.scan.devs[0].uuid, uuid, 16);
605 } else {
606 srv.scan.state = BT_MESH_RPR_SCAN_MULTI;
607 }
608
609 srv.scan.max_devs =
610 (max_devs ? max_devs :
611 CONFIG_BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX);
612 srv.scan.cli = cli;
613 status = BT_MESH_RPR_SUCCESS;
614
615 atomic_set_bit(srv.flags, SCANNING);
616 k_work_reschedule(&srv.scan.timeout, K_SECONDS(timeout));
617
618 rsp:
619 scan_status_send(ctx, status);
620
621 return 0;
622 }
623
handle_extended_scan_start(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)624 static int handle_extended_scan_start(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
625 struct net_buf_simple *buf)
626 {
627 BT_MESH_MODEL_BUF_DEFINE(rsp, RPR_OP_EXTENDED_SCAN_REPORT,
628 19 + CONFIG_BT_MESH_RPR_SRV_AD_DATA_MAX);
629 struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
630 enum bt_mesh_rpr_status status;
631 const uint8_t *uuid;
632 uint8_t *ad = NULL;
633 uint8_t ad_count;
634 uint8_t timeout;
635 int i;
636
637 /* According to MshPRTv1.1: 4.4.5.5.1.7, scan reports shall be
638 * sent as segmented messages.
639 */
640 ctx->send_rel = true;
641
642 ad_count = net_buf_simple_pull_u8(buf);
643 if (buf->len < ad_count || ad_count == 0 || ad_count > 0x10) {
644 /* Prohibited */
645 return -EINVAL;
646 }
647
648 ad = net_buf_simple_pull_mem(buf, ad_count);
649 for (i = 0; i < ad_count; ++i) {
650 if (ad[i] == BT_DATA_NAME_SHORTENED ||
651 ad[i] == BT_DATA_UUID16_SOME ||
652 ad[i] == BT_DATA_UUID32_SOME ||
653 ad[i] == BT_DATA_UUID128_SOME) {
654 return -EINVAL;
655 }
656
657 for (int j = 0; j < i; j++) {
658 if (ad[i] == ad[j]) {
659 /* Duplicate entry */
660 return -EINVAL;
661 }
662 }
663 }
664
665 ad_count = MIN(ad_count, CONFIG_BT_MESH_RPR_AD_TYPES_MAX);
666
667 if (!buf->len) {
668 const struct bt_mesh_prov *prov = bt_mesh_prov_get();
669
670 LOG_DBG("Self scan");
671
672 /* Want our local info. Could also include additional adv data,
673 * but there's no functionality for this in the mesh stack at
674 * the moment, so we'll only include the URI (if requested)
675 */
676 bt_mesh_model_msg_init(&rsp, RPR_OP_EXTENDED_SCAN_REPORT);
677
678 net_buf_simple_add_u8(&rsp, BT_MESH_RPR_SUCCESS);
679 net_buf_simple_add_mem(&rsp, prov->uuid, 16);
680 net_buf_simple_add_le16(&rsp, prov->oob_info);
681
682 if (prov->uri && get_ad_type(ad, ad_count, BT_DATA_URI)) {
683 uint8_t uri_len = strlen(prov->uri);
684
685 if (uri_len < CONFIG_BT_MESH_RPR_SRV_AD_DATA_MAX - 2) {
686 net_buf_simple_add_u8(&rsp, uri_len + 1);
687 net_buf_simple_add_u8(&rsp, BT_DATA_URI);
688 net_buf_simple_add_mem(&rsp, prov->uri,
689 uri_len);
690 LOG_DBG("URI added: %s", prov->uri);
691 } else {
692 LOG_WRN("URI data won't fit in scan report");
693 }
694 }
695
696 bt_mesh_model_send(mod, ctx, &rsp, NULL, NULL);
697 return 0;
698 }
699
700 if (buf->len != 17) {
701 return -EINVAL;
702 }
703
704 uuid = net_buf_simple_pull_mem(buf, 16);
705 timeout = net_buf_simple_pull_u8(buf);
706
707 if (IS_ENABLED(CONFIG_BT_MESH_MODEL_LOG_LEVEL_DBG)) {
708 struct bt_uuid_128 uuid_repr = { .uuid = { BT_UUID_TYPE_128 } };
709
710 memcpy(uuid_repr.val, uuid, 16);
711 LOG_DBG("%s AD types: %s", bt_uuid_str(&uuid_repr.uuid),
712 bt_hex(ad, ad_count));
713 }
714
715 if (timeout < BT_MESH_RPR_EXT_SCAN_TIME_MIN ||
716 timeout > BT_MESH_RPR_EXT_SCAN_TIME_MAX) {
717 LOG_ERR("Invalid extended scan timeout %u", timeout);
718 return -EINVAL;
719 }
720
721 if (srv.link.state != BT_MESH_RPR_LINK_IDLE) {
722 status = BT_MESH_RPR_ERR_LIMITED_RESOURCES;
723 goto rsp;
724 }
725
726 if (srv.scan.dev && (memcmp(srv.scan.dev->uuid, uuid, 16) ||
727 !rpr_node_equal(&srv.scan.cli, &cli))) {
728 LOG_WRN("Extended scan fail: Busy");
729 status = BT_MESH_RPR_ERR_LIMITED_RESOURCES;
730 goto rsp;
731 }
732
733 if (srv.scan.state == BT_MESH_RPR_SCAN_IDLE) {
734 srv.scan.max_devs = 1;
735 srv.scan.devs[0].flags = 0;
736 }
737
738 srv.scan.dev = unprov_get(uuid);
739 if (!srv.scan.dev) {
740 srv.scan.dev = unprov_get(NULL);
741 if (!srv.scan.dev) {
742 LOG_WRN("Extended scan fail: No memory");
743 status = BT_MESH_RPR_ERR_LIMITED_RESOURCES;
744 goto rsp;
745 }
746
747 memcpy(srv.scan.dev->uuid, uuid, 16);
748 srv.scan.dev->oob = 0;
749 srv.scan.dev->flags = 0;
750 }
751
752 memcpy(srv.scan.ad, ad, ad_count);
753 srv.scan.ad_count = ad_count;
754 net_buf_simple_reset(srv.scan.adv_data);
755
756 atomic_set_bit(srv.flags, SCANNING);
757 atomic_clear_bit(srv.flags, SCAN_EXT_HAS_ADDR);
758 srv.scan.dev->flags &= ~BT_MESH_RPR_UNPROV_REPORTED;
759 srv.scan.dev->flags |= BT_MESH_RPR_UNPROV_ACTIVE | BT_MESH_RPR_UNPROV_EXT;
760
761 if (srv.scan.state == BT_MESH_RPR_SCAN_IDLE) {
762 srv.scan.additional_time = 0;
763 srv.scan.cli = cli;
764 } else if (k_ticks_to_ms_floor32(
765 k_work_delayable_remaining_get(&srv.scan.timeout)) <
766 (timeout * MSEC_PER_SEC)) {
767 srv.scan.additional_time = 0;
768 } else {
769 srv.scan.additional_time =
770 k_ticks_to_ms_floor32(k_work_delayable_remaining_get(&srv.scan.timeout)) -
771 (timeout * MSEC_PER_SEC);
772 }
773
774 bt_mesh_scan_active_set(true);
775 k_work_reschedule(&srv.scan.timeout, K_SECONDS(timeout));
776 return 0;
777
778 rsp:
779 bt_mesh_model_msg_init(&rsp, RPR_OP_EXTENDED_SCAN_REPORT);
780 net_buf_simple_add_u8(&rsp, status);
781 net_buf_simple_add_mem(&rsp, uuid, 16);
782 bt_mesh_model_send(mod, ctx, &rsp, NULL, NULL);
783
784 return 0;
785 }
786
handle_scan_stop(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)787 static int handle_scan_stop(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
788 struct net_buf_simple *buf)
789 {
790 if (atomic_test_bit(srv.flags, SCANNING)) {
791 scan_report_send();
792 scan_stop();
793 }
794
795 scan_status_send(ctx, BT_MESH_RPR_SUCCESS);
796
797 return 0;
798 }
799
handle_link_get(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)800 static int handle_link_get(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
801 struct net_buf_simple *buf)
802 {
803 LOG_DBG("");
804
805 link_status_send(ctx, BT_MESH_RPR_SUCCESS);
806
807 return 0;
808 }
809
handle_link_open(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)810 static int handle_link_open(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
811 struct net_buf_simple *buf)
812 {
813 bool is_refresh_procedure = (buf->len == 1);
814 struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
815 int8_t timeout = LINK_OPEN_TIMEOUT_DEFAULT;
816 enum bt_mesh_rpr_status status;
817 const uint8_t *uuid;
818 uint8_t refresh;
819 int err;
820
821 if (buf->len != 1 && buf->len != 16 && buf->len != 17) {
822 return -EINVAL;
823 }
824
825 if (srv.link.state == BT_MESH_RPR_LINK_CLOSING ||
826 srv.link.state == BT_MESH_RPR_LINK_SENDING) {
827 status = BT_MESH_RPR_ERR_INVALID_STATE;
828 LOG_ERR("Invalid state: %u", srv.link.state);
829 goto rsp;
830 }
831
832 if (srv.link.state == BT_MESH_RPR_LINK_OPENING ||
833 srv.link.state == BT_MESH_RPR_LINK_ACTIVE) {
834
835 if (!rpr_node_equal(&cli, &srv.link.cli)) {
836 status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
837 goto rsp;
838 }
839
840 if (is_refresh_procedure) {
841 refresh = net_buf_simple_pull_u8(buf);
842 if (!atomic_test_bit(srv.flags, NODE_REFRESH) ||
843 srv.refresh.procedure != refresh) {
844 status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
845 } else {
846 status = BT_MESH_RPR_SUCCESS;
847 }
848
849 goto rsp;
850 }
851
852 if (atomic_test_bit(srv.flags, NODE_REFRESH)) {
853 status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
854 goto rsp;
855 }
856
857 uuid = net_buf_simple_pull_mem(buf, 16);
858
859 if (memcmp(uuid, srv.link.dev->uuid, 16)) {
860 status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
861 } else {
862 status = BT_MESH_RPR_SUCCESS;
863 }
864
865 goto rsp;
866 }
867
868 /* Link state is IDLE */
869
870 if (is_refresh_procedure) {
871 refresh = net_buf_simple_pull_u8(buf);
872 if (refresh > BT_MESH_RPR_NODE_REFRESH_COMPOSITION) {
873 LOG_ERR("Invalid refresh: %u", refresh);
874 return -EINVAL;
875 }
876
877 if (refresh == BT_MESH_RPR_NODE_REFRESH_COMPOSITION &&
878 !atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY)) {
879 LOG_WRN("Composition data page 128 is equal to page 0");
880 status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
881 goto rsp;
882 }
883
884 LOG_DBG("Node Refresh: %u", refresh);
885
886 atomic_set_bit(srv.flags, NODE_REFRESH);
887 srv.refresh.procedure = refresh;
888 srv.link.cli = cli;
889 srv.link.rx_pdu = 0;
890 srv.link.tx_pdu = 0;
891 srv.link.state = BT_MESH_RPR_LINK_ACTIVE;
892 srv.link.status = BT_MESH_RPR_SUCCESS;
893 srv.refresh.cb->link_opened(&pb_remote_srv, &srv);
894 status = BT_MESH_RPR_SUCCESS;
895 link_report_send();
896 goto rsp;
897 }
898
899 uuid = net_buf_simple_pull_mem(buf, 16);
900 if (buf->len) {
901 timeout = net_buf_simple_pull_u8(buf);
902 if (!timeout || timeout > 0x3c) {
903 LOG_ERR("Invalid timeout: %u", timeout);
904 return -EINVAL;
905 }
906 }
907
908 LOG_DBG("0x%04x: %s", cli.addr, bt_hex(uuid, 16));
909
910 /* Attempt to reuse the scanned unprovisioned device, to preserve as
911 * much information as possible, but fall back to hijacking the first
912 * slot if none was found.
913 */
914 srv.link.dev = unprov_get(uuid);
915 if (!srv.link.dev) {
916 srv.link.dev = &srv.scan.devs[0];
917 memcpy(srv.link.dev->uuid, uuid, 16);
918 srv.link.dev->flags = 0;
919 }
920
921 err = bt_mesh_pb_adv.link_open(uuid, timeout, &prov_bearer_cb, &srv);
922 if (err) {
923 status = BT_MESH_RPR_ERR_LINK_CANNOT_OPEN;
924 goto rsp;
925 }
926
927 srv.link.cli = cli;
928 srv.link.rx_pdu = 0;
929 srv.link.tx_pdu = 0;
930 srv.link.state = BT_MESH_RPR_LINK_OPENING;
931 srv.link.status = BT_MESH_RPR_SUCCESS;
932 srv.link.dev->flags |= BT_MESH_RPR_UNPROV_HAS_LINK;
933 status = BT_MESH_RPR_SUCCESS;
934
935 rsp:
936 link_status_send(ctx, status);
937
938 return 0;
939 }
940
handle_link_close(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)941 static int handle_link_close(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
942 struct net_buf_simple *buf)
943 {
944 struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
945 enum prov_bearer_link_status reason;
946
947 reason = net_buf_simple_pull_u8(buf);
948 if (reason != PROV_BEARER_LINK_STATUS_SUCCESS &&
949 reason != PROV_BEARER_LINK_STATUS_FAIL) {
950 return -EINVAL;
951 }
952
953 LOG_DBG("");
954
955 if (srv.link.state == BT_MESH_RPR_LINK_IDLE ||
956 srv.link.state == BT_MESH_RPR_LINK_CLOSING) {
957 link_status_send(ctx, BT_MESH_RPR_SUCCESS);
958 return 0;
959 }
960
961 if (!rpr_node_equal(&cli, &srv.link.cli)) {
962 link_status_send(ctx, BT_MESH_RPR_ERR_INVALID_STATE);
963 return 0;
964 }
965
966 srv.link.state = BT_MESH_RPR_LINK_CLOSING;
967
968 /* Note: The response status isn't the same as the link status state,
969 * which will be used in the link report when the link is fully closed.
970 */
971
972 /* Disable randomization for the Remote Provisioning Link Status message to avoid reordering
973 * of it with the Remote Provisioning Link Report message that shall be sent in a sequence
974 * when closing an active link (see section 4.4.5.5.3.3 of MshPRTv1.1).
975 */
976 ctx->rnd_delay = false;
977
978 link_status_send(ctx, BT_MESH_RPR_SUCCESS);
979 link_close(BT_MESH_RPR_ERR_LINK_CLOSED_BY_CLIENT, reason);
980
981 return 0;
982 }
983
handle_pdu_send(const struct bt_mesh_model * mod,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)984 static int handle_pdu_send(const struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
985 struct net_buf_simple *buf)
986 {
987 struct bt_mesh_rpr_node cli = RPR_NODE(ctx);
988 uint8_t pdu_num;
989 int err;
990
991 pdu_num = net_buf_simple_pull_u8(buf);
992
993 if (srv.link.state != BT_MESH_RPR_LINK_ACTIVE) {
994 LOG_WRN("Sending PDU while busy (state %u)", srv.link.state);
995 return 0;
996 }
997
998 if (!rpr_node_equal(&cli, &srv.link.cli)) {
999 LOG_WRN("Unknown client 0x%04x", cli.addr);
1000 return 0;
1001 }
1002
1003 if (pdu_num != srv.link.tx_pdu + 1) {
1004 LOG_WRN("Invalid pdu number: %u, expected %u", pdu_num,
1005 srv.link.tx_pdu + 1);
1006 outbound_pdu_report_send();
1007 return 0;
1008 }
1009
1010 LOG_DBG("0x%02x", buf->data[0]);
1011
1012 if (atomic_test_bit(srv.flags, NODE_REFRESH)) {
1013 srv.link.tx_pdu++;
1014 outbound_pdu_report_send();
1015 srv.refresh.cb->recv(&pb_remote_srv, srv.refresh.cb_data, buf);
1016 } else {
1017 srv.link.state = BT_MESH_RPR_LINK_SENDING;
1018 err = bt_mesh_pb_adv.send(buf, pdu_send_complete, &srv);
1019 if (err) {
1020 link_close(
1021 BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU,
1022 PROV_BEARER_LINK_STATUS_FAIL);
1023 }
1024 }
1025
1026 return 0;
1027 }
1028
1029 const struct bt_mesh_model_op _bt_mesh_rpr_srv_op[] = {
1030 { RPR_OP_SCAN_CAPS_GET, BT_MESH_LEN_EXACT(0), handle_scan_caps_get },
1031 { RPR_OP_SCAN_GET, BT_MESH_LEN_EXACT(0), handle_scan_get },
1032 { RPR_OP_SCAN_START, BT_MESH_LEN_MIN(2), handle_scan_start },
1033 { RPR_OP_EXTENDED_SCAN_START, BT_MESH_LEN_MIN(1), handle_extended_scan_start },
1034 { RPR_OP_SCAN_STOP, BT_MESH_LEN_EXACT(0), handle_scan_stop },
1035 { RPR_OP_LINK_GET, BT_MESH_LEN_EXACT(0), handle_link_get },
1036 { RPR_OP_LINK_OPEN, BT_MESH_LEN_MIN(1), handle_link_open },
1037 { RPR_OP_LINK_CLOSE, BT_MESH_LEN_EXACT(1), handle_link_close },
1038 { RPR_OP_PDU_SEND, BT_MESH_LEN_MIN(1), handle_pdu_send },
1039 BT_MESH_MODEL_OP_END,
1040 };
1041
1042 static struct bt_mesh_rpr_unprov *
adv_handle_beacon(const struct bt_le_scan_recv_info * info,struct bt_data * ad)1043 adv_handle_beacon(const struct bt_le_scan_recv_info *info,
1044 struct bt_data *ad)
1045 {
1046 struct bt_uuid_128 uuid_repr = { .uuid = { BT_UUID_TYPE_128 } };
1047 struct bt_mesh_rpr_unprov *dev = NULL;
1048 const uint8_t *uuid;
1049
1050 if (ad->data[0] != 0x00 || (ad->data_len != 19 && ad->data_len != 23)) {
1051 return NULL;
1052 }
1053
1054 uuid = &ad->data[1];
1055
1056 dev = unprov_get(uuid);
1057 if (!dev) {
1058 if (srv.scan.state != BT_MESH_RPR_SCAN_MULTI) {
1059 return NULL;
1060 }
1061
1062 dev = unprov_get(NULL);
1063 if (!dev) {
1064 return NULL;
1065 }
1066
1067 memcpy(dev->uuid, uuid, 16);
1068 dev->flags = BT_MESH_RPR_UNPROV_ACTIVE;
1069 } else if (dev->flags & BT_MESH_RPR_UNPROV_FOUND) {
1070 return dev;
1071 }
1072
1073 dev->oob = sys_get_be16(&ad->data[17]);
1074 dev->rssi = info->rssi;
1075
1076 if (ad->data_len == 23) {
1077 memcpy(&dev->hash, &ad->data[19], 4);
1078 dev->flags |= BT_MESH_RPR_UNPROV_HASH;
1079 }
1080
1081 dev->flags |= BT_MESH_RPR_UNPROV_FOUND;
1082 memcpy(uuid_repr.val, uuid, 16);
1083
1084 LOG_DBG("Unprov #%u: %s OOB: 0x%04x %s", dev - &srv.scan.devs[0],
1085 bt_uuid_str(&uuid_repr.uuid), dev->oob,
1086 (dev->flags & BT_MESH_RPR_UNPROV_HASH) ? bt_hex(&dev->hash, 4) :
1087 "(no hash)");
1088
1089 if (dev != srv.scan.dev && !(dev->flags & BT_MESH_RPR_UNPROV_REPORTED)) {
1090 scan_report_schedule();
1091 }
1092
1093 return dev;
1094 }
1095
pull_ad_data(struct net_buf_simple * buf,struct bt_data * ad)1096 static bool pull_ad_data(struct net_buf_simple *buf, struct bt_data *ad)
1097 {
1098 uint8_t len;
1099
1100 if (!buf->len) {
1101 return false;
1102 }
1103
1104 len = net_buf_simple_pull_u8(buf);
1105 if (!len || len > buf->len) {
1106 return false;
1107 }
1108
1109 ad->type = net_buf_simple_pull_u8(buf);
1110 ad->data_len = len - sizeof(ad->type);
1111 ad->data = net_buf_simple_pull_mem(buf, ad->data_len);
1112 return true;
1113 }
1114
adv_handle_ext_scan(const struct bt_le_scan_recv_info * info,struct net_buf_simple * buf)1115 static void adv_handle_ext_scan(const struct bt_le_scan_recv_info *info,
1116 struct net_buf_simple *buf)
1117 {
1118 struct bt_mesh_rpr_unprov *dev = NULL;
1119 struct net_buf_simple_state initial;
1120 struct bt_data ad;
1121 bool uri_match = false;
1122 bool uri_present = false;
1123 bool is_beacon = false;
1124
1125 if (atomic_test_bit(srv.flags, SCAN_EXT_HAS_ADDR) &&
1126 !bt_addr_le_cmp(&srv.scan.addr, info->addr)) {
1127 dev = srv.scan.dev;
1128 }
1129
1130 /* Do AD data walk in two rounds: First to figure out which
1131 * unprovisioned device this is (if any), and the second to copy out
1132 * relevant AD data to the extended scan report.
1133 */
1134
1135 net_buf_simple_save(buf, &initial);
1136 while (pull_ad_data(buf, &ad)) {
1137 if (ad.type == BT_DATA_URI) {
1138 uri_present = true;
1139 }
1140
1141 if (ad.type == BT_DATA_MESH_BEACON && !dev) {
1142 dev = adv_handle_beacon(info, &ad);
1143 is_beacon = true;
1144 } else if (ad.type == BT_DATA_URI &&
1145 (srv.scan.dev->flags & BT_MESH_RPR_UNPROV_HASH)) {
1146 uint8_t hash[16];
1147
1148 if (bt_mesh_s1(ad.data, ad.data_len, hash) ||
1149 memcmp(hash, &srv.scan.dev->hash, 4)) {
1150 continue;
1151 }
1152
1153 LOG_DBG("Found matching URI");
1154 uri_match = true;
1155 dev = srv.scan.dev;
1156 srv.scan.dev->flags |= BT_MESH_RPR_UNPROV_EXT_ADV_RXD;
1157 }
1158 }
1159
1160 if (uri_match) {
1161 atomic_set_bit(srv.flags, URI_MATCHED);
1162 }
1163
1164 if (!dev) {
1165 return;
1166 }
1167
1168 /* Do not process advertisement if it was not identified by URI hash from beacon */
1169 if (!(dev->flags & BT_MESH_RPR_UNPROV_EXT_ADV_RXD)) {
1170 return;
1171 }
1172
1173 srv.scan.addr = *info->addr;
1174 atomic_set_bit(srv.flags, SCAN_EXT_HAS_ADDR);
1175
1176 if (IS_ENABLED(CONFIG_BT_MESH_MODEL_LOG_LEVEL_DBG)) {
1177 struct bt_uuid_128 uuid_repr = { .uuid = { BT_UUID_TYPE_128 } };
1178
1179 memcpy(uuid_repr.val, dev->uuid, 16);
1180 LOG_DBG("Is %s", bt_uuid_str(&uuid_repr.uuid));
1181 }
1182
1183 net_buf_simple_restore(buf, &initial);
1184
1185 /* The ADTypeFilter field of the Remote Provisioning Extended Scan Start message
1186 * contains only the URI AD Type, and the URI Hash is not available for the device
1187 * with the Device UUID that was requested in the Remote Provisioning Extended Scan
1188 * Start message.
1189 */
1190 if (srv.scan.ad_count == 1 &&
1191 get_ad_type(srv.scan.ad, 1, BT_DATA_URI) &&
1192 !uri_match) {
1193 goto complete;
1194 }
1195
1196 while (srv.scan.ad_count && pull_ad_data(buf, &ad)) {
1197 uint8_t *ad_entry;
1198
1199 ad_entry = get_ad_type(srv.scan.ad, srv.scan.ad_count, ad.type);
1200 if (!ad_entry || (ad.type == BT_DATA_URI && !uri_match)) {
1201 continue;
1202 }
1203
1204 LOG_DBG("AD type 0x%02x", ad.type);
1205
1206 if (ad.type == BT_DATA_URI) {
1207 atomic_set_bit(srv.flags, URI_REQUESTED);
1208 }
1209
1210 if (ad.data_len + 2 >
1211 net_buf_simple_tailroom(srv.scan.adv_data)) {
1212 LOG_WRN("Can't fit AD 0x%02x in scan report", ad.type);
1213 continue;
1214 }
1215
1216 net_buf_simple_add_u8(srv.scan.adv_data, ad.data_len + 1);
1217 net_buf_simple_add_u8(srv.scan.adv_data, ad.type);
1218 net_buf_simple_add_mem(srv.scan.adv_data, ad.data, ad.data_len);
1219
1220 *ad_entry = srv.scan.ad[--srv.scan.ad_count];
1221 }
1222
1223 /* The Remote Provisioning Server collects AD structures corresponding to all
1224 * AD Types specified in the ADTypeFilter field of the Remote Provisioning Extended
1225 * Scan Start message. The timeout specified in the Timeout field of the Remote
1226 * Provisioning Extended Scan Start message expires.
1227 * OR
1228 * The ADTypeFilter field of the Remote Provisioning Extended Scan Start message
1229 * contains only the URI AD Type, and the Remote Provisioning Server has received
1230 * an advertising report or scan response with the URI corresponding to the URI Hash
1231 * of the device with the Device UUID that was requested in the Remote Provisioning
1232 * Extended Scan Start message.
1233 */
1234 if (!srv.scan.ad_count) {
1235 goto complete;
1236 }
1237
1238 /* The ADTypeFilter field of the Remote Provisioning Extended Scan Start message does
1239 * not contain the URI AD Type, and the Remote Provisioning Server receives and processes
1240 * the scan response data from the device with Device UUID requested in the Remote
1241 * Provisioning Extended Scan Start message.
1242 */
1243 if (!is_beacon && !uri_present &&
1244 info->adv_type == BT_GAP_ADV_TYPE_SCAN_RSP) {
1245 goto complete;
1246 }
1247
1248 /* The ADTypeFilter field of the Remote Provisioning Extended Scan Start message contains
1249 * the URI AD Type and at least one different AD Type in the ADTypeFilter field, and the
1250 * Remote Provisioning Server has received an advertising report or scan response with the
1251 * URI corresponding to the URI Hash of the device with the Device UUID that was requested
1252 * in the Remote Provisioning Extended Scan Start message, and the Remote Provisioning
1253 * Server received the scan response from the same device.
1254 * OR
1255 * The ADTypeFilter field of the Remote Provisioning Extended Scan Start message contains
1256 * the URI AD Type and at least one different AD Type in the ADTypeFilter field, and the
1257 * URI Hash is not available for the device with the Device UUID that was requested in the
1258 * Remote Provisioning Extended Scan Start message, and the Remote Provisioning Server
1259 * received the scan response from the same device.
1260 */
1261 if (atomic_get(srv.flags) & URI_REQUESTED &&
1262 (atomic_get(srv.flags) & URI_MATCHED ||
1263 (dev->flags & ~BT_MESH_RPR_UNPROV_HASH)) &&
1264 info->adv_type == BT_GAP_ADV_TYPE_SCAN_RSP) {
1265 goto complete;
1266 }
1267
1268 return;
1269 complete:
1270 srv.scan.additional_time = 0;
1271 if (srv.scan.state != BT_MESH_RPR_SCAN_MULTI) {
1272 k_work_cancel_delayable(&srv.scan.timeout);
1273 }
1274 scan_ext_stop(0);
1275 }
1276
adv_handle_scan(const struct bt_le_scan_recv_info * info,struct net_buf_simple * buf)1277 static void adv_handle_scan(const struct bt_le_scan_recv_info *info,
1278 struct net_buf_simple *buf)
1279 {
1280 struct bt_data ad;
1281
1282 if (info->adv_type != BT_HCI_ADV_NONCONN_IND) {
1283 return;
1284 }
1285
1286 while (pull_ad_data(buf, &ad)) {
1287 if (ad.type == BT_DATA_MESH_BEACON) {
1288 adv_handle_beacon(info, &ad);
1289 return;
1290 }
1291 }
1292 }
1293
scan_packet_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * buf)1294 static void scan_packet_recv(const struct bt_le_scan_recv_info *info,
1295 struct net_buf_simple *buf)
1296 {
1297 if (!atomic_test_bit(srv.flags, SCANNING)) {
1298 return;
1299 }
1300
1301 if (srv.scan.dev) {
1302 adv_handle_ext_scan(info, buf);
1303 } else {
1304 adv_handle_scan(info, buf);
1305 }
1306 }
1307
1308 static struct bt_le_scan_cb scan_cb = {
1309 .recv = scan_packet_recv,
1310 };
1311
rpr_srv_init(const struct bt_mesh_model * mod)1312 static int rpr_srv_init(const struct bt_mesh_model *mod)
1313 {
1314 if (mod->rt->elem_idx || srv.mod) {
1315 LOG_ERR("Remote provisioning server must be initialized "
1316 "on first element");
1317 return -EINVAL;
1318 }
1319
1320 srv.mod = mod;
1321
1322 net_buf_simple_init(srv.scan.adv_data, 0);
1323
1324 k_work_init_delayable(&srv.scan.timeout, scan_timeout);
1325 k_work_init_delayable(&srv.scan.report, scan_report_timeout);
1326 k_work_init(&srv.link.report, link_report_send_and_clear);
1327 bt_le_scan_cb_register(&scan_cb);
1328 mod->keys[0] = BT_MESH_KEY_DEV_LOCAL;
1329 mod->rt->flags |= BT_MESH_MOD_DEVKEY_ONLY;
1330
1331 return 0;
1332 }
1333
rpr_srv_reset(const struct bt_mesh_model * mod)1334 static void rpr_srv_reset(const struct bt_mesh_model *mod)
1335 {
1336 cli_link_clear();
1337 cli_scan_clear();
1338 srv.scan.state = BT_MESH_RPR_SCAN_IDLE;
1339 srv.link.state = BT_MESH_RPR_LINK_IDLE;
1340 k_work_cancel_delayable(&srv.scan.timeout);
1341 k_work_cancel_delayable(&srv.scan.report);
1342 net_buf_simple_init(srv.scan.adv_data, 0);
1343 atomic_clear(srv.flags);
1344 srv.link.dev = NULL;
1345 srv.scan.dev = NULL;
1346 }
1347
1348 const struct bt_mesh_model_cb _bt_mesh_rpr_srv_cb = {
1349 .init = rpr_srv_init,
1350 .reset = rpr_srv_reset,
1351 };
1352
node_refresh_link_accept(const struct prov_bearer_cb * cb,void * cb_data)1353 static int node_refresh_link_accept(const struct prov_bearer_cb *cb,
1354 void *cb_data)
1355 {
1356 srv.refresh.cb = cb;
1357 srv.refresh.cb_data = cb_data;
1358
1359 return 0;
1360 }
1361
node_refresh_tx_complete(int err,void * cb_data)1362 static void node_refresh_tx_complete(int err, void *cb_data)
1363 {
1364 if (err) {
1365 link_close(BT_MESH_RPR_ERR_LINK_CLOSED_AS_CANNOT_SEND_PDU,
1366 PROV_BEARER_LINK_STATUS_FAIL);
1367 return;
1368 }
1369
1370 if (srv.refresh.tx.cb) {
1371 srv.refresh.tx.cb(err, srv.refresh.tx.cb_data);
1372 }
1373 }
1374
node_refresh_buf_send(struct net_buf_simple * buf,prov_bearer_send_complete_t cb,void * cb_data)1375 static int node_refresh_buf_send(struct net_buf_simple *buf,
1376 prov_bearer_send_complete_t cb, void *cb_data)
1377 {
1378 static const struct bt_mesh_send_cb send_cb = {
1379 .end = node_refresh_tx_complete,
1380 };
1381 int err;
1382
1383 if (!atomic_test_bit(srv.flags, NODE_REFRESH)) {
1384 return -EBUSY;
1385 }
1386
1387 srv.refresh.tx.cb = cb;
1388 srv.refresh.tx.cb_data = cb_data;
1389 srv.link.rx_pdu++;
1390
1391 LOG_DBG("%u", srv.link.rx_pdu);
1392
1393 err = inbound_pdu_send(buf, &send_cb);
1394 if (err) {
1395 link_close(BT_MESH_RPR_ERR_LINK_CLOSED_BY_SERVER,
1396 PROV_BEARER_LINK_STATUS_FAIL);
1397 }
1398
1399 return err;
1400 }
1401
node_refresh_clear_tx(void)1402 static void node_refresh_clear_tx(void)
1403 {
1404 /* Nothing can be done */
1405 }
1406
1407 const struct prov_bearer pb_remote_srv = {
1408 .type = BT_MESH_PROV_REMOTE,
1409
1410 .link_accept = node_refresh_link_accept,
1411 .send = node_refresh_buf_send,
1412 .clear_tx = node_refresh_clear_tx,
1413 };
1414