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, &params);
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