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