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