1 /*
2 * Copyright (c) 2017 Intel Corporation
3 * Copyright (c) 2021 Lingao Meng
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/kernel.h>
9 #include <zephyr/sys/byteorder.h>
10 #include <zephyr/sys/iterable_sections.h>
11 #include <zephyr/net/buf.h>
12 #include <zephyr/bluetooth/bluetooth.h>
13 #include <zephyr/bluetooth/conn.h>
14 #include <zephyr/bluetooth/gatt.h>
15 #include <zephyr/bluetooth/mesh.h>
16 #include <zephyr/sys/util.h>
17
18 #include <zephyr/bluetooth/hci.h>
19
20 #include "common/bt_str.h"
21
22 #include "mesh.h"
23 #include "adv.h"
24 #include "net.h"
25 #include "rpl.h"
26 #include "transport.h"
27 #include "prov.h"
28 #include "beacon.h"
29 #include "foundation.h"
30 #include "access.h"
31 #include "proxy.h"
32 #include "proxy_msg.h"
33 #include "crypto.h"
34
35 #define LOG_LEVEL CONFIG_BT_MESH_PROXY_LOG_LEVEL
36 #include <zephyr/logging/log.h>
37 LOG_MODULE_REGISTER(bt_mesh_gatt);
38
39 #define PROXY_SVC_INIT_TIMEOUT K_MSEC(10)
40 #define PROXY_SVC_REG_ATTEMPTS 5
41
42 /* Interval to update random value in (10 minutes).
43 *
44 * Defined in the Bluetooth Mesh Specification v1.1, Section 7.2.2.2.4.
45 */
46 #define PROXY_RANDOM_UPDATE_INTERVAL (10 * 60 * MSEC_PER_SEC)
47
48 #if defined(CONFIG_BT_MESH_PROXY_USE_DEVICE_NAME)
49 #define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME
50 #else
51 #define ADV_OPT_USE_NAME 0
52 #endif
53
54 #define ADV_OPT_ADDR(private) (IS_ENABLED(CONFIG_BT_MESH_DEBUG_USE_ID_ADDR) ? \
55 BT_LE_ADV_OPT_USE_IDENTITY : (private) ? BT_LE_ADV_OPT_USE_NRPA : 0)
56
57 #define ADV_OPT_PROXY(private) \
58 (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_SCANNABLE | ADV_OPT_ADDR(private) | \
59 BT_LE_ADV_OPT_ONE_TIME | ADV_OPT_USE_NAME)
60
61 static void proxy_send_beacons(struct k_work *work);
62 static int proxy_send(struct bt_conn *conn,
63 const void *data, uint16_t len,
64 bt_gatt_complete_func_t end, void *user_data);
65
66 static struct bt_mesh_proxy_client {
67 struct bt_mesh_proxy_role *cli;
68 uint16_t filter[CONFIG_BT_MESH_PROXY_FILTER_SIZE];
69 enum __packed {
70 NONE,
71 ACCEPT,
72 REJECT,
73 } filter_type;
74 struct k_work send_beacons;
75 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
76 bool privacy;
77 #endif
78 } clients[CONFIG_BT_MAX_CONN] = {
79 [0 ... (CONFIG_BT_MAX_CONN - 1)] = {
80 .send_beacons = Z_WORK_INITIALIZER(proxy_send_beacons),
81 },
82 };
83
84 static bool service_registered;
85
find_client(struct bt_conn * conn)86 static struct bt_mesh_proxy_client *find_client(struct bt_conn *conn)
87 {
88 return &clients[bt_conn_index(conn)];
89 }
90
gatt_recv(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)91 static ssize_t gatt_recv(struct bt_conn *conn,
92 const struct bt_gatt_attr *attr, const void *buf,
93 uint16_t len, uint16_t offset, uint8_t flags)
94 {
95 const uint8_t *data = buf;
96
97 if (len < 1) {
98 LOG_WRN("Too small Proxy PDU");
99 return -EINVAL;
100 }
101
102 if (PDU_TYPE(data) == BT_MESH_PROXY_PROV) {
103 LOG_WRN("Proxy PDU type doesn't match GATT service");
104 return -EINVAL;
105 }
106
107 return bt_mesh_proxy_msg_recv(conn, buf, len);
108 }
109
110 /* Next subnet in queue to be advertised */
111 static struct bt_mesh_subnet *beacon_sub;
112
filter_set(struct bt_mesh_proxy_client * client,struct net_buf_simple * buf)113 static int filter_set(struct bt_mesh_proxy_client *client,
114 struct net_buf_simple *buf)
115 {
116 uint8_t type;
117
118 if (buf->len < 1) {
119 LOG_WRN("Too short Filter Set message");
120 return -EINVAL;
121 }
122
123 type = net_buf_simple_pull_u8(buf);
124 LOG_DBG("type 0x%02x", type);
125
126 switch (type) {
127 case 0x00:
128 (void)memset(client->filter, 0, sizeof(client->filter));
129 client->filter_type = ACCEPT;
130 break;
131 case 0x01:
132 (void)memset(client->filter, 0, sizeof(client->filter));
133 client->filter_type = REJECT;
134 break;
135 default:
136 LOG_WRN("Prohibited Filter Type 0x%02x", type);
137 return -EINVAL;
138 }
139
140 return 0;
141 }
142
filter_add(struct bt_mesh_proxy_client * client,uint16_t addr)143 static void filter_add(struct bt_mesh_proxy_client *client, uint16_t addr)
144 {
145 int i;
146
147 LOG_DBG("addr 0x%04x", addr);
148
149 if (addr == BT_MESH_ADDR_UNASSIGNED) {
150 return;
151 }
152
153 for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
154 if (client->filter[i] == addr) {
155 return;
156 }
157 }
158
159 for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
160 if (client->filter[i] == BT_MESH_ADDR_UNASSIGNED) {
161 client->filter[i] = addr;
162 return;
163 }
164 }
165 }
166
filter_remove(struct bt_mesh_proxy_client * client,uint16_t addr)167 static void filter_remove(struct bt_mesh_proxy_client *client, uint16_t addr)
168 {
169 int i;
170
171 LOG_DBG("addr 0x%04x", addr);
172
173 if (addr == BT_MESH_ADDR_UNASSIGNED) {
174 return;
175 }
176
177 for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
178 if (client->filter[i] == addr) {
179 client->filter[i] = BT_MESH_ADDR_UNASSIGNED;
180 return;
181 }
182 }
183 }
184
send_filter_status(struct bt_mesh_proxy_client * client,struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)185 static void send_filter_status(struct bt_mesh_proxy_client *client,
186 struct bt_mesh_net_rx *rx,
187 struct net_buf_simple *buf)
188 {
189 struct bt_mesh_net_tx tx = {
190 .sub = rx->sub,
191 .ctx = &rx->ctx,
192 .src = bt_mesh_primary_addr(),
193 };
194 uint16_t filter_size;
195 int i, err;
196
197 /* Configuration messages always have dst unassigned */
198 tx.ctx->addr = BT_MESH_ADDR_UNASSIGNED;
199
200 net_buf_simple_reset(buf);
201 net_buf_simple_reserve(buf, 10);
202
203 net_buf_simple_add_u8(buf, CFG_FILTER_STATUS);
204
205 if (client->filter_type == ACCEPT) {
206 net_buf_simple_add_u8(buf, 0x00);
207 } else {
208 net_buf_simple_add_u8(buf, 0x01);
209 }
210
211 for (filter_size = 0U, i = 0; i < ARRAY_SIZE(client->filter); i++) {
212 if (client->filter[i] != BT_MESH_ADDR_UNASSIGNED) {
213 filter_size++;
214 }
215 }
216
217 net_buf_simple_add_be16(buf, filter_size);
218
219 LOG_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));
220
221 err = bt_mesh_net_encode(&tx, buf, BT_MESH_NONCE_PROXY);
222 if (err) {
223 LOG_ERR("Encoding Proxy cfg message failed (err %d)", err);
224 return;
225 }
226
227 err = bt_mesh_proxy_msg_send(client->cli->conn, BT_MESH_PROXY_CONFIG,
228 buf, NULL, NULL);
229 if (err) {
230 LOG_ERR("Failed to send proxy cfg message (err %d)", err);
231 }
232 }
233
proxy_filter_recv(struct bt_conn * conn,struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)234 static void proxy_filter_recv(struct bt_conn *conn,
235 struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
236 {
237 struct bt_mesh_proxy_client *client;
238 uint8_t opcode;
239
240 client = find_client(conn);
241
242 opcode = net_buf_simple_pull_u8(buf);
243 switch (opcode) {
244 case CFG_FILTER_SET:
245 filter_set(client, buf);
246 send_filter_status(client, rx, buf);
247 break;
248 case CFG_FILTER_ADD:
249 while (buf->len >= 2) {
250 uint16_t addr;
251
252 addr = net_buf_simple_pull_be16(buf);
253 filter_add(client, addr);
254 }
255 send_filter_status(client, rx, buf);
256 break;
257 case CFG_FILTER_REMOVE:
258 while (buf->len >= 2) {
259 uint16_t addr;
260
261 addr = net_buf_simple_pull_be16(buf);
262 filter_remove(client, addr);
263 }
264 send_filter_status(client, rx, buf);
265 break;
266 default:
267 LOG_WRN("Unhandled configuration OpCode 0x%02x", opcode);
268 break;
269 }
270 }
271
proxy_cfg(struct bt_mesh_proxy_role * role)272 static void proxy_cfg(struct bt_mesh_proxy_role *role)
273 {
274 NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_NET_MAX_PDU_LEN);
275 struct bt_mesh_net_rx rx;
276 int err;
277
278 err = bt_mesh_net_decode(&role->buf, BT_MESH_NET_IF_PROXY_CFG,
279 &rx, &buf);
280 if (err) {
281 LOG_ERR("Failed to decode Proxy Configuration (err %d)", err);
282 return;
283 }
284
285 rx.local_match = 1U;
286
287 if (bt_mesh_rpl_check(&rx, NULL)) {
288 LOG_WRN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", rx.ctx.addr, rx.ctx.recv_dst,
289 rx.seq);
290 return;
291 }
292
293 /* Remove network headers */
294 net_buf_simple_pull(&buf, BT_MESH_NET_HDR_LEN);
295
296 LOG_DBG("%u bytes: %s", buf.len, bt_hex(buf.data, buf.len));
297
298 if (buf.len < 1) {
299 LOG_WRN("Too short proxy configuration PDU");
300 return;
301 }
302
303 proxy_filter_recv(role->conn, &rx, &buf);
304 }
305
proxy_msg_recv(struct bt_mesh_proxy_role * role)306 static void proxy_msg_recv(struct bt_mesh_proxy_role *role)
307 {
308 switch (role->msg_type) {
309 case BT_MESH_PROXY_NET_PDU:
310 LOG_DBG("Mesh Network PDU");
311 bt_mesh_net_recv(&role->buf, 0, BT_MESH_NET_IF_PROXY);
312 break;
313 case BT_MESH_PROXY_BEACON:
314 LOG_DBG("Mesh Beacon PDU");
315 bt_mesh_beacon_recv(&role->buf);
316 break;
317 case BT_MESH_PROXY_CONFIG:
318 LOG_DBG("Mesh Configuration PDU");
319 proxy_cfg(role);
320 break;
321 default:
322 LOG_WRN("Unhandled Message Type 0x%02x", role->msg_type);
323 break;
324 }
325 }
326
beacon_send(struct bt_mesh_proxy_client * client,struct bt_mesh_subnet * sub)327 static int beacon_send(struct bt_mesh_proxy_client *client,
328 struct bt_mesh_subnet *sub)
329 {
330 int err;
331
332 NET_BUF_SIMPLE_DEFINE(buf, 28);
333
334 net_buf_simple_reserve(&buf, 1);
335
336 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
337 err = bt_mesh_beacon_create(sub, &buf, client->privacy);
338 #else
339 err = bt_mesh_beacon_create(sub, &buf, false);
340 #endif
341 if (err) {
342 return err;
343 }
344
345 return bt_mesh_proxy_msg_send(client->cli->conn, BT_MESH_PROXY_BEACON,
346 &buf, NULL, NULL);
347 }
348
send_beacon_cb(struct bt_mesh_subnet * sub,void * cb_data)349 static bool send_beacon_cb(struct bt_mesh_subnet *sub, void *cb_data)
350 {
351 struct bt_mesh_proxy_client *client = cb_data;
352
353 return beacon_send(client, sub) != 0;
354 }
355
proxy_send_beacons(struct k_work * work)356 static void proxy_send_beacons(struct k_work *work)
357 {
358 struct bt_mesh_proxy_client *client;
359
360 client = CONTAINER_OF(work, struct bt_mesh_proxy_client, send_beacons);
361
362 (void)bt_mesh_subnet_find(send_beacon_cb, client);
363 }
364
bt_mesh_proxy_beacon_send(struct bt_mesh_subnet * sub)365 void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub)
366 {
367 int i;
368
369 if (!sub) {
370 /* NULL means we send on all subnets */
371 bt_mesh_subnet_foreach(bt_mesh_proxy_beacon_send);
372 return;
373 }
374
375 for (i = 0; i < ARRAY_SIZE(clients); i++) {
376 if (clients[i].cli) {
377 beacon_send(&clients[i], sub);
378 }
379 }
380 }
381
identity_enabled(struct bt_mesh_subnet * sub)382 static void identity_enabled(struct bt_mesh_subnet *sub)
383 {
384 sub->node_id = BT_MESH_NODE_IDENTITY_RUNNING;
385 sub->node_id_start = k_uptime_get_32();
386
387 STRUCT_SECTION_FOREACH(bt_mesh_proxy_cb, cb) {
388 if (cb->identity_enabled) {
389 cb->identity_enabled(sub->net_idx);
390 }
391 }
392 }
393
node_id_start(struct bt_mesh_subnet * sub)394 static void node_id_start(struct bt_mesh_subnet *sub)
395 {
396 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
397 sub->priv_beacon_ctx.node_id = false;
398 #endif
399
400 identity_enabled(sub);
401 }
402
private_node_id_start(struct bt_mesh_subnet * sub)403 static void private_node_id_start(struct bt_mesh_subnet *sub)
404 {
405 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
406 sub->priv_beacon_ctx.node_id = true;
407 #endif
408
409 identity_enabled(sub);
410 }
411
bt_mesh_proxy_identity_start(struct bt_mesh_subnet * sub,bool private)412 void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub, bool private)
413 {
414 if (private) {
415 private_node_id_start(sub);
416 } else {
417 node_id_start(sub);
418 }
419
420 /* Prioritize the recently enabled subnet */
421 beacon_sub = sub;
422 }
423
bt_mesh_proxy_identity_stop(struct bt_mesh_subnet * sub)424 void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub)
425 {
426 sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED;
427 sub->node_id_start = 0U;
428
429 STRUCT_SECTION_FOREACH(bt_mesh_proxy_cb, cb) {
430 if (cb->identity_disabled) {
431 cb->identity_disabled(sub->net_idx);
432 }
433 }
434 }
435
bt_mesh_proxy_identity_enable(void)436 int bt_mesh_proxy_identity_enable(void)
437 {
438 LOG_DBG("");
439
440 if (!bt_mesh_is_provisioned()) {
441 return -EAGAIN;
442 }
443
444 if (bt_mesh_subnet_foreach(node_id_start)) {
445 bt_mesh_adv_gatt_update();
446 }
447
448 return 0;
449 }
450
bt_mesh_proxy_private_identity_enable(void)451 int bt_mesh_proxy_private_identity_enable(void)
452 {
453 LOG_DBG("");
454
455 if (!IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS)) {
456 return -ENOTSUP;
457 }
458
459 if (!bt_mesh_is_provisioned()) {
460 return -EAGAIN;
461 }
462
463 if (bt_mesh_subnet_foreach(private_node_id_start)) {
464 bt_mesh_adv_gatt_update();
465 }
466
467 return 0;
468 }
469
470 #define ENC_ID_LEN 19
471 #define NET_ID_LEN 11
472
473 #define NODE_ID_TIMEOUT (CONFIG_BT_MESH_NODE_ID_TIMEOUT * MSEC_PER_SEC)
474
475 static uint8_t proxy_svc_data[ENC_ID_LEN] = {
476 BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL),
477 };
478
479 static const struct bt_data enc_id_ad[] = {
480 BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
481 BT_DATA_BYTES(BT_DATA_UUID16_ALL,
482 BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL)),
483 BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, ENC_ID_LEN),
484 };
485
486 static const struct bt_data net_id_ad[] = {
487 BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
488 BT_DATA_BYTES(BT_DATA_UUID16_ALL,
489 BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL)),
490 BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, NET_ID_LEN),
491 };
492
randomize_bt_addr(void)493 static int randomize_bt_addr(void)
494 {
495 /* TODO: There appears to be no way to force an RPA/NRPA refresh. */
496 return 0;
497 }
498
enc_id_adv(struct bt_mesh_subnet * sub,uint8_t type,uint8_t hash[16],int32_t duration)499 static int enc_id_adv(struct bt_mesh_subnet *sub, uint8_t type,
500 uint8_t hash[16], int32_t duration)
501 {
502 struct bt_le_adv_param slow_adv_param = {
503 .id = BT_ID_DEFAULT,
504 .options = ADV_OPT_PROXY(type == BT_MESH_ID_TYPE_PRIV_NET ||
505 type == BT_MESH_ID_TYPE_PRIV_NODE),
506 ADV_SLOW_INT,
507 };
508 struct bt_le_adv_param fast_adv_param = {
509 .id = BT_ID_DEFAULT,
510 .options = ADV_OPT_PROXY(type == BT_MESH_ID_TYPE_PRIV_NET ||
511 type == BT_MESH_ID_TYPE_PRIV_NODE),
512 ADV_FAST_INT,
513 };
514 int err;
515
516 err = bt_mesh_encrypt(&sub->keys[SUBNET_KEY_TX_IDX(sub)].identity, hash, hash);
517 if (err) {
518 return err;
519 }
520
521 /* Section 7.2.2.2.4: The AdvA field shall be regenerated whenever the Random field is
522 * regenerated.
523 */
524 err = randomize_bt_addr();
525 if (err) {
526 LOG_ERR("AdvA refresh failed: %d", err);
527 return err;
528 }
529
530 proxy_svc_data[2] = type;
531 memcpy(&proxy_svc_data[3], &hash[8], 8);
532
533 err = bt_mesh_adv_gatt_start(
534 type == BT_MESH_ID_TYPE_PRIV_NET ? &slow_adv_param : &fast_adv_param,
535 duration, enc_id_ad, ARRAY_SIZE(enc_id_ad), NULL, 0);
536 if (err) {
537 LOG_WRN("Failed to advertise using type 0x%02x (err %d)", type, err);
538 return err;
539 }
540
541 return 0;
542 }
543
node_id_adv(struct bt_mesh_subnet * sub,int32_t duration)544 static int node_id_adv(struct bt_mesh_subnet *sub, int32_t duration)
545 {
546 uint8_t *random = &proxy_svc_data[11];
547 uint8_t tmp[16];
548 int err;
549
550 LOG_DBG("0x%03x", sub->net_idx);
551
552 err = bt_rand(random, 8);
553 if (err) {
554 return err;
555 }
556
557 memset(&tmp[0], 0x00, 6);
558 memcpy(&tmp[6], random, 8);
559 sys_put_be16(bt_mesh_primary_addr(), &tmp[14]);
560
561 return enc_id_adv(sub, BT_MESH_ID_TYPE_NODE, tmp, duration);
562 }
563
priv_node_id_adv(struct bt_mesh_subnet * sub,int32_t duration)564 static int priv_node_id_adv(struct bt_mesh_subnet *sub, int32_t duration)
565 {
566 uint8_t *random = &proxy_svc_data[11];
567 uint8_t tmp[16];
568 int err;
569
570 LOG_DBG("0x%03x", sub->net_idx);
571
572 err = bt_rand(random, 8);
573 if (err) {
574 return err;
575 }
576
577 memset(&tmp[0], 0x00, 5);
578 tmp[5] = 0x03;
579 memcpy(&tmp[6], random, 8);
580 sys_put_be16(bt_mesh_primary_addr(), &tmp[14]);
581
582 return enc_id_adv(sub, BT_MESH_ID_TYPE_PRIV_NODE, tmp, duration);
583 }
584
priv_net_id_adv(struct bt_mesh_subnet * sub,int32_t duration)585 static int priv_net_id_adv(struct bt_mesh_subnet *sub, int32_t duration)
586 {
587 uint8_t *random = &proxy_svc_data[11];
588 uint8_t tmp[16];
589 int err;
590
591 LOG_DBG("0x%03x", sub->net_idx);
592
593 err = bt_rand(random, 8);
594 if (err) {
595 return err;
596 }
597
598 memcpy(&tmp[0], sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8);
599 memcpy(&tmp[8], random, 8);
600
601 return enc_id_adv(sub, BT_MESH_ID_TYPE_PRIV_NET, tmp, duration);
602 }
603
net_id_adv(struct bt_mesh_subnet * sub,int32_t duration)604 static int net_id_adv(struct bt_mesh_subnet *sub, int32_t duration)
605 {
606 struct bt_le_adv_param slow_adv_param = {
607 .id = BT_ID_DEFAULT,
608 .options = ADV_OPT_PROXY(false),
609 ADV_SLOW_INT,
610 };
611 int err;
612
613 proxy_svc_data[2] = BT_MESH_ID_TYPE_NET;
614
615 LOG_DBG("Advertising with NetId %s", bt_hex(sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8));
616
617 memcpy(proxy_svc_data + 3, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8);
618
619 err = bt_mesh_adv_gatt_start(&slow_adv_param, duration, net_id_ad,
620 ARRAY_SIZE(net_id_ad), NULL, 0);
621 if (err) {
622 LOG_WRN("Failed to advertise using Network ID (err %d)", err);
623 return err;
624 }
625
626 return 0;
627 }
628
advertise_subnet(struct bt_mesh_subnet * sub)629 static bool advertise_subnet(struct bt_mesh_subnet *sub)
630 {
631 if (sub->net_idx == BT_MESH_KEY_UNUSED) {
632 return false;
633 }
634
635 return (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING ||
636 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
637 sub->solicited ||
638 #endif
639 bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED ||
640 bt_mesh_priv_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED);
641 }
642
next_sub(void)643 static struct bt_mesh_subnet *next_sub(void)
644 {
645 struct bt_mesh_subnet *sub = NULL;
646
647 if (!beacon_sub) {
648 beacon_sub = bt_mesh_subnet_next(NULL);
649 if (!beacon_sub) {
650 /* No valid subnets */
651 return NULL;
652 }
653 }
654
655 sub = beacon_sub;
656 do {
657 if (advertise_subnet(sub)) {
658 beacon_sub = sub;
659 return sub;
660 }
661
662 sub = bt_mesh_subnet_next(sub);
663 } while (sub != beacon_sub);
664
665 /* No subnets to advertise on */
666 return NULL;
667 }
668
sub_count_cb(struct bt_mesh_subnet * sub,void * cb_data)669 static bool sub_count_cb(struct bt_mesh_subnet *sub, void *cb_data)
670 {
671 int *count = cb_data;
672
673 if (advertise_subnet(sub)) {
674 (*count)++;
675 }
676
677 /* Don't stop until we've visited all subnets.
678 * We're only using the "find" variant of the subnet iteration to get a context parameter.
679 */
680 return false;
681 }
682
sub_count(void)683 static int sub_count(void)
684 {
685 int count = 0;
686
687 (void)bt_mesh_subnet_find(sub_count_cb, &count);
688
689 return count;
690 }
691
692 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
gatt_proxy_solicited(struct bt_mesh_subnet * sub)693 static void gatt_proxy_solicited(struct bt_mesh_subnet *sub)
694 {
695 int64_t now = k_uptime_get();
696 int64_t timeout = 0;
697 int32_t remaining;
698
699 if (sub->priv_net_id_sent > 0) {
700 timeout = sub->priv_net_id_sent + MSEC_PER_SEC * bt_mesh_od_priv_proxy_get();
701 remaining = MIN(timeout - now, INT32_MAX);
702 } else {
703 remaining = MSEC_PER_SEC * bt_mesh_od_priv_proxy_get();
704 }
705
706 if ((timeout > 0 && now > timeout) || (remaining / MSEC_PER_SEC < 1)) {
707 LOG_DBG("Advertising Private Network ID timed out "
708 "after solicitation");
709 sub->priv_net_id_sent = 0;
710 sub->solicited = false;
711 } else {
712 LOG_DBG("Advertising Private Network ID for %ds"
713 "(%d remaining)",
714 bt_mesh_od_priv_proxy_get(),
715 remaining / MSEC_PER_SEC);
716 priv_net_id_adv(sub, remaining);
717
718 if (!sub->priv_net_id_sent) {
719 sub->priv_net_id_sent = now;
720 }
721 }
722 }
723 #endif
724
gatt_proxy_advertise(struct bt_mesh_subnet * sub)725 static int gatt_proxy_advertise(struct bt_mesh_subnet *sub)
726 {
727 int32_t remaining = SYS_FOREVER_MS;
728 int subnet_count;
729 int err = -EBUSY;
730 bool planned = false;
731
732 LOG_DBG("");
733
734 if (!bt_mesh_proxy_has_avail_conn()) {
735 LOG_DBG("Connectable advertising deferred (max connections)");
736 return -ENOMEM;
737 }
738
739 sub = beacon_sub ? beacon_sub : bt_mesh_subnet_next(beacon_sub);
740 if (!sub) {
741 LOG_WRN("No subnets to advertise on");
742 return -ENOENT;
743 }
744
745 subnet_count = sub_count();
746 LOG_DBG("sub_count %u", subnet_count);
747 if (subnet_count > 1) {
748 int32_t max_timeout;
749
750 /* We use NODE_ID_TIMEOUT as a starting point since it may
751 * be less than 60 seconds. Divide this period into at least
752 * 6 slices, but make sure that a slice is at least one
753 * second long (to avoid excessive rotation).
754 */
755 max_timeout = NODE_ID_TIMEOUT / MAX(subnet_count, 6);
756 max_timeout = MAX(max_timeout, 1 * MSEC_PER_SEC);
757
758 if (remaining > max_timeout || remaining == SYS_FOREVER_MS) {
759 remaining = max_timeout;
760 }
761 }
762
763 for (int i = 0; i < subnet_count; i++) {
764
765 if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) {
766 uint32_t active = k_uptime_get_32() - sub->node_id_start;
767 bool priv_node_id = false;
768
769 if (active < NODE_ID_TIMEOUT) {
770 remaining = MIN(remaining, NODE_ID_TIMEOUT - active);
771 LOG_DBG("Node ID active for %u ms, %d ms remaining",
772 active, remaining);
773 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
774 priv_node_id = sub->priv_beacon_ctx.node_id;
775 #endif
776 if (priv_node_id) {
777 err = priv_node_id_adv(sub, remaining);
778 } else {
779 err = node_id_adv(sub, remaining);
780 }
781 planned = true;
782 } else {
783 bt_mesh_proxy_identity_stop(sub);
784 LOG_DBG("Node ID stopped");
785 }
786 }
787
788 /* Mesh Profile Specification v1.0.1, section 7.2.2.2.1
789 * A node that does not support the Proxy feature or
790 * has the GATT Proxy state disabled shall not advertise with Network ID.
791 */
792 if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) {
793 if (IS_ENABLED(CONFIG_BT_MESH_PRIV_BEACONS) &&
794 (bt_mesh_priv_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED)) {
795 /* Bluetooth mesh specification v1.1, section 7.2.2.2.4: The Random
796 * field should be updated every 10 minutes. Limit advertising to
797 * 10 minutes to ensure regeneration of a new random value at least
798 * that often.
799 */
800 if (remaining == SYS_FOREVER_MS ||
801 remaining > PROXY_RANDOM_UPDATE_INTERVAL) {
802 remaining = PROXY_RANDOM_UPDATE_INTERVAL;
803 }
804
805 err = priv_net_id_adv(sub, remaining);
806 planned = true;
807 } else if (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED) {
808 err = net_id_adv(sub, remaining);
809 planned = true;
810 }
811
812 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
813 else if (bt_mesh_od_priv_proxy_get() > 0 &&
814 sub->solicited) {
815 gatt_proxy_solicited(sub);
816 }
817 #endif
818 }
819
820 beacon_sub = bt_mesh_subnet_next(sub);
821
822 if (planned) {
823 LOG_DBG("Advertising %d ms for net_idx 0x%04x", remaining, sub->net_idx);
824 return err;
825 }
826
827 sub = beacon_sub;
828 }
829
830 return 0;
831 }
832
subnet_evt(struct bt_mesh_subnet * sub,enum bt_mesh_key_evt evt)833 static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt)
834 {
835 if (evt == BT_MESH_KEY_DELETED) {
836 if (sub == beacon_sub) {
837 beacon_sub = NULL;
838 }
839 } else {
840 bt_mesh_proxy_beacon_send(sub);
841 bt_mesh_adv_gatt_update();
842 }
843 }
844
845 BT_MESH_SUBNET_CB_DEFINE(gatt_services) = {
846 .evt_handler = subnet_evt,
847 };
848
proxy_ccc_changed(const struct bt_gatt_attr * attr,uint16_t value)849 static void proxy_ccc_changed(const struct bt_gatt_attr *attr, uint16_t value)
850 {
851 LOG_DBG("value 0x%04x", value);
852 }
853
proxy_ccc_write(struct bt_conn * conn,const struct bt_gatt_attr * attr,uint16_t value)854 static ssize_t proxy_ccc_write(struct bt_conn *conn,
855 const struct bt_gatt_attr *attr, uint16_t value)
856 {
857 struct bt_mesh_proxy_client *client;
858
859 LOG_DBG("value: 0x%04x", value);
860
861 if (value != BT_GATT_CCC_NOTIFY) {
862 LOG_WRN("Client wrote 0x%04x instead enabling notify", value);
863 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
864 }
865
866 client = find_client(conn);
867 if (client->filter_type == NONE) {
868 client->filter_type = ACCEPT;
869 k_work_submit(&client->send_beacons);
870 }
871
872 return sizeof(value);
873 }
874
875 /* Mesh Proxy Service Declaration */
876 static struct _bt_gatt_ccc proxy_ccc =
877 BT_GATT_CCC_INITIALIZER(proxy_ccc_changed, proxy_ccc_write, NULL);
878
879 static struct bt_gatt_attr proxy_attrs[] = {
880 BT_GATT_PRIMARY_SERVICE(BT_UUID_MESH_PROXY),
881
882 BT_GATT_CHARACTERISTIC(BT_UUID_MESH_PROXY_DATA_IN,
883 BT_GATT_CHRC_WRITE_WITHOUT_RESP,
884 BT_GATT_PERM_WRITE,
885 NULL, gatt_recv, NULL),
886
887 BT_GATT_CHARACTERISTIC(BT_UUID_MESH_PROXY_DATA_OUT,
888 BT_GATT_CHRC_NOTIFY,
889 BT_GATT_PERM_NONE,
890 NULL, NULL, NULL),
891 BT_GATT_CCC_MANAGED(&proxy_ccc,
892 BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
893 };
894
895 static struct bt_gatt_service proxy_svc = BT_GATT_SERVICE(proxy_attrs);
896 static void svc_reg_work_handler(struct k_work *work);
897 static struct k_work_delayable svc_reg_work = Z_WORK_DELAYABLE_INITIALIZER(svc_reg_work_handler);
898 static uint32_t svc_reg_attempts;
899
svc_reg_work_handler(struct k_work * work)900 static void svc_reg_work_handler(struct k_work *work)
901 {
902 int err;
903
904 err = bt_gatt_service_register(&proxy_svc);
905 if ((err == -EINVAL) && ((--svc_reg_attempts) > 0)) {
906 /* settings_load() didn't finish yet. Try again. */
907 (void)k_work_schedule(&svc_reg_work, PROXY_SVC_INIT_TIMEOUT);
908 return;
909 } else if (err) {
910 LOG_ERR("Unable to register Mesh Proxy Service (err %d)", err);
911 return;
912 }
913
914 service_registered = true;
915
916 for (int i = 0; i < ARRAY_SIZE(clients); i++) {
917 if (clients[i].cli) {
918 clients[i].filter_type = ACCEPT;
919 }
920 }
921
922 bt_mesh_adv_gatt_update();
923 }
924
bt_mesh_proxy_gatt_enable(void)925 int bt_mesh_proxy_gatt_enable(void)
926 {
927 LOG_DBG("");
928
929 if (!bt_mesh_is_provisioned()) {
930 return -ENOTSUP;
931 }
932
933 if (service_registered) {
934 return -EBUSY;
935 }
936
937 svc_reg_attempts = PROXY_SVC_REG_ATTEMPTS;
938 return k_work_schedule(&svc_reg_work, PROXY_SVC_INIT_TIMEOUT);
939 }
940
bt_mesh_proxy_gatt_disconnect(void)941 void bt_mesh_proxy_gatt_disconnect(void)
942 {
943 int i;
944
945 LOG_DBG("");
946
947 for (i = 0; i < ARRAY_SIZE(clients); i++) {
948 struct bt_mesh_proxy_client *client = &clients[i];
949
950 if (client->cli && (client->filter_type == ACCEPT ||
951 client->filter_type == REJECT)) {
952 client->filter_type = NONE;
953 bt_conn_disconnect(client->cli->conn,
954 BT_HCI_ERR_REMOTE_USER_TERM_CONN);
955 }
956 }
957 }
958
bt_mesh_proxy_gatt_disable(void)959 int bt_mesh_proxy_gatt_disable(void)
960 {
961 LOG_DBG("");
962
963 if (!service_registered) {
964 return -EALREADY;
965 }
966
967 bt_mesh_proxy_gatt_disconnect();
968
969 bt_gatt_service_unregister(&proxy_svc);
970 service_registered = false;
971
972 return 0;
973 }
974
bt_mesh_proxy_addr_add(struct net_buf_simple * buf,uint16_t addr)975 void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, uint16_t addr)
976 {
977 struct bt_mesh_proxy_client *client;
978 struct bt_mesh_proxy_role *cli =
979 CONTAINER_OF(buf, struct bt_mesh_proxy_role, buf);
980
981 client = find_client(cli->conn);
982
983 LOG_DBG("filter_type %u addr 0x%04x", client->filter_type, addr);
984
985 if (client->filter_type == ACCEPT) {
986 filter_add(client, addr);
987 } else if (client->filter_type == REJECT) {
988 filter_remove(client, addr);
989 }
990 }
991
client_filter_match(struct bt_mesh_proxy_client * client,uint16_t addr)992 static bool client_filter_match(struct bt_mesh_proxy_client *client,
993 uint16_t addr)
994 {
995 int i;
996
997 LOG_DBG("filter_type %u addr 0x%04x", client->filter_type, addr);
998
999 if (client->filter_type == REJECT) {
1000 for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
1001 if (client->filter[i] == addr) {
1002 return false;
1003 }
1004 }
1005
1006 return true;
1007 }
1008
1009 if (addr == BT_MESH_ADDR_ALL_NODES) {
1010 return true;
1011 }
1012
1013 if (client->filter_type == ACCEPT) {
1014 for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
1015 if (client->filter[i] == addr) {
1016 return true;
1017 }
1018 }
1019 }
1020
1021 return false;
1022 }
1023
bt_mesh_proxy_relay(struct net_buf * buf,uint16_t dst)1024 bool bt_mesh_proxy_relay(struct net_buf *buf, uint16_t dst)
1025 {
1026 bool relayed = false;
1027 int i;
1028
1029 LOG_DBG("%u bytes to dst 0x%04x", buf->len, dst);
1030
1031 for (i = 0; i < ARRAY_SIZE(clients); i++) {
1032 struct bt_mesh_proxy_client *client = &clients[i];
1033
1034 if (!client->cli) {
1035 continue;
1036 }
1037
1038 if (!client_filter_match(client, dst)) {
1039 continue;
1040 }
1041
1042 if (bt_mesh_proxy_relay_send(client->cli->conn, buf)) {
1043 continue;
1044 }
1045
1046 relayed = true;
1047 }
1048
1049 return relayed;
1050 }
1051
solicitation_reset(struct bt_mesh_subnet * sub)1052 static void solicitation_reset(struct bt_mesh_subnet *sub)
1053 {
1054 #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV)
1055 sub->solicited = false;
1056 sub->priv_net_id_sent = 0;
1057 #endif
1058 }
1059
gatt_connected(struct bt_conn * conn,uint8_t err)1060 static void gatt_connected(struct bt_conn *conn, uint8_t err)
1061 {
1062 struct bt_mesh_proxy_client *client;
1063 struct bt_conn_info info;
1064
1065 bt_conn_get_info(conn, &info);
1066 if (info.role != BT_CONN_ROLE_PERIPHERAL || !service_registered ||
1067 info.id != BT_ID_DEFAULT) {
1068 return;
1069 }
1070
1071 LOG_DBG("conn %p err 0x%02x", (void *)conn, err);
1072
1073 client = find_client(conn);
1074
1075 client->filter_type = NONE;
1076 (void)memset(client->filter, 0, sizeof(client->filter));
1077 client->cli = bt_mesh_proxy_role_setup(conn, proxy_send,
1078 proxy_msg_recv);
1079
1080 #if defined(CONFIG_BT_MESH_PRIV_BEACONS)
1081 /* Binding from section 7.2.2.2.6 of MshPRTv1.1. */
1082 enum bt_mesh_subnets_node_id_state cur_node_id = bt_mesh_subnets_node_id_state_get();
1083
1084 if (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED ||
1085 cur_node_id == BT_MESH_SUBNETS_NODE_ID_STATE_ENABLED) {
1086 client->privacy = false;
1087 } else {
1088 client->privacy = (bt_mesh_priv_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED) ||
1089 (cur_node_id == BT_MESH_SUBNETS_NODE_ID_STATE_ENABLED_PRIVATE);
1090 }
1091
1092 LOG_DBG("privacy: %d", client->privacy);
1093 #endif
1094
1095 /* If connection was formed after Proxy Solicitation we need to stop future
1096 * Private Network ID advertisements
1097 */
1098 bt_mesh_subnet_foreach(solicitation_reset);
1099
1100 /* Try to re-enable advertising in case it's possible */
1101 if (bt_mesh_proxy_has_avail_conn()) {
1102 bt_mesh_adv_gatt_update();
1103 }
1104 }
1105
gatt_disconnected(struct bt_conn * conn,uint8_t reason)1106 static void gatt_disconnected(struct bt_conn *conn, uint8_t reason)
1107 {
1108 struct bt_conn_info info;
1109 struct bt_mesh_proxy_client *client;
1110
1111 bt_conn_get_info(conn, &info);
1112 if (info.role != BT_CONN_ROLE_PERIPHERAL || info.id != BT_ID_DEFAULT) {
1113 return;
1114 }
1115
1116 if (!service_registered && bt_mesh_is_provisioned()) {
1117 (void)bt_mesh_proxy_gatt_enable();
1118 return;
1119 }
1120
1121 client = find_client(conn);
1122 if (client->cli) {
1123 bt_mesh_proxy_role_cleanup(client->cli);
1124 client->cli = NULL;
1125 }
1126 }
1127
proxy_send(struct bt_conn * conn,const void * data,uint16_t len,bt_gatt_complete_func_t end,void * user_data)1128 static int proxy_send(struct bt_conn *conn,
1129 const void *data, uint16_t len,
1130 bt_gatt_complete_func_t end, void *user_data)
1131 {
1132 LOG_DBG("%u bytes: %s", len, bt_hex(data, len));
1133
1134 struct bt_gatt_notify_params params = {
1135 .data = data,
1136 .len = len,
1137 .attr = &proxy_attrs[3],
1138 .user_data = user_data,
1139 .func = end,
1140 };
1141
1142 return bt_gatt_notify_cb(conn, ¶ms);
1143 }
1144
bt_mesh_proxy_adv_start(void)1145 int bt_mesh_proxy_adv_start(void)
1146 {
1147 LOG_DBG("");
1148
1149 if (!service_registered || !bt_mesh_is_provisioned()) {
1150 return -ENOTSUP;
1151 }
1152
1153 return gatt_proxy_advertise(next_sub());
1154 }
1155
1156 BT_CONN_CB_DEFINE(conn_callbacks) = {
1157 .connected = gatt_connected,
1158 .disconnected = gatt_disconnected,
1159 };
1160