1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
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/mesh.h>
14 
15 #include "crypto.h"
16 #include "mesh.h"
17 #include "net.h"
18 #include "app_keys.h"
19 #include "transport.h"
20 #include "access.h"
21 #include "foundation.h"
22 #include "friend.h"
23 #include "va.h"
24 
25 #define LOG_LEVEL CONFIG_BT_MESH_FRIEND_LOG_LEVEL
26 #include <zephyr/logging/log.h>
27 LOG_MODULE_REGISTER(bt_mesh_friend);
28 
29 /**
30  * Log modes other than the deferred may cause unintended delays during processing of log messages.
31  * This in turns will affect scheduling of the receive delay and receive window.
32  */
33 #if !defined(CONFIG_TEST) && !defined(CONFIG_ARCH_POSIX) && \
34 	defined(CONFIG_LOG) && !defined(CONFIG_LOG_MODE_DEFERRED) && \
35 	(LOG_LEVEL >= LOG_LEVEL_INF)
36 #warning Frienship feature may work unstable when non-deferred log mode is selected. Use the \
37 	 CONFIG_LOG_MODE_DEFERRED Kconfig option when Friend feature is enabled.
38 #endif
39 
40 /* We reserve one extra buffer for each friendship, since we need to be able
41  * to resend the last sent PDU, which sits separately outside of the queue.
42  */
43 #define FRIEND_BUF_COUNT    ((CONFIG_BT_MESH_FRIEND_QUEUE_SIZE + 1) * \
44 			     CONFIG_BT_MESH_FRIEND_LPN_COUNT)
45 
46 /* PDUs from Friend to the LPN should only be transmitted once with the
47  * smallest possible interval (20ms).
48  */
49 #define FRIEND_XMIT         BT_MESH_TRANSMIT(0, 20)
50 
51 struct friend_pdu_info {
52 	uint16_t  src;
53 	uint16_t  dst;
54 
55 	uint8_t   seq[3];
56 
57 	uint8_t   ttl:7,
58 	       ctl:1;
59 
60 	uint32_t  iv_index;
61 };
62 
63 BUILD_ASSERT(CONFIG_BT_MESH_LABEL_COUNT <= 0xFFFU, "Friend doesn't support more than 4096 labels.");
64 
65 struct friend_adv {
66 	uint16_t app_idx;
67 	struct {
68 		/* CONFIG_BT_MESH_LABEL_COUNT max value is 4096. */
69 		uint16_t uuidx:15,
70 			 seg:1;
71 	};
72 };
73 
74 NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT, BT_MESH_ADV_DATA_SIZE,
75 			  sizeof(struct friend_adv), NULL);
76 
77 static struct friend_adv adv_pool[FRIEND_BUF_COUNT];
78 
79 #define FRIEND_ADV(buf) (*(struct friend_adv **)net_buf_user_data(buf))
80 
adv_alloc(int id)81 static struct friend_adv *adv_alloc(int id)
82 {
83 	adv_pool[id].app_idx = BT_MESH_KEY_UNUSED;
84 	adv_pool[id].seg = false;
85 	return &adv_pool[id];
86 }
87 
friend_is_allocated(const struct bt_mesh_friend * frnd)88 static bool friend_is_allocated(const struct bt_mesh_friend *frnd)
89 {
90 	return frnd->subnet != NULL;
91 }
92 
is_lpn_unicast(struct bt_mesh_friend * frnd,uint16_t addr)93 static bool is_lpn_unicast(struct bt_mesh_friend *frnd, uint16_t addr)
94 {
95 	if (frnd->lpn == BT_MESH_ADDR_UNASSIGNED) {
96 		return false;
97 	}
98 
99 	return (addr >= frnd->lpn && addr < (frnd->lpn + frnd->num_elem));
100 }
101 
bt_mesh_friend_find(uint16_t net_idx,uint16_t lpn_addr,bool valid,bool established)102 struct bt_mesh_friend *bt_mesh_friend_find(uint16_t net_idx, uint16_t lpn_addr,
103 					   bool valid, bool established)
104 {
105 	int i;
106 
107 	LOG_DBG("net_idx 0x%04x lpn_addr 0x%04x", net_idx, lpn_addr);
108 
109 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
110 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
111 
112 		if (valid && !friend_is_allocated(frnd)) {
113 			continue;
114 		}
115 
116 		if (established && !frnd->established) {
117 			continue;
118 		}
119 
120 		if (net_idx != BT_MESH_KEY_ANY &&
121 		    (!frnd->subnet || frnd->subnet->net_idx != net_idx)) {
122 			continue;
123 		}
124 
125 		if (is_lpn_unicast(frnd, lpn_addr)) {
126 			return frnd;
127 		}
128 	}
129 
130 	return NULL;
131 }
132 
friend_cred_create(struct bt_mesh_friend * frnd,uint8_t idx)133 static int friend_cred_create(struct bt_mesh_friend *frnd, uint8_t idx)
134 {
135 	return bt_mesh_friend_cred_create(&frnd->cred[idx], frnd->lpn,
136 					  bt_mesh_primary_addr(),
137 					  frnd->lpn_counter, frnd->counter,
138 					  &frnd->subnet->keys[idx].net);
139 }
140 
purge_buffers(sys_slist_t * list)141 static void purge_buffers(sys_slist_t *list)
142 {
143 	struct net_buf *buf;
144 
145 	while ((buf = (void *)net_buf_slist_get(list))) {
146 		net_buf_unref(buf);
147 	}
148 }
149 
150 /* Intentionally start a little bit late into the ReceiveWindow when
151  * it's large enough. This may improve reliability with some platforms,
152  * like the PTS, where the receiver might not have sufficiently compensated
153  * for internal latencies required to start scanning.
154  */
recv_delay(struct bt_mesh_friend * frnd)155 static int32_t recv_delay(struct bt_mesh_friend *frnd)
156 {
157 #if CONFIG_BT_MESH_FRIEND_RECV_WIN > 50
158 	return (int32_t)frnd->recv_delay + (CONFIG_BT_MESH_FRIEND_RECV_WIN / 5);
159 #else
160 	return frnd->recv_delay;
161 #endif
162 }
163 
friend_clear(struct bt_mesh_friend * frnd)164 static void friend_clear(struct bt_mesh_friend *frnd)
165 {
166 	int i;
167 
168 	LOG_DBG("LPN 0x%04x", frnd->lpn);
169 
170 	/* If cancelling the timer fails, we'll exit early in the work handler. */
171 	(void)k_work_cancel_delayable(&frnd->timer);
172 
173 	for (i = 0; i < ARRAY_SIZE(frnd->cred); i++) {
174 		if (frnd->subnet->keys[i].valid) {
175 			bt_mesh_friend_cred_destroy(&frnd->cred[i]);
176 		}
177 	}
178 	memset(frnd->cred, 0, sizeof(frnd->cred));
179 
180 	if (frnd->last) {
181 		net_buf_unref(frnd->last);
182 		frnd->last = NULL;
183 	}
184 
185 	purge_buffers(&frnd->queue);
186 
187 	for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
188 		struct bt_mesh_friend_seg *seg = &frnd->seg[i];
189 
190 		purge_buffers(&seg->queue);
191 		seg->seg_count = 0U;
192 	}
193 
194 	STRUCT_SECTION_FOREACH(bt_mesh_friend_cb, cb) {
195 		if (frnd->established && cb->terminated) {
196 			cb->terminated(frnd->subnet->net_idx, frnd->lpn);
197 		}
198 	}
199 
200 	frnd->counter++;
201 	frnd->subnet = NULL;
202 	frnd->established = 0U;
203 	frnd->pending_buf = 0U;
204 	frnd->fsn = 0U;
205 	frnd->queue_size = 0U;
206 	frnd->pending_req = 0U;
207 	(void)memset(frnd->sub_list, 0, sizeof(frnd->sub_list));
208 }
209 
bt_mesh_friends_clear(void)210 void bt_mesh_friends_clear(void)
211 {
212 	int i;
213 
214 	LOG_DBG("");
215 
216 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
217 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
218 
219 		if (!friend_is_allocated(frnd)) {
220 			continue;
221 		}
222 
223 		friend_clear(frnd);
224 	}
225 }
226 
227 static void enqueue_update(struct bt_mesh_friend *frnd, uint8_t md);
228 
bt_mesh_friend_sec_update(uint16_t net_idx)229 void bt_mesh_friend_sec_update(uint16_t net_idx)
230 {
231 	int i;
232 
233 	LOG_DBG("net_idx 0x%04x", net_idx);
234 
235 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
236 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
237 
238 		if (!friend_is_allocated(frnd)) {
239 			continue;
240 		}
241 
242 		if (net_idx == BT_MESH_KEY_ANY ||
243 		    frnd->subnet->net_idx == net_idx) {
244 			enqueue_update(frnd, 0x00);
245 		}
246 	}
247 }
248 
bt_mesh_friend_clear(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)249 int bt_mesh_friend_clear(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
250 {
251 	struct bt_mesh_ctl_friend_clear *msg = (void *)buf->data;
252 	struct bt_mesh_friend *frnd;
253 	uint16_t lpn_addr, lpn_counter;
254 	struct bt_mesh_net_tx tx = {
255 		.sub  = rx->sub,
256 		.ctx  = &rx->ctx,
257 		.src  = bt_mesh_primary_addr(),
258 		.xmit = bt_mesh_net_transmit_get(),
259 	};
260 	struct bt_mesh_ctl_friend_clear_confirm cfm;
261 
262 	if (buf->len < sizeof(*msg)) {
263 		LOG_WRN("Too short Friend Clear");
264 		return -EBADMSG;
265 	}
266 
267 	lpn_addr = sys_be16_to_cpu(msg->lpn_addr);
268 	lpn_counter = sys_be16_to_cpu(msg->lpn_counter);
269 
270 	LOG_DBG("LPN addr 0x%04x counter 0x%04x", lpn_addr, lpn_counter);
271 
272 	frnd = bt_mesh_friend_find(rx->sub->net_idx, lpn_addr, false, false);
273 	if (!frnd) {
274 		LOG_WRN("No matching LPN addr 0x%04x", lpn_addr);
275 		return 0;
276 	}
277 
278 	/* A Friend Clear message is considered valid if the result of the
279 	 * subtraction of the value of the LPNCounter field of the Friend
280 	 * Request message (the one that initiated the friendship) from the
281 	 * value of the LPNCounter field of the Friend Clear message, modulo
282 	 * 65536, is in the range 0 to 255 inclusive.
283 	 */
284 	if (lpn_counter - frnd->lpn_counter > 255) {
285 		LOG_WRN("LPN Counter out of range (old %u new %u)", frnd->lpn_counter, lpn_counter);
286 		return 0;
287 	}
288 
289 	tx.ctx->send_ttl = BT_MESH_TTL_MAX;
290 
291 	cfm.lpn_addr    = msg->lpn_addr;
292 	cfm.lpn_counter = msg->lpn_counter;
293 
294 	bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR_CFM, &cfm,
295 			 sizeof(cfm), NULL, NULL);
296 
297 	friend_clear(frnd);
298 
299 	return 0;
300 }
301 
friend_sub_add(struct bt_mesh_friend * frnd,uint16_t addr)302 static void friend_sub_add(struct bt_mesh_friend *frnd, uint16_t addr)
303 {
304 	int empty_idx = INT_MAX;
305 
306 	for (int i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) {
307 		if (frnd->sub_list[i] == addr) {
308 			return;
309 		}
310 
311 		if (frnd->sub_list[i] == BT_MESH_ADDR_UNASSIGNED) {
312 			empty_idx = i;
313 		}
314 	}
315 
316 	if (empty_idx != INT_MAX) {
317 		frnd->sub_list[empty_idx] = addr;
318 		LOG_DBG("%04x added %04x to subscription list", frnd->lpn, addr);
319 	} else {
320 		LOG_WRN("No space in friend subscription list");
321 	}
322 }
323 
friend_sub_rem(struct bt_mesh_friend * frnd,uint16_t addr)324 static void friend_sub_rem(struct bt_mesh_friend *frnd, uint16_t addr)
325 {
326 	int i;
327 
328 	for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) {
329 		if (frnd->sub_list[i] == addr) {
330 			LOG_DBG("%04x removed %04x from subscription list", frnd->lpn, addr);
331 			frnd->sub_list[i] = BT_MESH_ADDR_UNASSIGNED;
332 			return;
333 		}
334 	}
335 }
336 
create_friend_pdu(struct bt_mesh_friend * frnd,struct friend_pdu_info * info,struct net_buf_simple * sdu)337 static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
338 					 struct friend_pdu_info *info,
339 					 struct net_buf_simple *sdu)
340 {
341 	struct net_buf *buf;
342 
343 
344 	buf = net_buf_alloc(&friend_buf_pool, K_NO_WAIT);
345 	if (!buf) {
346 		return NULL;
347 	}
348 
349 	FRIEND_ADV(buf) = adv_alloc(net_buf_id(buf));
350 
351 	net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */
352 
353 	if (info->ctl) {
354 		net_buf_add_u8(buf, info->ttl | 0x80);
355 	} else {
356 		net_buf_add_u8(buf, info->ttl);
357 	}
358 
359 	net_buf_add_mem(buf, info->seq, sizeof(info->seq));
360 
361 	net_buf_add_be16(buf, info->src);
362 	net_buf_add_be16(buf, info->dst);
363 
364 	net_buf_add_mem(buf, sdu->data, sdu->len);
365 
366 	return buf;
367 }
368 
369 struct unseg_app_sdu_meta {
370 	struct bt_mesh_app_crypto_ctx crypto;
371 	const struct bt_mesh_key *key;
372 	struct bt_mesh_subnet *subnet;
373 	uint8_t aid;
374 };
375 
unseg_app_sdu_unpack(struct bt_mesh_friend * frnd,struct net_buf * buf,struct unseg_app_sdu_meta * meta)376 static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd,
377 				struct net_buf *buf,
378 				struct unseg_app_sdu_meta *meta)
379 {
380 	uint16_t app_idx = FRIEND_ADV(buf)->app_idx;
381 	uint16_t uuidx = FRIEND_ADV(buf)->uuidx;
382 	struct bt_mesh_net_rx net = {
383 		.ctx = {
384 			.app_idx = app_idx,
385 			.net_idx = frnd->subnet->net_idx,
386 		},
387 	};
388 	int err;
389 
390 	meta->subnet = frnd->subnet;
391 	bt_mesh_net_header_parse(&buf->b, &net);
392 	err = bt_mesh_keys_resolve(&net.ctx, &net.sub, &meta->key, &meta->aid);
393 	if (err) {
394 		return err;
395 	}
396 
397 	meta->crypto.src = net.ctx.addr;
398 	meta->crypto.dst = net.ctx.recv_dst;
399 	meta->crypto.iv_index = BT_MESH_NET_IVI_TX;
400 	meta->crypto.dev_key = BT_MESH_IS_DEV_KEY(app_idx);
401 	meta->crypto.seq_num = net.seq;
402 	meta->crypto.aszmic = 0;
403 
404 	if (BT_MESH_ADDR_IS_VIRTUAL(meta->crypto.dst)) {
405 		meta->crypto.ad = bt_mesh_va_get_uuid_by_idx(uuidx);
406 	} else {
407 		meta->crypto.ad = NULL;
408 	}
409 
410 	return 0;
411 }
412 
unseg_app_sdu_decrypt(struct bt_mesh_friend * frnd,struct net_buf * buf,const struct unseg_app_sdu_meta * meta)413 static int unseg_app_sdu_decrypt(struct bt_mesh_friend *frnd,
414 				 struct net_buf *buf,
415 				 const struct unseg_app_sdu_meta *meta)
416 {
417 	struct net_buf_simple in;
418 	struct net_buf_simple out;
419 
420 	/* Direct the input buffer at the Upper Transport Access PDU, accounting for
421 	 * the network header and the 1 byte lower transport header
422 	 */
423 	net_buf_simple_clone(&buf->b, &in);
424 	net_buf_simple_pull(&in, BT_MESH_NET_HDR_LEN);
425 	net_buf_simple_pull(&in, 1);
426 	in.len -= BT_MESH_MIC_SHORT;
427 
428 	net_buf_simple_clone(&in, &out);
429 	out.len = 0; /* length will be set by decrypt */
430 
431 	/* Decrypt in place, as we only need to test one key: */
432 	return bt_mesh_app_decrypt(meta->key, &meta->crypto, &in, &out);
433 }
434 
unseg_app_sdu_encrypt(struct bt_mesh_friend * frnd,struct net_buf * buf,const struct unseg_app_sdu_meta * meta)435 static int unseg_app_sdu_encrypt(struct bt_mesh_friend *frnd,
436 				 struct net_buf *buf,
437 				 const struct unseg_app_sdu_meta *meta)
438 {
439 	struct net_buf_simple sdu;
440 
441 	net_buf_simple_clone(&buf->b, &sdu);
442 	net_buf_simple_pull(&sdu, BT_MESH_NET_HDR_LEN);
443 	net_buf_simple_pull(&sdu, 1);
444 	sdu.len -= BT_MESH_MIC_SHORT;
445 
446 	return bt_mesh_app_encrypt(meta->key, &meta->crypto, &sdu);
447 }
448 
unseg_app_sdu_prepare(struct bt_mesh_friend * frnd,struct net_buf * buf)449 static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd,
450 				 struct net_buf *buf)
451 {
452 	struct unseg_app_sdu_meta meta;
453 	int err;
454 
455 	if (FRIEND_ADV(buf)->app_idx == BT_MESH_KEY_UNUSED) {
456 		return 0;
457 	}
458 
459 	err = unseg_app_sdu_unpack(frnd, buf, &meta);
460 	if (err) {
461 		return err;
462 	}
463 
464 	/* No need to reencrypt the message if the sequence number is
465 	 * unchanged.
466 	 */
467 	if (meta.crypto.seq_num == bt_mesh.seq) {
468 		return 0;
469 	}
470 
471 	LOG_DBG("Re-encrypting friend pdu (SeqNum %06x -> %06x)", meta.crypto.seq_num, bt_mesh.seq);
472 
473 	err = unseg_app_sdu_decrypt(frnd, buf, &meta);
474 	if (err) {
475 		LOG_WRN("Decryption failed! %d", err);
476 		return err;
477 	}
478 
479 	meta.crypto.seq_num = bt_mesh.seq;
480 
481 	err = unseg_app_sdu_encrypt(frnd, buf, &meta);
482 	if (err) {
483 		LOG_WRN("Re-encryption failed! %d", err);
484 	}
485 
486 	return err;
487 }
488 
encrypt_friend_pdu(struct bt_mesh_friend * frnd,struct net_buf * buf,bool flooding_cred)489 static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf,
490 			      bool flooding_cred)
491 {
492 	const struct bt_mesh_net_cred *cred;
493 	uint32_t iv_index;
494 	uint16_t src;
495 	int err;
496 
497 	if (flooding_cred) {
498 		cred = &frnd->subnet->keys[SUBNET_KEY_TX_IDX(frnd->subnet)]
499 				.msg;
500 	} else {
501 		cred = &frnd->cred[SUBNET_KEY_TX_IDX(frnd->subnet)];
502 	}
503 
504 	src = sys_get_be16(&buf->data[5]);
505 
506 	if (bt_mesh_has_addr(src)) {
507 		uint32_t seq;
508 
509 		if (FRIEND_ADV(buf)->app_idx != BT_MESH_KEY_UNUSED) {
510 			err = unseg_app_sdu_prepare(frnd, buf);
511 			if (err) {
512 				return err;
513 			}
514 		}
515 
516 		seq = bt_mesh_next_seq();
517 		sys_put_be24(seq, &buf->data[2]);
518 
519 		iv_index = BT_MESH_NET_IVI_TX;
520 		FRIEND_ADV(buf)->app_idx = BT_MESH_KEY_UNUSED;
521 	} else {
522 		uint8_t ivi = (buf->data[0] >> 7);
523 		iv_index = (bt_mesh.iv_index - ((bt_mesh.iv_index & 1) != ivi));
524 	}
525 
526 	buf->data[0] = (cred->nid | (iv_index & 1) << 7);
527 
528 	if (bt_mesh_net_encrypt(&cred->enc, &buf->b, iv_index, BT_MESH_NONCE_NETWORK)) {
529 		LOG_ERR("Encrypting failed");
530 		return -EINVAL;
531 	}
532 
533 	if (bt_mesh_net_obfuscate(buf->data, iv_index, &cred->privacy)) {
534 		LOG_ERR("Obfuscating failed");
535 		return -EINVAL;
536 	}
537 
538 	return 0;
539 }
540 
encode_friend_ctl(struct bt_mesh_friend * frnd,uint8_t ctl_op,struct net_buf_simple * sdu)541 static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd,
542 					 uint8_t ctl_op,
543 					 struct net_buf_simple *sdu)
544 {
545 	struct friend_pdu_info info;
546 
547 	LOG_DBG("LPN 0x%04x", frnd->lpn);
548 
549 	net_buf_simple_push_u8(sdu, TRANS_CTL_HDR(ctl_op, 0));
550 
551 	info.src = bt_mesh_primary_addr();
552 	info.dst = frnd->lpn;
553 
554 	info.ctl = 1U;
555 	info.ttl = 0U;
556 
557 	memset(info.seq, 0, sizeof(info.seq));
558 
559 	info.iv_index = BT_MESH_NET_IVI_TX;
560 
561 	return create_friend_pdu(frnd, &info, sdu);
562 }
563 
encode_update(struct bt_mesh_friend * frnd,uint8_t md)564 static struct net_buf *encode_update(struct bt_mesh_friend *frnd, uint8_t md)
565 {
566 	struct bt_mesh_ctl_friend_update *upd;
567 	NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*upd));
568 
569 	__ASSERT_NO_MSG(friend_is_allocated(frnd));
570 
571 	LOG_DBG("lpn 0x%04x md 0x%02x", frnd->lpn, md);
572 
573 	net_buf_simple_reserve(&sdu, 1);
574 
575 	upd = net_buf_simple_add(&sdu, sizeof(*upd));
576 	upd->flags = bt_mesh_net_flags(frnd->subnet);
577 	upd->iv_index = sys_cpu_to_be32(bt_mesh.iv_index);
578 	upd->md = md;
579 
580 	return encode_friend_ctl(frnd, TRANS_CTL_OP_FRIEND_UPDATE, &sdu);
581 }
582 
enqueue_sub_cfm(struct bt_mesh_friend * frnd,uint8_t xact)583 static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, uint8_t xact)
584 {
585 	struct bt_mesh_ctl_friend_sub_confirm *cfm;
586 	NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*cfm));
587 	struct net_buf *buf;
588 
589 	LOG_DBG("lpn 0x%04x xact 0x%02x", frnd->lpn, xact);
590 
591 	net_buf_simple_reserve(&sdu, 1);
592 
593 	cfm = net_buf_simple_add(&sdu, sizeof(*cfm));
594 	cfm->xact = xact;
595 
596 	buf = encode_friend_ctl(frnd, TRANS_CTL_OP_FRIEND_SUB_CFM, &sdu);
597 	if (!buf) {
598 		LOG_ERR("Unable to encode Subscription List Confirmation");
599 		return;
600 	}
601 
602 	if (encrypt_friend_pdu(frnd, buf, false)) {
603 		return;
604 	}
605 
606 	if (frnd->last) {
607 		LOG_DBG("Discarding last PDU");
608 		net_buf_unref(frnd->last);
609 	}
610 
611 	frnd->last = buf;
612 	frnd->send_last = 1U;
613 }
614 
friend_recv_delay(struct bt_mesh_friend * frnd)615 static void friend_recv_delay(struct bt_mesh_friend *frnd)
616 {
617 	int32_t delay = recv_delay(frnd);
618 
619 	frnd->pending_req = 1U;
620 	k_work_reschedule(&frnd->timer, K_MSEC(delay));
621 	LOG_DBG("Waiting RecvDelay of %d ms", delay);
622 }
623 
bt_mesh_friend_sub_add(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)624 int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx,
625 			   struct net_buf_simple *buf)
626 {
627 	struct bt_mesh_friend *frnd;
628 	uint8_t xact;
629 
630 	if (buf->len < BT_MESH_FRIEND_SUB_MIN_LEN) {
631 		LOG_WRN("Too short Friend Subscription Add");
632 		return -EBADMSG;
633 	}
634 
635 	frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, true);
636 	if (!frnd) {
637 		LOG_WRN("No matching LPN addr 0x%04x", rx->ctx.addr);
638 		return 0;
639 	}
640 
641 	if (frnd->pending_buf) {
642 		LOG_WRN("Previous buffer not yet sent!");
643 		return 0;
644 	}
645 
646 	friend_recv_delay(frnd);
647 
648 	xact = net_buf_simple_pull_u8(buf);
649 
650 	while (buf->len >= 2U) {
651 		friend_sub_add(frnd, net_buf_simple_pull_be16(buf));
652 	}
653 
654 	enqueue_sub_cfm(frnd, xact);
655 
656 	return 0;
657 }
658 
bt_mesh_friend_sub_rem(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)659 int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx,
660 			   struct net_buf_simple *buf)
661 {
662 	struct bt_mesh_friend *frnd;
663 	uint8_t xact;
664 
665 	if (buf->len < BT_MESH_FRIEND_SUB_MIN_LEN) {
666 		LOG_WRN("Too short Friend Subscription Remove");
667 		return -EBADMSG;
668 	}
669 
670 	frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, true);
671 	if (!frnd) {
672 		LOG_WRN("No matching LPN addr 0x%04x", rx->ctx.addr);
673 		return 0;
674 	}
675 
676 	if (frnd->pending_buf) {
677 		LOG_WRN("Previous buffer not yet sent!");
678 		return 0;
679 	}
680 
681 	friend_recv_delay(frnd);
682 
683 	xact = net_buf_simple_pull_u8(buf);
684 
685 	while (buf->len >= 2U) {
686 		friend_sub_rem(frnd, net_buf_simple_pull_be16(buf));
687 	}
688 
689 	enqueue_sub_cfm(frnd, xact);
690 
691 	return 0;
692 }
693 
enqueue_buf(struct bt_mesh_friend * frnd,struct net_buf * buf)694 static void enqueue_buf(struct bt_mesh_friend *frnd, struct net_buf *buf)
695 {
696 	net_buf_slist_put(&frnd->queue, buf);
697 	frnd->queue_size++;
698 }
699 
enqueue_update(struct bt_mesh_friend * frnd,uint8_t md)700 static void enqueue_update(struct bt_mesh_friend *frnd, uint8_t md)
701 {
702 	struct net_buf *buf;
703 
704 	buf = encode_update(frnd, md);
705 	if (!buf) {
706 		LOG_ERR("Unable to encode Friend Update");
707 		return;
708 	}
709 
710 	enqueue_buf(frnd, buf);
711 }
712 
bt_mesh_friend_poll(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)713 int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
714 {
715 	struct bt_mesh_ctl_friend_poll *msg = (void *)buf->data;
716 	struct bt_mesh_friend *frnd;
717 
718 	if (buf->len < sizeof(*msg)) {
719 		LOG_WRN("Too short Friend Poll");
720 		return -EBADMSG;
721 	}
722 
723 	frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, false);
724 	if (!frnd) {
725 		LOG_WRN("No matching LPN addr 0x%04x", rx->ctx.addr);
726 		return 0;
727 	}
728 
729 	if (msg->fsn & ~1) {
730 		LOG_WRN("Prohibited (non-zero) padding bits");
731 		return -EBADMSG;
732 	}
733 
734 	if (frnd->pending_buf) {
735 		LOG_WRN("Previous buffer not yet sent");
736 		return 0;
737 	}
738 
739 	LOG_DBG("msg->fsn %u frnd->fsn %u", (msg->fsn & 1), frnd->fsn);
740 
741 	friend_recv_delay(frnd);
742 
743 	if (msg->fsn == frnd->fsn && frnd->last) {
744 		LOG_DBG("Re-sending last PDU");
745 		frnd->send_last = 1U;
746 	} else {
747 		if (frnd->last) {
748 			net_buf_unref(frnd->last);
749 			frnd->last = NULL;
750 		}
751 
752 		frnd->fsn = msg->fsn;
753 
754 		if (sys_slist_is_empty(&frnd->queue)) {
755 			enqueue_update(frnd, 0);
756 			LOG_DBG("Enqueued Friend Update to empty queue");
757 		}
758 	}
759 
760 	STRUCT_SECTION_FOREACH(bt_mesh_friend_cb, cb) {
761 		if (cb->polled) {
762 			cb->polled(frnd->subnet->net_idx, frnd->lpn);
763 		}
764 	}
765 
766 	if (!frnd->established) {
767 		LOG_DBG("Friendship established with 0x%04x", frnd->lpn);
768 		frnd->established = 1U;
769 
770 		STRUCT_SECTION_FOREACH(bt_mesh_friend_cb, cb) {
771 			if (cb->established) {
772 				cb->established(frnd->subnet->net_idx, frnd->lpn, frnd->recv_delay,
773 						frnd->poll_to);
774 			}
775 		}
776 	}
777 
778 	return 0;
779 }
780 
find_clear(uint16_t prev_friend)781 static struct bt_mesh_friend *find_clear(uint16_t prev_friend)
782 {
783 	int i;
784 
785 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
786 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
787 
788 		if (frnd->clear.frnd == prev_friend) {
789 			return frnd;
790 		}
791 	}
792 
793 	return NULL;
794 }
795 
friend_clear_sent(int err,void * user_data)796 static void friend_clear_sent(int err, void *user_data)
797 {
798 	struct bt_mesh_friend *frnd = user_data;
799 
800 	k_work_reschedule(&frnd->clear.timer,
801 			  K_SECONDS(frnd->clear.repeat_sec));
802 	frnd->clear.repeat_sec *= 2U;
803 }
804 
805 static const struct bt_mesh_send_cb clear_sent_cb = {
806 	.end = friend_clear_sent,
807 };
808 
send_friend_clear(struct bt_mesh_friend * frnd)809 static void send_friend_clear(struct bt_mesh_friend *frnd)
810 {
811 	struct bt_mesh_msg_ctx ctx = {
812 		.net_idx  = frnd->subnet->net_idx,
813 		.app_idx  = BT_MESH_KEY_UNUSED,
814 		.addr     = frnd->clear.frnd,
815 		.send_ttl = BT_MESH_TTL_MAX,
816 	};
817 	struct bt_mesh_net_tx tx = {
818 		.sub  = frnd->subnet,
819 		.ctx  = &ctx,
820 		.src  = bt_mesh_primary_addr(),
821 		.xmit = bt_mesh_net_transmit_get(),
822 	};
823 	struct bt_mesh_ctl_friend_clear req = {
824 		.lpn_addr    = sys_cpu_to_be16(frnd->lpn),
825 		.lpn_counter = sys_cpu_to_be16(frnd->lpn_counter),
826 	};
827 
828 	LOG_DBG("");
829 
830 	bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req,
831 			 sizeof(req), &clear_sent_cb, frnd);
832 }
833 
clear_timeout(struct k_work * work)834 static void clear_timeout(struct k_work *work)
835 {
836 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
837 	struct bt_mesh_friend *frnd = CONTAINER_OF(dwork, struct bt_mesh_friend,
838 						   clear.timer);
839 	uint32_t duration;
840 
841 	if (frnd->clear.frnd == BT_MESH_ADDR_UNASSIGNED) {
842 		/* Failed cancelling timer, return early. */
843 		return;
844 	}
845 
846 	LOG_DBG("LPN 0x%04x (old) Friend 0x%04x", frnd->lpn, frnd->clear.frnd);
847 
848 	duration = k_uptime_get_32() - frnd->clear.start;
849 	if (duration > 2 * frnd->poll_to) {
850 		LOG_DBG("Clear Procedure timer expired");
851 		frnd->clear.frnd = BT_MESH_ADDR_UNASSIGNED;
852 		return;
853 	}
854 
855 	send_friend_clear(frnd);
856 }
857 
clear_procedure_start(struct bt_mesh_friend * frnd)858 static void clear_procedure_start(struct bt_mesh_friend *frnd)
859 {
860 	LOG_DBG("LPN 0x%04x (old) Friend 0x%04x", frnd->lpn, frnd->clear.frnd);
861 
862 	frnd->clear.start = k_uptime_get_32();
863 	frnd->clear.repeat_sec = 1U;
864 
865 	send_friend_clear(frnd);
866 }
867 
bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)868 int bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx *rx,
869 			     struct net_buf_simple *buf)
870 {
871 	struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->data;
872 	struct bt_mesh_friend *frnd;
873 	uint16_t lpn_addr, lpn_counter;
874 
875 	LOG_DBG("");
876 
877 	if (buf->len < sizeof(*msg)) {
878 		LOG_WRN("Too short Friend Clear Confirm");
879 		return -EBADMSG;
880 	}
881 
882 	frnd = find_clear(rx->ctx.addr);
883 	if (!frnd) {
884 		LOG_WRN("No pending clear procedure for 0x%02x", rx->ctx.addr);
885 		return 0;
886 	}
887 
888 	lpn_addr = sys_be16_to_cpu(msg->lpn_addr);
889 	if (lpn_addr != frnd->lpn) {
890 		LOG_WRN("LPN address mismatch (0x%04x != 0x%04x)", lpn_addr, frnd->lpn);
891 		return 0;
892 	}
893 
894 	lpn_counter = sys_be16_to_cpu(msg->lpn_counter);
895 	if (lpn_counter != frnd->lpn_counter) {
896 		LOG_WRN("LPN counter mismatch (0x%04x != 0x%04x)", lpn_counter, frnd->lpn_counter);
897 		return 0;
898 	}
899 
900 	/* If this fails, the unassigned check will make the handler return early. */
901 	(void)k_work_cancel_delayable(&frnd->clear.timer);
902 	frnd->clear.frnd = BT_MESH_ADDR_UNASSIGNED;
903 
904 	return 0;
905 }
906 
enqueue_offer(struct bt_mesh_friend * frnd,int8_t rssi)907 static void enqueue_offer(struct bt_mesh_friend *frnd, int8_t rssi)
908 {
909 	struct bt_mesh_ctl_friend_offer *off;
910 	NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*off));
911 	struct net_buf *buf;
912 
913 	LOG_DBG("");
914 
915 	net_buf_simple_reserve(&sdu, 1);
916 
917 	off = net_buf_simple_add(&sdu, sizeof(*off));
918 
919 	off->recv_win = CONFIG_BT_MESH_FRIEND_RECV_WIN,
920 	off->queue_size = CONFIG_BT_MESH_FRIEND_QUEUE_SIZE,
921 	off->sub_list_size = ARRAY_SIZE(frnd->sub_list),
922 	off->rssi = rssi,
923 
924 	/* The Counter may be used in the later key update procedure. Therefore
925 	 * we should postpone the update of counter until we terminated friendship.
926 	 */
927 	off->frnd_counter = sys_cpu_to_be16(frnd->counter);
928 
929 	buf = encode_friend_ctl(frnd, TRANS_CTL_OP_FRIEND_OFFER, &sdu);
930 	if (!buf) {
931 		LOG_ERR("Unable to encode Friend Offer");
932 		return;
933 	}
934 
935 	if (encrypt_friend_pdu(frnd, buf, true)) {
936 		return;
937 	}
938 
939 	if (frnd->last) {
940 		net_buf_unref(frnd->last);
941 	}
942 
943 	frnd->last = buf;
944 	frnd->send_last = 1U;
945 }
946 
947 #define RECV_WIN                  CONFIG_BT_MESH_FRIEND_RECV_WIN
948 #define RSSI_FACT(crit)           (((crit) >> 5) & (uint8_t)BIT_MASK(2))
949 #define RECV_WIN_FACT(crit)       (((crit) >> 3) & (uint8_t)BIT_MASK(2))
950 #define MIN_QUEUE_SIZE_LOG(crit)  ((crit) & (uint8_t)BIT_MASK(3))
951 #define MIN_QUEUE_SIZE(crit)      ((uint32_t)BIT(MIN_QUEUE_SIZE_LOG(crit)))
952 
offer_delay(struct bt_mesh_friend * frnd,int8_t rssi,uint8_t crit)953 static int32_t offer_delay(struct bt_mesh_friend *frnd, int8_t rssi, uint8_t crit)
954 {
955 	/* Scaling factors. The actual values are 1, 1.5, 2 & 2.5, but we
956 	 * want to avoid floating-point arithmetic.
957 	 */
958 	static const uint8_t fact[] = { 10, 15, 20, 25 };
959 	int32_t delay;
960 
961 	LOG_DBG("ReceiveWindowFactor %u ReceiveWindow %u RSSIFactor %u RSSI %d",
962 		fact[RECV_WIN_FACT(crit)], RECV_WIN, fact[RSSI_FACT(crit)], rssi);
963 
964 	/* Delay = ReceiveWindowFactor * ReceiveWindow - RSSIFactor * RSSI */
965 	delay = (int32_t)fact[RECV_WIN_FACT(crit)] * RECV_WIN;
966 	delay -= (int32_t)fact[RSSI_FACT(crit)] * rssi;
967 	delay /= 10;
968 
969 	LOG_DBG("Local Delay calculated as %d ms", delay);
970 
971 	return MAX(delay, 100);
972 }
973 
bt_mesh_friend_req(struct bt_mesh_net_rx * rx,struct net_buf_simple * buf)974 int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
975 {
976 	struct bt_mesh_ctl_friend_req *msg = (void *)buf->data;
977 	struct bt_mesh_friend *frnd = NULL;
978 	uint32_t poll_to;
979 	int32_t delay;
980 	int i, err;
981 
982 	if (rx->net_if == BT_MESH_NET_IF_LOCAL) {
983 		LOG_DBG("Ignoring Friend request from local interface");
984 		return 0;
985 	}
986 
987 	if (buf->len < sizeof(*msg)) {
988 		LOG_WRN("Too short Friend Request");
989 		return -EBADMSG;
990 	}
991 
992 	if (msg->recv_delay <= 0x09) {
993 		LOG_WRN("Prohibited ReceiveDelay (0x%02x)", msg->recv_delay);
994 		return -EBADMSG;
995 	}
996 
997 	poll_to = sys_get_be24(msg->poll_to);
998 
999 	if (poll_to <= 0x000009 || poll_to >= 0x34bc00) {
1000 		LOG_WRN("Prohibited PollTimeout (0x%06x)", poll_to);
1001 		return -EBADMSG;
1002 	}
1003 
1004 	if (msg->num_elem == 0x00) {
1005 		LOG_WRN("Prohibited NumElements value (0x00)");
1006 		return -EBADMSG;
1007 	}
1008 
1009 	if (!BT_MESH_ADDR_IS_UNICAST(rx->ctx.addr + msg->num_elem - 1)) {
1010 		LOG_WRN("LPN elements stretch outside of unicast range");
1011 		return -EBADMSG;
1012 	}
1013 
1014 	if (!MIN_QUEUE_SIZE_LOG(msg->criteria)) {
1015 		LOG_WRN("Prohibited Minimum Queue Size in Friend Request");
1016 		return -EBADMSG;
1017 	}
1018 
1019 	if (CONFIG_BT_MESH_FRIEND_QUEUE_SIZE < MIN_QUEUE_SIZE(msg->criteria)) {
1020 		LOG_WRN("We have a too small Friend Queue size (%u < %u)",
1021 			CONFIG_BT_MESH_FRIEND_QUEUE_SIZE, MIN_QUEUE_SIZE(msg->criteria));
1022 		return 0;
1023 	}
1024 
1025 	frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, false);
1026 	if (frnd) {
1027 		LOG_WRN("Existing LPN re-requesting Friendship");
1028 		friend_clear(frnd);
1029 		goto init_friend;
1030 	}
1031 
1032 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
1033 		if (!bt_mesh.frnd[i].subnet) {
1034 			frnd = &bt_mesh.frnd[i];
1035 			break;
1036 		}
1037 	}
1038 
1039 	if (!frnd) {
1040 		LOG_WRN("No free Friend contexts for new LPN");
1041 		return -ENOMEM;
1042 	}
1043 
1044 init_friend:
1045 	frnd->lpn = rx->ctx.addr;
1046 	frnd->num_elem = msg->num_elem;
1047 	frnd->subnet = rx->sub;
1048 	frnd->recv_delay = msg->recv_delay - CONFIG_BT_MESH_FRIEND_ADV_LATENCY;
1049 	frnd->poll_to = poll_to * 100U;
1050 	frnd->lpn_counter = sys_be16_to_cpu(msg->lpn_counter);
1051 	frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr);
1052 
1053 	err = friend_cred_create(frnd, SUBNET_KEY_TX_IDX(frnd->subnet));
1054 	if (err) {
1055 		LOG_ERR("Failed to create friend credentials");
1056 		friend_clear(frnd);
1057 		return -EIO;
1058 	}
1059 
1060 	LOG_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums", frnd->lpn, rx->ctx.recv_rssi,
1061 		frnd->recv_delay, frnd->poll_to);
1062 
1063 	if (BT_MESH_ADDR_IS_UNICAST(frnd->clear.frnd) &&
1064 	    !bt_mesh_has_addr(frnd->clear.frnd)) {
1065 		clear_procedure_start(frnd);
1066 	}
1067 
1068 	delay = offer_delay(frnd, rx->ctx.recv_rssi, msg->criteria);
1069 	k_work_reschedule(&frnd->timer, K_MSEC(delay));
1070 
1071 	enqueue_offer(frnd, rx->ctx.recv_rssi);
1072 
1073 	return 0;
1074 }
1075 
is_seg(struct bt_mesh_friend_seg * seg,uint16_t src,uint16_t seq_zero)1076 static bool is_seg(struct bt_mesh_friend_seg *seg, uint16_t src, uint16_t seq_zero)
1077 {
1078 	struct net_buf *buf = (void *)sys_slist_peek_head(&seg->queue);
1079 	struct net_buf_simple_state state;
1080 	uint16_t buf_seq_zero;
1081 	uint16_t buf_src;
1082 
1083 	if (!buf) {
1084 		return false;
1085 	}
1086 
1087 	net_buf_simple_save(&buf->b, &state);
1088 	net_buf_skip(buf, 5);   /* skip IVI, NID, CTL, TTL, SEQ */
1089 	buf_src = net_buf_pull_be16(buf);
1090 	net_buf_skip(buf, 3);   /* skip DST, OP/AID */
1091 	buf_seq_zero = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK);
1092 	net_buf_simple_restore(&buf->b, &state);
1093 
1094 	return ((src == buf_src) && (seq_zero == buf_seq_zero));
1095 }
1096 
get_seg(struct bt_mesh_friend * frnd,uint16_t src,uint16_t seq_zero,uint8_t seg_count)1097 static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd,
1098 					  uint16_t src, uint16_t seq_zero,
1099 					  uint8_t seg_count)
1100 {
1101 	struct bt_mesh_friend_seg *unassigned = NULL;
1102 	int i;
1103 
1104 	for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
1105 		struct bt_mesh_friend_seg *seg = &frnd->seg[i];
1106 
1107 		if (is_seg(seg, src, seq_zero)) {
1108 			return seg;
1109 		}
1110 
1111 		if (!unassigned && !sys_slist_peek_head(&seg->queue)) {
1112 			unassigned = seg;
1113 		}
1114 	}
1115 
1116 	if (unassigned) {
1117 		unassigned->seg_count = seg_count;
1118 	}
1119 
1120 	return unassigned;
1121 }
1122 
enqueue_friend_pdu(struct bt_mesh_friend * frnd,enum bt_mesh_friend_pdu_type type,uint16_t src,uint8_t seg_count,struct net_buf * buf)1123 static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
1124 			       enum bt_mesh_friend_pdu_type type,
1125 			       uint16_t src, uint8_t seg_count,
1126 			       struct net_buf *buf)
1127 {
1128 	struct bt_mesh_friend_seg *seg;
1129 
1130 	LOG_DBG("type %u", type);
1131 
1132 	if (type == BT_MESH_FRIEND_PDU_SINGLE) {
1133 		enqueue_buf(frnd, buf);
1134 		return;
1135 	}
1136 
1137 	uint16_t seq_zero = (((buf->data[10] << 8 | buf->data[11]) >> 2) & TRANS_SEQ_ZERO_MASK);
1138 
1139 	seg = get_seg(frnd, src, seq_zero, seg_count);
1140 	if (!seg) {
1141 		LOG_ERR("No free friend segment RX contexts for 0x%04x", src);
1142 		net_buf_unref(buf);
1143 		return;
1144 	}
1145 
1146 	net_buf_slist_put(&seg->queue, buf);
1147 
1148 	if (type == BT_MESH_FRIEND_PDU_COMPLETE) {
1149 		sys_slist_merge_slist(&frnd->queue, &seg->queue);
1150 
1151 		frnd->queue_size += seg->seg_count;
1152 		seg->seg_count = 0U;
1153 	} else {
1154 		FRIEND_ADV(buf)->seg = true;
1155 	}
1156 }
1157 
buf_send_start(uint16_t duration,int err,void * user_data)1158 static void buf_send_start(uint16_t duration, int err, void *user_data)
1159 {
1160 	struct bt_mesh_friend *frnd = user_data;
1161 
1162 	LOG_DBG("err %d", err);
1163 
1164 	if (!frnd->pending_buf) {
1165 		LOG_WRN("Attempt of sending to removed friend");
1166 		return;
1167 	}
1168 
1169 	frnd->pending_buf = 0U;
1170 
1171 	/* Friend Offer doesn't follow the re-sending semantics */
1172 	if (!frnd->established && frnd->last) {
1173 		net_buf_unref(frnd->last);
1174 		frnd->last = NULL;
1175 	}
1176 }
1177 
buf_send_end(int err,void * user_data)1178 static void buf_send_end(int err, void *user_data)
1179 {
1180 	struct bt_mesh_friend *frnd = user_data;
1181 
1182 	LOG_DBG("err %d", err);
1183 
1184 	if (frnd->pending_req || frnd->pending_buf) {
1185 		LOG_WRN("Another request before previous completed sending");
1186 		return;
1187 	}
1188 
1189 	if (frnd->established) {
1190 		/* Always restart poll timeout timer after sending */
1191 		k_work_reschedule(&frnd->timer, K_MSEC(frnd->poll_to));
1192 		LOG_DBG("Waiting %u ms for next poll", frnd->poll_to);
1193 	} else {
1194 		/* Friend offer timeout is 1 second */
1195 		k_work_reschedule(&frnd->timer, K_SECONDS(1));
1196 		LOG_DBG("Waiting for first poll");
1197 	}
1198 }
1199 
update_overwrite(struct net_buf * buf,uint8_t md)1200 static void update_overwrite(struct net_buf *buf, uint8_t md)
1201 {
1202 	struct net_buf_simple_state state;
1203 	struct bt_mesh_ctl_friend_update *upd;
1204 
1205 	if (buf->len != 16) {
1206 		return;
1207 	}
1208 
1209 	net_buf_simple_save(&buf->b, &state);
1210 
1211 	net_buf_skip(buf, 1); /* skip IVI, NID */
1212 
1213 	if (!(net_buf_pull_u8(buf) >> 7)) {
1214 		goto end;
1215 	}
1216 
1217 	net_buf_skip(buf, 7); /* skip seqnum src dec*/
1218 
1219 	if (TRANS_CTL_OP((uint8_t *) net_buf_pull_mem(buf, 1))
1220 			!= TRANS_CTL_OP_FRIEND_UPDATE) {
1221 		goto end;
1222 	}
1223 
1224 	upd = net_buf_pull_mem(buf, sizeof(*upd));
1225 	LOG_DBG("Update Previous Friend Update MD 0x%02x -> 0x%02x", upd->md, md);
1226 	upd->md = md;
1227 
1228 end:
1229 	net_buf_simple_restore(&buf->b, &state);
1230 }
1231 
friend_timeout(struct k_work * work)1232 static void friend_timeout(struct k_work *work)
1233 {
1234 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1235 	struct bt_mesh_friend *frnd = CONTAINER_OF(dwork, struct bt_mesh_friend,
1236 						   timer);
1237 	static const struct bt_mesh_send_cb buf_sent_cb = {
1238 		.start = buf_send_start,
1239 		.end = buf_send_end,
1240 	};
1241 	struct bt_mesh_adv *adv;
1242 	uint8_t md;
1243 
1244 	if (!friend_is_allocated(frnd)) {
1245 		return;
1246 	}
1247 
1248 	__ASSERT_NO_MSG(frnd->pending_buf == 0U);
1249 
1250 	LOG_DBG("lpn 0x%04x send_last %u last %p", frnd->lpn, frnd->send_last, frnd->last);
1251 
1252 	if (frnd->send_last && frnd->last) {
1253 		LOG_DBG("Sending frnd->last %p", frnd->last);
1254 		frnd->send_last = 0U;
1255 		goto send_last;
1256 	}
1257 
1258 	if (frnd->established && !frnd->pending_req) {
1259 		LOG_WRN("Friendship lost with 0x%04x", frnd->lpn);
1260 		friend_clear(frnd);
1261 		return;
1262 	}
1263 
1264 	frnd->last = (void *)net_buf_slist_get(&frnd->queue);
1265 	if (!frnd->last) {
1266 		LOG_WRN("Friendship not established with 0x%04x", frnd->lpn);
1267 		friend_clear(frnd);
1268 		return;
1269 	}
1270 
1271 	md = (uint8_t)(sys_slist_peek_head(&frnd->queue) != NULL);
1272 
1273 	update_overwrite(frnd->last, md);
1274 
1275 	if (encrypt_friend_pdu(frnd, frnd->last, false)) {
1276 		return;
1277 	}
1278 
1279 	LOG_DBG("Sending buf %p from Friend Queue of LPN 0x%04x", frnd->last, frnd->lpn);
1280 	frnd->queue_size--;
1281 
1282 send_last:
1283 	adv = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_FRIEND,
1284 				 FRIEND_XMIT, K_NO_WAIT);
1285 	if (!adv) {
1286 		LOG_ERR("Unable to allocate friend adv");
1287 		return;
1288 	}
1289 
1290 	net_buf_simple_add_mem(&adv->b, frnd->last->data, frnd->last->len);
1291 
1292 	frnd->pending_req = 0U;
1293 	frnd->pending_buf = 1U;
1294 	bt_mesh_adv_send(adv, &buf_sent_cb, frnd);
1295 	bt_mesh_adv_unref(adv);
1296 }
1297 
subnet_evt(struct bt_mesh_subnet * sub,enum bt_mesh_key_evt evt)1298 static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt)
1299 {
1300 	int i, err;
1301 
1302 	if (evt == BT_MESH_KEY_ADDED) {
1303 		return;
1304 	}
1305 
1306 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
1307 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
1308 
1309 		if (frnd->subnet != sub) {
1310 			continue;
1311 		}
1312 
1313 		switch (evt) {
1314 		case BT_MESH_KEY_DELETED:
1315 			LOG_DBG("Cleared network for 0x%04x", frnd->lpn);
1316 			friend_clear(frnd);
1317 			break;
1318 		case BT_MESH_KEY_UPDATED:
1319 			LOG_DBG("Generating new keys for 0x%04x", frnd->lpn);
1320 			err = friend_cred_create(frnd, 1);
1321 			if (err) {
1322 				LOG_ERR("Failed updating friend cred for 0x%04x", frnd->lpn);
1323 				friend_clear(frnd);
1324 			}
1325 			break;
1326 		case BT_MESH_KEY_SWAPPED:
1327 			enqueue_update(frnd, 0);
1328 			break;
1329 		case BT_MESH_KEY_REVOKED:
1330 			LOG_DBG("Revoking old keys for 0x%04x", frnd->lpn);
1331 			bt_mesh_friend_cred_destroy(&frnd->cred[0]);
1332 			memcpy(&frnd->cred[0], &frnd->cred[1],
1333 			       sizeof(frnd->cred[0]));
1334 			memset(&frnd->cred[1], 0, sizeof(frnd->cred[1]));
1335 			enqueue_update(frnd, 0);
1336 			break;
1337 		default:
1338 			break;
1339 		}
1340 	}
1341 }
1342 
1343 BT_MESH_SUBNET_CB_DEFINE(friend) = {
1344 	.evt_handler = subnet_evt,
1345 };
1346 
bt_mesh_friend_init(void)1347 int bt_mesh_friend_init(void)
1348 {
1349 	int i;
1350 
1351 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
1352 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
1353 		int j;
1354 
1355 		sys_slist_init(&frnd->queue);
1356 
1357 		k_work_init_delayable(&frnd->timer, friend_timeout);
1358 		k_work_init_delayable(&frnd->clear.timer, clear_timeout);
1359 
1360 		for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) {
1361 			sys_slist_init(&frnd->seg[j].queue);
1362 		}
1363 	}
1364 
1365 	return 0;
1366 }
1367 
is_segack(struct net_buf * buf,const uint64_t * seqauth,uint16_t src)1368 static bool is_segack(struct net_buf *buf, const uint64_t *seqauth, uint16_t src)
1369 {
1370 	struct net_buf_simple_state state;
1371 	bool found = false;
1372 
1373 	if (buf->len != 16) {
1374 		return false;
1375 	}
1376 
1377 	net_buf_simple_save(&buf->b, &state);
1378 
1379 	net_buf_skip(buf, 1); /* skip IVI, NID */
1380 
1381 	if (!(net_buf_pull_u8(buf) >> 7)) {
1382 		goto end;
1383 	}
1384 
1385 	net_buf_pull(buf, 3); /* skip SEQNUM */
1386 
1387 	if (src != net_buf_pull_be16(buf)) {
1388 		goto end;
1389 	}
1390 
1391 	net_buf_skip(buf, 2); /* skip dst */
1392 
1393 	if (TRANS_CTL_OP((uint8_t *) net_buf_pull_mem(buf, 1)) != TRANS_CTL_OP_ACK) {
1394 		goto end;
1395 	}
1396 
1397 	found = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK) ==
1398 		(*seqauth & TRANS_SEQ_ZERO_MASK);
1399 end:
1400 	net_buf_simple_restore(&buf->b, &state);
1401 	return found;
1402 }
1403 
friend_purge_old_ack(struct bt_mesh_friend * frnd,const uint64_t * seq_auth,uint16_t src)1404 static void friend_purge_old_ack(struct bt_mesh_friend *frnd,
1405 				 const uint64_t *seq_auth, uint16_t src)
1406 {
1407 	sys_snode_t *cur, *prev = NULL;
1408 
1409 	LOG_DBG("SeqAuth %llx src 0x%04x", *seq_auth, src);
1410 
1411 	for (cur = sys_slist_peek_head(&frnd->queue);
1412 	     cur != NULL; prev = cur, cur = sys_slist_peek_next(cur)) {
1413 		struct net_buf *buf = (void *)cur;
1414 
1415 		if (is_segack(buf, seq_auth, src)) {
1416 			LOG_DBG("Removing old ack from Friend Queue");
1417 
1418 			sys_slist_remove(&frnd->queue, prev, cur);
1419 			frnd->queue_size--;
1420 
1421 			net_buf_unref(buf);
1422 			break;
1423 		}
1424 	}
1425 }
1426 
friend_lpn_enqueue_rx(struct bt_mesh_friend * frnd,struct bt_mesh_net_rx * rx,enum bt_mesh_friend_pdu_type type,const uint64_t * seq_auth,uint8_t seg_count,struct net_buf_simple * sbuf)1427 static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd,
1428 				  struct bt_mesh_net_rx *rx,
1429 				  enum bt_mesh_friend_pdu_type type,
1430 				  const uint64_t *seq_auth, uint8_t seg_count,
1431 				  struct net_buf_simple *sbuf)
1432 {
1433 	struct friend_pdu_info info;
1434 	struct net_buf *buf;
1435 
1436 	/* Because of network loopback, tx packets will also be passed into
1437 	 * this rx function. These packets have already been added to the
1438 	 * queue, and should be ignored.
1439 	 */
1440 	if (bt_mesh_has_addr(rx->ctx.addr)) {
1441 		return;
1442 	}
1443 
1444 	LOG_DBG("LPN 0x%04x queue_size %u", frnd->lpn, frnd->queue_size);
1445 
1446 	if (type == BT_MESH_FRIEND_PDU_SINGLE && seq_auth) {
1447 		friend_purge_old_ack(frnd, seq_auth, rx->ctx.addr);
1448 	}
1449 
1450 	info.src = rx->ctx.addr;
1451 	info.dst = rx->ctx.recv_dst;
1452 
1453 	if (rx->net_if == BT_MESH_NET_IF_LOCAL) {
1454 		info.ttl = rx->ctx.recv_ttl;
1455 	} else {
1456 		info.ttl = rx->ctx.recv_ttl - 1U;
1457 	}
1458 
1459 	info.ctl = rx->ctl;
1460 
1461 	sys_put_be24(rx->seq, info.seq);
1462 
1463 	info.iv_index = BT_MESH_NET_IVI_RX(rx);
1464 
1465 	buf = create_friend_pdu(frnd, &info, sbuf);
1466 	if (!buf) {
1467 		LOG_ERR("Failed to encode Friend buffer");
1468 		return;
1469 	}
1470 
1471 	enqueue_friend_pdu(frnd, type, info.src, seg_count, buf);
1472 
1473 	LOG_DBG("Queued message for LPN 0x%04x, queue_size %u", frnd->lpn, frnd->queue_size);
1474 }
1475 
friend_lpn_enqueue_tx(struct bt_mesh_friend * frnd,struct bt_mesh_net_tx * tx,enum bt_mesh_friend_pdu_type type,const uint64_t * seq_auth,uint8_t seg_count,struct net_buf_simple * sbuf)1476 static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd,
1477 				  struct bt_mesh_net_tx *tx,
1478 				  enum bt_mesh_friend_pdu_type type,
1479 				  const uint64_t *seq_auth, uint8_t seg_count,
1480 				  struct net_buf_simple *sbuf)
1481 {
1482 	struct friend_pdu_info info;
1483 	struct net_buf *buf;
1484 
1485 	LOG_DBG("LPN 0x%04x", frnd->lpn);
1486 
1487 	if (type == BT_MESH_FRIEND_PDU_SINGLE && seq_auth) {
1488 		friend_purge_old_ack(frnd, seq_auth, tx->src);
1489 	}
1490 
1491 	info.src = tx->src;
1492 	info.dst = tx->ctx->addr;
1493 
1494 	info.ttl = tx->ctx->send_ttl;
1495 	info.ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED);
1496 
1497 	sys_put_be24(bt_mesh.seq, info.seq);
1498 
1499 	info.iv_index = BT_MESH_NET_IVI_TX;
1500 
1501 	buf = create_friend_pdu(frnd, &info, sbuf);
1502 	if (!buf) {
1503 		LOG_ERR("Failed to encode Friend buffer");
1504 		return;
1505 	}
1506 
1507 	if (type == BT_MESH_FRIEND_PDU_SINGLE && !info.ctl) {
1508 		/* Unsegmented application packets may be reencrypted later,
1509 		 * as they depend on the sequence number being the same
1510 		 * when encrypting in transport and network.
1511 		 */
1512 		FRIEND_ADV(buf)->app_idx = tx->ctx->app_idx;
1513 
1514 		/* When reencrypting a virtual address message, we need to know uuid as well. */
1515 		if (BT_MESH_ADDR_IS_VIRTUAL(tx->ctx->addr)) {
1516 			uint16_t uuidx;
1517 			int err;
1518 
1519 			err = bt_mesh_va_get_idx_by_uuid(tx->ctx->uuid, &uuidx);
1520 			if (err) {
1521 				net_buf_unref(buf);
1522 				return;
1523 			}
1524 
1525 			FRIEND_ADV(buf)->uuidx = uuidx;
1526 		}
1527 	}
1528 
1529 	enqueue_friend_pdu(frnd, type, info.src, seg_count, buf);
1530 
1531 	LOG_DBG("Queued message for LPN 0x%04x, dst: %04x, uuid: %p", frnd->lpn, tx->ctx->addr,
1532 		tx->ctx->uuid);
1533 }
1534 
friend_lpn_matches(struct bt_mesh_friend * frnd,uint16_t net_idx,uint16_t addr)1535 static bool friend_lpn_matches(struct bt_mesh_friend *frnd, uint16_t net_idx,
1536 			       uint16_t addr)
1537 {
1538 	int i;
1539 
1540 	if (!frnd->established) {
1541 		return false;
1542 	}
1543 
1544 	if (net_idx != frnd->subnet->net_idx) {
1545 		return false;
1546 	}
1547 
1548 	if (BT_MESH_ADDR_IS_UNICAST(addr)) {
1549 		return is_lpn_unicast(frnd, addr);
1550 	}
1551 
1552 	for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) {
1553 		if (frnd->sub_list[i] == addr) {
1554 			return true;
1555 		}
1556 	}
1557 
1558 	return false;
1559 }
1560 
bt_mesh_friend_match(uint16_t net_idx,uint16_t addr)1561 bool bt_mesh_friend_match(uint16_t net_idx, uint16_t addr)
1562 {
1563 	int i;
1564 
1565 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
1566 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
1567 
1568 		if (friend_lpn_matches(frnd, net_idx, addr)) {
1569 			LOG_DBG("LPN 0x%04x matched address 0x%04x", frnd->lpn, addr);
1570 			return true;
1571 		}
1572 	}
1573 
1574 	LOG_DBG("No matching LPN for address 0x%04x", addr);
1575 
1576 	return false;
1577 }
1578 
friend_queue_has_space(struct bt_mesh_friend * frnd,uint16_t addr,const uint64_t * seq_auth,uint8_t seg_count)1579 static bool friend_queue_has_space(struct bt_mesh_friend *frnd, uint16_t addr,
1580 				   const uint64_t *seq_auth, uint8_t seg_count)
1581 {
1582 	uint32_t total = 0;
1583 	int i;
1584 
1585 	if (seg_count > CONFIG_BT_MESH_FRIEND_QUEUE_SIZE) {
1586 		return false;
1587 	}
1588 
1589 	for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
1590 		struct bt_mesh_friend_seg *seg = &frnd->seg[i];
1591 
1592 		if (seq_auth && is_seg(seg, addr, *seq_auth & TRANS_SEQ_ZERO_MASK)) {
1593 			/* If there's a segment queue for this message then the
1594 			 * space verification has already happened.
1595 			 */
1596 			return true;
1597 		}
1598 
1599 		total += seg->seg_count;
1600 	}
1601 
1602 	/* If currently pending segments combined with this segmented message
1603 	 * are more than the Friend Queue Size, then there's no space. This
1604 	 * is because we don't have a mechanism of aborting already pending
1605 	 * segmented messages to free up buffers.
1606 	 */
1607 	return (CONFIG_BT_MESH_FRIEND_QUEUE_SIZE - total) > seg_count;
1608 }
1609 
bt_mesh_friend_queue_has_space(uint16_t net_idx,uint16_t src,uint16_t dst,uint64_t * seq_auth,uint8_t seg_count)1610 bool bt_mesh_friend_queue_has_space(uint16_t net_idx, uint16_t src, uint16_t dst,
1611 				    uint64_t *seq_auth, uint8_t seg_count)
1612 {
1613 	bool someone_has_space = false, friend_match = false;
1614 	int i;
1615 
1616 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
1617 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
1618 
1619 		if (!friend_lpn_matches(frnd, net_idx, dst)) {
1620 			continue;
1621 		}
1622 
1623 		friend_match = true;
1624 
1625 		if (friend_queue_has_space(frnd, src, seq_auth, seg_count)) {
1626 			someone_has_space = true;
1627 		}
1628 	}
1629 
1630 	/* If there were no matched LPNs treat this as success, so the
1631 	 * transport layer can continue its work.
1632 	 */
1633 	if (!friend_match) {
1634 		return true;
1635 	}
1636 
1637 	/* From the transport layers perspective it's good enough that at
1638 	 * least one Friend Queue has space. If there were multiple Friend
1639 	 * matches then the destination must be a group address, in which
1640 	 * case e.g. segment acks are not sent.
1641 	 */
1642 	return someone_has_space;
1643 }
1644 
friend_queue_check_dup(struct bt_mesh_friend * frnd,uint32_t seq,uint16_t src)1645 static bool friend_queue_check_dup(struct bt_mesh_friend *frnd, uint32_t seq,
1646 				   uint16_t src)
1647 {
1648 	struct bt_mesh_net_rx rx;
1649 	sys_snode_t *cur;
1650 
1651 	for (cur = sys_slist_peek_head(&frnd->queue); cur != NULL;
1652 	     cur = sys_slist_peek_next(cur)) {
1653 		struct net_buf *buf = (void *)cur;
1654 
1655 		bt_mesh_net_header_parse(&buf->b, &rx);
1656 
1657 		if ((src == rx.ctx.addr) && (seq == rx.seq)) {
1658 			return true;
1659 		}
1660 	}
1661 
1662 	return false;
1663 }
1664 
friend_queue_prepare_space(struct bt_mesh_friend * frnd,uint16_t addr,const uint64_t * seq_auth,uint8_t seg_count)1665 static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t addr,
1666 				       const uint64_t *seq_auth, uint8_t seg_count)
1667 {
1668 	bool pending_segments;
1669 	uint8_t avail_space;
1670 
1671 	if (!friend_queue_has_space(frnd, addr, seq_auth, seg_count)) {
1672 		return false;
1673 	}
1674 
1675 	avail_space = CONFIG_BT_MESH_FRIEND_QUEUE_SIZE - frnd->queue_size;
1676 	pending_segments = false;
1677 
1678 	while (pending_segments || avail_space < seg_count) {
1679 		struct net_buf *buf = (void *)net_buf_slist_get(&frnd->queue);
1680 
1681 		if (!buf) {
1682 			LOG_ERR("Unable to free up enough buffers");
1683 			return false;
1684 		}
1685 
1686 		frnd->queue_size--;
1687 		avail_space++;
1688 
1689 		pending_segments = FRIEND_ADV(buf)->seg;
1690 
1691 		net_buf_unref(buf);
1692 	}
1693 
1694 	return true;
1695 }
1696 
bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx * rx,enum bt_mesh_friend_pdu_type type,const uint64_t * seq_auth,uint8_t seg_count,struct net_buf_simple * sbuf)1697 void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx,
1698 			       enum bt_mesh_friend_pdu_type type,
1699 			       const uint64_t *seq_auth, uint8_t seg_count,
1700 			       struct net_buf_simple *sbuf)
1701 {
1702 	int i;
1703 
1704 	if (!rx->friend_match ||
1705 	    (rx->ctx.recv_ttl <= 1U && rx->net_if != BT_MESH_NET_IF_LOCAL) ||
1706 	    bt_mesh_friend_get() != BT_MESH_FRIEND_ENABLED) {
1707 		return;
1708 	}
1709 
1710 	LOG_DBG("recv_ttl %u net_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.recv_ttl,
1711 		rx->sub->net_idx, rx->ctx.addr, rx->ctx.recv_dst);
1712 
1713 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
1714 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
1715 
1716 		if (!friend_lpn_matches(frnd, rx->sub->net_idx,
1717 					rx->ctx.recv_dst)) {
1718 			continue;
1719 		}
1720 
1721 		if (friend_lpn_matches(frnd, rx->sub->net_idx,
1722 					rx->ctx.addr)) {
1723 			continue;
1724 		}
1725 
1726 		if (friend_queue_check_dup(frnd, rx->seq, rx->ctx.addr)) {
1727 			continue;
1728 		}
1729 
1730 		if (!friend_queue_prepare_space(frnd, rx->ctx.addr, seq_auth,
1731 						seg_count)) {
1732 			continue;
1733 		}
1734 
1735 		friend_lpn_enqueue_rx(frnd, rx, type, seq_auth, seg_count,
1736 				      sbuf);
1737 	}
1738 }
1739 
bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx * tx,enum bt_mesh_friend_pdu_type type,const uint64_t * seq_auth,uint8_t seg_count,struct net_buf_simple * sbuf)1740 bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx,
1741 			       enum bt_mesh_friend_pdu_type type,
1742 			       const uint64_t *seq_auth, uint8_t seg_count,
1743 			       struct net_buf_simple *sbuf)
1744 {
1745 	bool matched = false;
1746 	int i;
1747 
1748 	if (!bt_mesh_friend_match(tx->sub->net_idx, tx->ctx->addr) ||
1749 	    bt_mesh_friend_get() != BT_MESH_FRIEND_ENABLED) {
1750 		return matched;
1751 	}
1752 
1753 	LOG_DBG("net_idx 0x%04x dst 0x%04x src 0x%04x", tx->sub->net_idx, tx->ctx->addr, tx->src);
1754 
1755 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
1756 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
1757 
1758 		if (!friend_lpn_matches(frnd, tx->sub->net_idx,
1759 					tx->ctx->addr)) {
1760 			continue;
1761 		}
1762 
1763 		if (!friend_queue_prepare_space(frnd, tx->src, seq_auth,
1764 						seg_count)) {
1765 			continue;
1766 		}
1767 
1768 		friend_lpn_enqueue_tx(frnd, tx, type, seq_auth, seg_count,
1769 				      sbuf);
1770 		matched = true;
1771 	}
1772 
1773 	return matched;
1774 }
1775 
bt_mesh_friend_terminate(uint16_t lpn_addr)1776 int bt_mesh_friend_terminate(uint16_t lpn_addr)
1777 {
1778 	struct bt_mesh_friend *frnd;
1779 
1780 	frnd = bt_mesh_friend_find(BT_MESH_KEY_ANY, lpn_addr, false, false);
1781 	if (!frnd) {
1782 		return -ENOENT;
1783 	}
1784 
1785 	friend_clear(frnd);
1786 
1787 	return 0;
1788 }
1789 
bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet * sub,uint16_t src,uint16_t dst,uint64_t * seq_auth)1790 void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, uint16_t src,
1791 				     uint16_t dst, uint64_t *seq_auth)
1792 {
1793 	int i;
1794 
1795 	LOG_DBG("");
1796 
1797 	for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
1798 		struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
1799 		int j;
1800 
1801 		if (!friend_lpn_matches(frnd, sub->net_idx, dst)) {
1802 			continue;
1803 		}
1804 
1805 		for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) {
1806 			struct bt_mesh_friend_seg *seg = &frnd->seg[j];
1807 
1808 			if (!is_seg(seg, src, *seq_auth & TRANS_SEQ_ZERO_MASK)) {
1809 				continue;
1810 			}
1811 
1812 			LOG_WRN("Clearing incomplete segments for 0x%04x", src);
1813 
1814 			purge_buffers(&seg->queue);
1815 			seg->seg_count = 0U;
1816 			break;
1817 		}
1818 	}
1819 }
1820