1 /*
2  * Copyright (c) 2021 Nordic Semiconductor
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "mesh_test.h"
7 #include "mesh/net.h"
8 #include "mesh/transport.h"
9 #include <sys/byteorder.h>
10 #include "argparse.h"
11 
12 #define LOG_MODULE_NAME test_friendship
13 
14 #include <logging/log.h>
15 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
16 
17 /*
18  * Friendship tests:
19  *   Tests both the friend and the low power role in various scenarios.
20  */
21 
22 #define GROUP_ADDR 0xc000
23 #define WAIT_TIME 60 /*seconds*/
24 #define LPN_ADDR_START 0x0003
25 #define POLL_TIMEOUT_MS (100 * CONFIG_BT_MESH_LPN_POLL_TIMEOUT)
26 
27 extern enum bst_result_t bst_result;
28 
29 enum test_flags {
30 	LPN_ESTABLISHED,
31 	LPN_TERMINATED,
32 	LPN_POLLED,
33 	FRIEND_ESTABLISHED,
34 	FRIEND_TERMINATED,
35 	FRIEND_POLLED,
36 
37 	TEST_FLAGS,
38 };
39 
40 static ATOMIC_DEFINE(state, TEST_FLAGS);
41 static struct k_sem events[TEST_FLAGS];
42 
43 static const struct bt_mesh_test_cfg friend_cfg = {
44 	.addr = 0x0001,
45 	.dev_key = { 0x01 },
46 };
47 static const struct bt_mesh_test_cfg other_cfg = {
48 	.addr = 0x0002,
49 	.dev_key = { 0x02 },
50 };
51 static struct bt_mesh_test_cfg lpn_cfg;
52 static uint16_t friend_lpn_addr;
53 
test_common_init(const struct bt_mesh_test_cfg * cfg)54 static void test_common_init(const struct bt_mesh_test_cfg *cfg)
55 {
56 	for (int i = 0; i < ARRAY_SIZE(events); i++) {
57 		k_sem_init(&events[i], 0, 1);
58 	}
59 
60 	bt_mesh_test_cfg_set(cfg, WAIT_TIME);
61 }
62 
test_friend_init(void)63 static void test_friend_init(void)
64 {
65 	test_common_init(&friend_cfg);
66 }
67 
test_lpn_init(void)68 static void test_lpn_init(void)
69 {
70 	/* As there may be multiple LPN devices, we'll set the address and
71 	 * devkey based on the device number, which is guaranteed to be unique
72 	 * for each device in the simulation.
73 	 */
74 	lpn_cfg.addr = LPN_ADDR_START + get_device_nbr();
75 	lpn_cfg.dev_key[0] = get_device_nbr();
76 	test_common_init(&lpn_cfg);
77 }
78 
test_other_init(void)79 static void test_other_init(void)
80 {
81 	test_common_init(&other_cfg);
82 }
83 
evt_signal(enum test_flags evt)84 static void evt_signal(enum test_flags evt)
85 {
86 	atomic_set_bit(state, evt);
87 	k_sem_give(&events[evt]);
88 }
89 
evt_wait(enum test_flags evt,k_timeout_t timeout)90 static int evt_wait(enum test_flags evt, k_timeout_t timeout)
91 {
92 	return k_sem_take(&events[evt], timeout);
93 }
94 
evt_clear(enum test_flags evt)95 static void evt_clear(enum test_flags evt)
96 {
97 	atomic_clear_bit(state, evt);
98 	k_sem_reset(&events[evt]);
99 }
100 
friend_established(uint16_t net_idx,uint16_t lpn_addr,uint8_t recv_delay,uint32_t polltimeout)101 static void friend_established(uint16_t net_idx, uint16_t lpn_addr,
102 			    uint8_t recv_delay, uint32_t polltimeout)
103 {
104 	LOG_INF("Friend: established with 0x%04x", lpn_addr);
105 	friend_lpn_addr = lpn_addr;
106 	evt_signal(FRIEND_ESTABLISHED);
107 }
108 
friend_terminated(uint16_t net_idx,uint16_t lpn_addr)109 static void friend_terminated(uint16_t net_idx, uint16_t lpn_addr)
110 {
111 	LOG_INF("Friend: terminated with 0x%04x", lpn_addr);
112 	evt_signal(FRIEND_TERMINATED);
113 }
114 
friend_polled(uint16_t net_idx,uint16_t lpn_addr)115 static void friend_polled(uint16_t net_idx, uint16_t lpn_addr)
116 {
117 	LOG_INF("Friend: Poll from 0x%04x", lpn_addr);
118 	evt_signal(FRIEND_POLLED);
119 }
120 
121 BT_MESH_FRIEND_CB_DEFINE(friend) = {
122 	.established = friend_established,
123 	.terminated = friend_terminated,
124 	.polled = friend_polled,
125 };
126 
lpn_established(uint16_t net_idx,uint16_t friend_addr,uint8_t queue_size,uint8_t recv_window)127 static void lpn_established(uint16_t net_idx, uint16_t friend_addr,
128 			    uint8_t queue_size, uint8_t recv_window)
129 {
130 	LOG_INF("LPN: established with 0x%04x", friend_addr);
131 	evt_signal(LPN_ESTABLISHED);
132 }
133 
lpn_terminated(uint16_t net_idx,uint16_t friend_addr)134 static void lpn_terminated(uint16_t net_idx, uint16_t friend_addr)
135 {
136 	LOG_INF("LPN: terminated with 0x%04x", friend_addr);
137 	evt_signal(LPN_TERMINATED);
138 }
139 
lpn_polled(uint16_t net_idx,uint16_t friend_addr,bool retry)140 static void lpn_polled(uint16_t net_idx, uint16_t friend_addr, bool retry)
141 {
142 	LOG_INF("LPN: Polling 0x%04x (%s)", friend_addr,
143 		retry ? "retry" : "initial");
144 	evt_signal(LPN_POLLED);
145 }
146 
147 BT_MESH_LPN_CB_DEFINE(lpn) = {
148 	.established = lpn_established,
149 	.polled = lpn_polled,
150 	.terminated = lpn_terminated,
151 };
152 
friend_wait_for_polls(int polls)153 static void friend_wait_for_polls(int polls)
154 {
155 	/* Let LPN poll to get the sent message */
156 	ASSERT_OK(evt_wait(FRIEND_POLLED, K_SECONDS(30)), "LPN never polled");
157 
158 	while (--polls) {
159 		/* Wait for LPN to poll until the "no more data" message.
160 		 * At this point, the message has been delivered.
161 		 */
162 		ASSERT_OK(evt_wait(FRIEND_POLLED, K_SECONDS(2)),
163 			  "LPN missing %d polls", polls);
164 	}
165 
166 	if (evt_wait(FRIEND_POLLED, K_SECONDS(2)) != -EAGAIN) {
167 		FAIL("Unexpected extra poll");
168 		return;
169 	}
170 }
171 
172 /* Friend test functions */
173 
174 /** Initialize as a friend and wait for the friendship to be established.
175  */
test_friend_est(void)176 static void test_friend_est(void)
177 {
178 	bt_mesh_test_setup();
179 
180 	bt_mesh_friend_set(BT_MESH_FEATURE_ENABLED);
181 
182 	ASSERT_OK(evt_wait(FRIEND_ESTABLISHED, K_SECONDS(5)),
183 		  "Friendship not established");
184 
185 	PASS();
186 }
187 
188 /** Initialize as a friend, and wait for multiple friendships to be established
189  *  concurrently.
190  *
191  *  Verify that all friendships survive the first poll timeout.
192  */
test_friend_est_multi(void)193 static void test_friend_est_multi(void)
194 {
195 	int err;
196 
197 	bt_mesh_test_setup();
198 
199 	k_sem_init(&events[FRIEND_ESTABLISHED], 0,
200 		   CONFIG_BT_MESH_FRIEND_LPN_COUNT);
201 
202 	bt_mesh_friend_set(BT_MESH_FEATURE_ENABLED);
203 
204 	for (int i = 0; i < CONFIG_BT_MESH_FRIEND_LPN_COUNT; i++) {
205 		ASSERT_OK(evt_wait(FRIEND_ESTABLISHED, K_SECONDS(5)),
206 			  "Friendship %d not established", i);
207 	}
208 
209 	/* Wait for all friends to do at least one poll without terminating */
210 	err = evt_wait(FRIEND_TERMINATED,
211 		       K_MSEC(POLL_TIMEOUT_MS + 5 * MSEC_PER_SEC));
212 	if (!err) {
213 		FAIL("One or more friendships terminated");
214 	}
215 
216 	PASS();
217 }
218 
219 /** As a friend, send messages to the LPN.
220  *
221  *  Verifies unsegmented, segmented and multiple packet sending and receiving.
222  */
test_friend_msg(void)223 static void test_friend_msg(void)
224 {
225 	bt_mesh_test_setup();
226 
227 	bt_mesh_friend_set(BT_MESH_FEATURE_ENABLED);
228 
229 	ASSERT_OK(evt_wait(FRIEND_ESTABLISHED, K_SECONDS(5)),
230 		  "Friendship not established");
231 	/* LPN polls on establishment. Clear the poll state */
232 	evt_clear(FRIEND_POLLED);
233 
234 	k_sleep(K_SECONDS(1));
235 
236 	/* Send unsegmented message from friend to LPN: */
237 	LOG_INF("Sending unsegmented message");
238 	ASSERT_OK(bt_mesh_test_send(friend_lpn_addr, 5, 0, K_SECONDS(1)),
239 		  "Unseg send failed");
240 
241 	/* Wait for LPN to poll for message and the "no more messages" msg */
242 	friend_wait_for_polls(2);
243 
244 	/* Send segmented message */
245 	ASSERT_OK(bt_mesh_test_send(friend_lpn_addr, 13, 0, K_SECONDS(1)),
246 		  "Unseg send failed");
247 
248 	/* Two segments require 2 polls plus the "no more messages" msg */
249 	friend_wait_for_polls(3);
250 
251 	/* Send two unsegmented messages before the next poll.
252 	 * This tests the friend role's re-encryption mechanism for the second
253 	 * message, as sending the first message through the network layer
254 	 * increases the seqnum by one, creating an inconsistency between the
255 	 * transport and network parts of the second packet.
256 	 * Ensures coverage for the regression reported in #32033.
257 	 */
258 	ASSERT_OK(bt_mesh_test_send(friend_lpn_addr, BT_MESH_SDU_UNSEG_MAX, 0, K_SECONDS(1)),
259 		  "Unseg send failed");
260 	ASSERT_OK(bt_mesh_test_send(friend_lpn_addr, BT_MESH_SDU_UNSEG_MAX, 0, K_SECONDS(1)),
261 		  "Unseg send failed");
262 
263 	/* Two messages require 2 polls plus the "no more messages" msg */
264 	friend_wait_for_polls(3);
265 
266 	ASSERT_OK(bt_mesh_test_recv(5, cfg->addr, K_SECONDS(10)),
267 		  "Receive from LPN failed");
268 
269 	/* Receive a segmented message from the LPN. LPN should poll for the ack
270 	 * after sending the segments.
271 	 */
272 	ASSERT_OK(bt_mesh_test_recv(15, cfg->addr, K_SECONDS(10)),
273 		  "Receive from LPN failed");
274 	friend_wait_for_polls(2);
275 
276 	PASS();
277 }
278 
279 /** As a friend, overflow the message queue for the LPN with own packets.
280  *
281  *  Verify that the LPN doesn't terminate the friendship during the poll for
282  *  messages.
283  */
test_friend_overflow(void)284 static void test_friend_overflow(void)
285 {
286 	bt_mesh_test_setup();
287 
288 	bt_mesh_friend_set(BT_MESH_FEATURE_ENABLED);
289 
290 	ASSERT_OK(evt_wait(FRIEND_ESTABLISHED, K_SECONDS(5)),
291 		  "Friendship not established");
292 	evt_clear(FRIEND_POLLED);
293 
294 	k_sleep(K_SECONDS(3));
295 
296 	/* Fill the queue */
297 	for (int i = 0; i < CONFIG_BT_MESH_FRIEND_QUEUE_SIZE; i++) {
298 		bt_mesh_test_send(friend_lpn_addr, 5, 0, K_NO_WAIT);
299 	}
300 
301 	/* Add one more message, which should overflow the queue and cause the
302 	 * first message to be discarded.
303 	 */
304 	bt_mesh_test_send(friend_lpn_addr, 5, 0, K_NO_WAIT);
305 
306 	ASSERT_OK(evt_wait(FRIEND_POLLED, K_SECONDS(35)),
307 		  "Friend never polled");
308 
309 	if (atomic_test_bit(state, FRIEND_TERMINATED)) {
310 		FAIL("Friendship terminated unexpectedly");
311 	}
312 
313 	PASS();
314 }
315 
316 /** Establish a friendship, wait for communication between the LPN and a mesh
317  *  device to finish, then send group and virtual addr messages to the LPN.
318  *  Let the LPN add another group message, then send to that as well.
319  */
test_friend_group(void)320 static void test_friend_group(void)
321 {
322 	uint16_t virtual_addr;
323 
324 	bt_mesh_test_setup();
325 
326 	bt_mesh_friend_set(BT_MESH_FEATURE_ENABLED);
327 
328 	ASSERT_OK(evt_wait(FRIEND_ESTABLISHED, K_SECONDS(5)),
329 		  "Friendship not established");
330 	evt_clear(FRIEND_POLLED);
331 
332 	ASSERT_OK(bt_mesh_va_add(test_va_uuid, &virtual_addr));
333 
334 	/* The other mesh device will send its messages in the first poll */
335 	ASSERT_OK(evt_wait(FRIEND_POLLED, K_SECONDS(10)));
336 
337 	k_sleep(K_SECONDS(2));
338 
339 	evt_clear(FRIEND_POLLED);
340 
341 	/* Send a group message to the LPN */
342 	ASSERT_OK(bt_mesh_test_send(GROUP_ADDR, 5, 0, K_SECONDS(1)),
343 		  "Failed to send to LPN");
344 	/* Send a virtual message to the LPN */
345 	ASSERT_OK(bt_mesh_test_send(virtual_addr, 5, 0, K_SECONDS(1)),
346 		  "Failed to send to LPN");
347 
348 	/* Wait for the LPN to poll for each message, then for adding the
349 	 * group address:
350 	 */
351 	friend_wait_for_polls(3);
352 
353 	/* Send a group message to an address the LPN added after the friendship
354 	 * was established.
355 	 */
356 	ASSERT_OK(bt_mesh_test_send(GROUP_ADDR + 1, 5, 0, K_SECONDS(1)),
357 		  "Failed to send to LPN");
358 
359 	evt_wait(FRIEND_POLLED, K_SECONDS(10));
360 
361 	PASS();
362 }
363 
364 /* LPN test functions */
365 
366 /** Enable the LPN role, and verify that the friendship is established.
367  *
368  *  Verify that the friendship survives the first poll timeout.
369  */
test_lpn_est(void)370 static void test_lpn_est(void)
371 {
372 	bt_mesh_test_setup();
373 
374 	bt_mesh_lpn_set(true);
375 
376 	ASSERT_OK(evt_wait(LPN_ESTABLISHED, K_SECONDS(5)),
377 		  "LPN not established");
378 	if (!evt_wait(LPN_TERMINATED,
379 		      K_MSEC(POLL_TIMEOUT_MS + 5 * MSEC_PER_SEC))) {
380 		FAIL("Friendship terminated unexpectedly");
381 	}
382 
383 	PASS();
384 }
385 
386 /** As an LPN, exchange messages with the friend node.
387  *
388  *  Verifies sending and receiving of unsegmented, segmented and multiple
389  *  messages to and from the connected friend node.
390  */
test_lpn_msg_frnd(void)391 static void test_lpn_msg_frnd(void)
392 {
393 	bt_mesh_test_setup();
394 
395 	bt_mesh_lpn_set(true);
396 
397 	ASSERT_OK(evt_wait(LPN_ESTABLISHED, K_SECONDS(5)),
398 		  "LPN not established");
399 	/* LPN polls on establishment. Clear the poll state */
400 	evt_clear(LPN_POLLED);
401 
402 	/* Give friend time to prepare the message */
403 	k_sleep(K_SECONDS(3));
404 
405 	/* Receive unsegmented message */
406 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
407 	ASSERT_OK(bt_mesh_test_recv(5, cfg->addr, K_SECONDS(1)),
408 		  "Failed to receive message");
409 
410 	/* Give friend time to prepare the message */
411 	k_sleep(K_SECONDS(3));
412 
413 	/* Receive segmented message */
414 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
415 	ASSERT_OK(bt_mesh_test_recv(13, cfg->addr, K_SECONDS(2)),
416 		  "Failed to receive message");
417 
418 	/* Give friend time to prepare the messages */
419 	k_sleep(K_SECONDS(3));
420 
421 	/* Receive two unsegmented messages */
422 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
423 	ASSERT_OK(bt_mesh_test_recv(BT_MESH_SDU_UNSEG_MAX, cfg->addr, K_SECONDS(2)),
424 		  "Failed to receive message");
425 	ASSERT_OK(bt_mesh_test_recv(BT_MESH_SDU_UNSEG_MAX, cfg->addr, K_SECONDS(2)),
426 		  "Failed to receive message");
427 
428 	k_sleep(K_SECONDS(3));
429 
430 	/* Send an unsegmented message to the friend.
431 	 * Should not be affected by the LPN mode at all.
432 	 */
433 	ASSERT_OK(bt_mesh_test_send(friend_cfg.addr, 5, 0, K_MSEC(500)),
434 		  "Send to friend failed");
435 
436 	k_sleep(K_SECONDS(5));
437 
438 	/* Send a segmented message to the friend. Should trigger a poll for the
439 	 * ack.
440 	 */
441 	ASSERT_OK(bt_mesh_test_send(friend_cfg.addr, 15, 0, K_SECONDS(5)),
442 		  "Send to friend failed");
443 
444 	PASS();
445 }
446 
447 /** As an LPN, exchange messages with a third party mesh node while in a
448  *  friendship.
449  *
450  *  Verifies sending and receiving of unsegmented and segmented messages to and
451  *  from the third party node.
452  */
test_lpn_msg_mesh(void)453 static void test_lpn_msg_mesh(void)
454 {
455 	bt_mesh_test_setup();
456 
457 	bt_mesh_lpn_set(true);
458 
459 	ASSERT_OK(evt_wait(LPN_ESTABLISHED, K_SECONDS(2)),
460 		  "LPN not established");
461 	/* LPN polls on establishment. Clear the poll state */
462 	evt_clear(LPN_POLLED);
463 
464 	/* Send an unsegmented message to a third mesh node.
465 	 * Should not be affected by the LPN mode at all.
466 	 */
467 	ASSERT_OK(bt_mesh_test_send(other_cfg.addr, 5, 0, K_MSEC(500)),
468 		  "Send to mesh failed");
469 
470 	/* Receive an unsegmented message back */
471 	k_sleep(K_SECONDS(1));
472 	ASSERT_OK(bt_mesh_lpn_poll());
473 	ASSERT_OK(bt_mesh_test_recv(5, cfg->addr, K_SECONDS(2)));
474 
475 	k_sleep(K_SECONDS(1));
476 
477 	/* Send a segmented message to the mesh node.
478 	 * Should trigger a poll for the ack.
479 	 */
480 	ASSERT_OK(bt_mesh_test_send(other_cfg.addr, 15, 0, K_SECONDS(5)),
481 		  "Send to other failed");
482 
483 	/* Receive a segmented message back */
484 	k_sleep(K_SECONDS(1));
485 	ASSERT_OK(bt_mesh_lpn_poll());
486 	ASSERT_OK(bt_mesh_test_recv(15, cfg->addr, K_SECONDS(5)));
487 
488 	/* Send an unsegmented message with friend credentials to a third mesh
489 	 * node. The friend shall relay it.
490 	 */
491 	test_model->pub->addr = other_cfg.addr;
492 	test_model->pub->cred = true; /* Use friend credentials */
493 	test_model->pub->ttl = BT_MESH_TTL_DEFAULT;
494 
495 	net_buf_simple_reset(test_model->pub->msg);
496 	bt_mesh_model_msg_init(test_model->pub->msg, TEST_MSG_OP_1);
497 	ASSERT_OK(bt_mesh_model_publish(test_model));
498 
499 	PASS();
500 }
501 
502 /** As an LPN, establish and terminate a friendship with the same friend
503  *  multiple times in a row to ensure that both parties are able to recover.
504  */
test_lpn_re_est(void)505 static void test_lpn_re_est(void)
506 {
507 	bt_mesh_test_setup();
508 
509 	for (int i = 0; i < 4; i++) {
510 		bt_mesh_lpn_set(true);
511 		ASSERT_OK(evt_wait(LPN_ESTABLISHED, K_SECONDS(2)),
512 			"LPN not established");
513 
514 		bt_mesh_lpn_set(false);
515 		ASSERT_OK(evt_wait(LPN_TERMINATED, K_SECONDS(5)),
516 			"LPN never terminated friendship");
517 
518 		k_sleep(K_SECONDS(2));
519 	}
520 
521 	PASS();
522 }
523 
524 /** Establish a friendship as an LPN, and verify that the friendship survives
525  *  the first poll timeout without terminating
526  */
test_lpn_poll(void)527 static void test_lpn_poll(void)
528 {
529 	bt_mesh_test_setup();
530 
531 	bt_mesh_lpn_set(true);
532 	ASSERT_OK(evt_wait(LPN_ESTABLISHED, K_SECONDS(5)),
533 		  "LPN not established");
534 	evt_clear(LPN_POLLED);
535 
536 	ASSERT_OK(evt_wait(LPN_POLLED, K_MSEC(POLL_TIMEOUT_MS)),
537 		  "LPN failed to poll before the timeout");
538 
539 	k_sleep(K_SECONDS(10));
540 	if (atomic_test_bit(state, LPN_TERMINATED)) {
541 		FAIL("LPN terminated.");
542 	}
543 
544 	PASS();
545 }
546 
547 /** Receive packets from a friend that overflowed its queue. Verify that the
548  *  first packet is discarded because of the overflow.
549  */
test_lpn_overflow(void)550 static void test_lpn_overflow(void)
551 {
552 	struct bt_mesh_test_msg msg;
553 	int err;
554 
555 	bt_mesh_test_setup();
556 
557 	bt_mesh_lpn_set(true);
558 	ASSERT_OK(evt_wait(LPN_ESTABLISHED, K_SECONDS(5)),
559 		  "LPN not established");
560 	evt_clear(LPN_POLLED);
561 
562 	k_sleep(K_SECONDS(5));
563 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
564 
565 	for (int i = 0; i < CONFIG_BT_MESH_FRIEND_QUEUE_SIZE; i++) {
566 		ASSERT_OK(bt_mesh_test_recv_msg(&msg, K_SECONDS(2)),
567 			  "Receive %d failed", i);
568 
569 		if (msg.len != 5) {
570 			FAIL("Message %d: Invalid length %d", i, msg.len);
571 		}
572 
573 		if (msg.ctx.recv_dst != cfg->addr) {
574 			FAIL("Message %d: Invalid dst 0x%04x", i,
575 			     msg.ctx.recv_dst);
576 		}
577 
578 		/* The first message (with seq=1) should have been discarded by
579 		 * the friend, so the first message should have seq=2:
580 		 */
581 		if (msg.seq != i + 2) {
582 			FAIL("Message %d: Invalid seq 0x%02x", i, msg.seq);
583 		}
584 	}
585 
586 	/* Not expecting any more messages from friend */
587 	err = bt_mesh_test_recv_msg(&msg, K_SECONDS(10));
588 	if (!err) {
589 		FAIL("Unexpected additional message 0x%02x from 0x%04x",
590 		     msg.seq, msg.ctx.addr);
591 	}
592 
593 	PASS();
594 }
595 
596 /** As an LPN, receive packets on group and virtual addresses from mesh device
597  *  and friend. Then, add a second group address (while the friendship is
598  *  established), and receive on that as well.
599  */
test_lpn_group(void)600 static void test_lpn_group(void)
601 {
602 	struct bt_mesh_test_msg msg;
603 	uint16_t vaddr;
604 	uint8_t status = 0;
605 	int err;
606 
607 	bt_mesh_test_setup();
608 
609 	err = bt_mesh_cfg_mod_sub_add(0, cfg->addr, cfg->addr, GROUP_ADDR,
610 				      TEST_MOD_ID, &status);
611 	if (err || status) {
612 		FAIL("Group addr add failed with err %d status 0x%x", err,
613 		     status);
614 	}
615 
616 	err = bt_mesh_cfg_mod_sub_va_add(0, cfg->addr, cfg->addr, test_va_uuid,
617 					 TEST_MOD_ID, &vaddr, &status);
618 	if (err || status) {
619 		FAIL("VA addr add failed with err %d status 0x%x", err, status);
620 	}
621 
622 	bt_mesh_lpn_set(true);
623 	ASSERT_OK(evt_wait(LPN_ESTABLISHED, K_SECONDS(5)),
624 		  "LPN not established");
625 	evt_clear(LPN_POLLED);
626 
627 	/* Send a message to the other mesh device to indicate that the
628 	 * friendship has been established. Give the other device a time to
629 	 * start up first.
630 	 */
631 	k_sleep(K_MSEC(10));
632 	ASSERT_OK(bt_mesh_test_send(other_cfg.addr, 5, 0, K_SECONDS(1)));
633 
634 	k_sleep(K_SECONDS(5));
635 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
636 
637 	/* From other device */
638 	ASSERT_OK(bt_mesh_test_recv_msg(&msg, K_SECONDS(1)));
639 	if (msg.ctx.recv_dst != GROUP_ADDR || msg.ctx.addr != other_cfg.addr) {
640 		FAIL("Unexpected message: 0x%04x -> 0x%04x", msg.ctx.addr,
641 		     msg.ctx.recv_dst);
642 	}
643 
644 	ASSERT_OK(bt_mesh_test_recv_msg(&msg, K_SECONDS(1)));
645 	if (msg.ctx.recv_dst != vaddr || msg.ctx.addr != other_cfg.addr) {
646 		FAIL("Unexpected message: 0x%04x -> 0x%04x", msg.ctx.addr,
647 		     msg.ctx.recv_dst);
648 	}
649 
650 	k_sleep(K_SECONDS(5));
651 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
652 
653 	/* From friend */
654 	ASSERT_OK(bt_mesh_test_recv_msg(&msg, K_SECONDS(1)));
655 	if (msg.ctx.recv_dst != GROUP_ADDR || msg.ctx.addr != friend_cfg.addr) {
656 		FAIL("Unexpected message: 0x%04x -> 0x%04x", msg.ctx.addr,
657 		     msg.ctx.recv_dst);
658 	}
659 
660 	ASSERT_OK(bt_mesh_test_recv_msg(&msg, K_SECONDS(1)));
661 	if (msg.ctx.recv_dst != vaddr || msg.ctx.addr != friend_cfg.addr) {
662 		FAIL("Unexpected message: 0x%04x -> 0x%04x", msg.ctx.addr,
663 		     msg.ctx.recv_dst);
664 	}
665 
666 	k_sleep(K_SECONDS(1));
667 
668 	LOG_INF("Adding second group addr");
669 
670 	/* Add a new group addr, then receive on it to ensure that the friend
671 	 * has added it to the subscription list.
672 	 */
673 	err = bt_mesh_cfg_mod_sub_add(0, cfg->addr, cfg->addr, GROUP_ADDR + 1,
674 				      TEST_MOD_ID, &status);
675 	if (err || status) {
676 		FAIL("Group addr add failed with err %d status 0x%x", err,
677 		     status);
678 	}
679 
680 	k_sleep(K_SECONDS(5));
681 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
682 
683 	/* From friend on second group address */
684 	ASSERT_OK(bt_mesh_test_recv_msg(&msg, K_SECONDS(1)));
685 	if (msg.ctx.recv_dst != GROUP_ADDR + 1 ||
686 	    msg.ctx.addr != friend_cfg.addr) {
687 		FAIL("Unexpected message: 0x%04x -> 0x%04x", msg.ctx.addr,
688 		     msg.ctx.recv_dst);
689 	}
690 
691 	PASS();
692 }
693 
694 /** As an LPN, send packets to own address to ensure that this is handled by
695  *  loopback mechanism, and ignored by friend.
696  *
697  *  Adds test coverage for regression in #30657.
698  */
test_lpn_loopback(void)699 static void test_lpn_loopback(void)
700 {
701 	struct bt_mesh_test_msg msg;
702 	uint16_t vaddr;
703 	uint8_t status = 0;
704 	int err;
705 
706 	bt_mesh_test_setup();
707 
708 	err = bt_mesh_cfg_mod_sub_add(0, cfg->addr, cfg->addr, GROUP_ADDR,
709 				      TEST_MOD_ID, &status);
710 	if (err || status) {
711 		FAIL("Group addr add failed with err %d status 0x%x", err,
712 		     status);
713 	}
714 
715 	err = bt_mesh_cfg_mod_sub_va_add(0, cfg->addr, cfg->addr, test_va_uuid,
716 					 TEST_MOD_ID, &vaddr, &status);
717 	if (err || status) {
718 		FAIL("VA addr add failed with err %d status 0x%x", err, status);
719 	}
720 
721 	bt_mesh_lpn_set(true);
722 	ASSERT_OK(evt_wait(LPN_ESTABLISHED, K_SECONDS(5)),
723 		  "LPN not established");
724 	evt_clear(LPN_POLLED);
725 
726 	k_sleep(K_SECONDS(1));
727 
728 	/* Loopback on unicast, shouldn't even leave the device */
729 	ASSERT_OK(bt_mesh_test_send_async(cfg->addr, 5, 0, NULL, NULL));
730 	ASSERT_OK(bt_mesh_test_recv(5, cfg->addr, K_SECONDS(1)));
731 
732 	/* Loopback on group address, should not come back from the friend */
733 	ASSERT_OK(bt_mesh_test_send_async(GROUP_ADDR, 5, 0, NULL, NULL));
734 	ASSERT_OK(bt_mesh_test_recv(5, GROUP_ADDR, K_SECONDS(1)));
735 
736 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
737 	err = bt_mesh_test_recv_msg(&msg, K_SECONDS(2));
738 	if (err != -ETIMEDOUT) {
739 		FAIL("Unexpected receive status: %d", err);
740 	}
741 
742 	/* Loopback on virtual address, should not come back from the friend */
743 	ASSERT_OK(bt_mesh_test_send_async(vaddr, 5, 0, NULL, NULL));
744 	ASSERT_OK(bt_mesh_test_recv(5, vaddr, K_SECONDS(1)));
745 
746 	k_sleep(K_SECONDS(2));
747 
748 	/* Poll the friend and make sure we don't receive any messages: */
749 	ASSERT_OK(bt_mesh_lpn_poll(), "Poll failed");
750 	err = bt_mesh_test_recv_msg(&msg, K_SECONDS(5));
751 	if (err != -ETIMEDOUT) {
752 		FAIL("Unexpected receive status: %d", err);
753 	}
754 
755 	PASS();
756 }
757 
758 /* Mesh device test functions */
759 
760 /** Without engaging in a friendship, communicate with an LPN through a friend
761  *  node.
762  */
test_other_msg(void)763 static void test_other_msg(void)
764 {
765 	bt_mesh_test_setup();
766 
767 	/* Receive an unsegmented message from the LPN. */
768 	ASSERT_OK(bt_mesh_test_recv(5, cfg->addr, K_SECONDS(4)),
769 		  "Failed to receive from LPN");
770 
771 	/* Send an unsegmented message to the LPN */
772 	ASSERT_OK(bt_mesh_test_send(LPN_ADDR_START, 5, 0, K_SECONDS(1)),
773 		  "Failed to send to LPN");
774 
775 	/* Receive a segmented message from the LPN. */
776 	ASSERT_OK(bt_mesh_test_recv(15, cfg->addr, K_SECONDS(10)),
777 		  "Failed to receive from LPN");
778 
779 	/* Send a segmented message to the friend. Should trigger a poll for the
780 	 * ack.
781 	 */
782 	ASSERT_OK(bt_mesh_test_send(LPN_ADDR_START, 15, 0, K_SECONDS(10)),
783 		  "Send to LPN failed");
784 
785 	/* Receive an unsegmented message from the LPN, originally sent with
786 	 * friend credentials.
787 	 */
788 	ASSERT_OK(bt_mesh_test_recv(1, cfg->addr, K_SECONDS(10)),
789 		  "Failed to receive from LPN");
790 
791 	PASS();
792 }
793 
794 /** Without engaging in a friendship, send group and virtual addr messages to
795  *  the LPN.
796  */
test_other_group(void)797 static void test_other_group(void)
798 {
799 	uint16_t virtual_addr;
800 
801 	bt_mesh_test_setup();
802 
803 	ASSERT_OK(bt_mesh_va_add(test_va_uuid, &virtual_addr));
804 
805 	/* Wait for LPN to send us a message after establishing the friendship */
806 	ASSERT_OK(bt_mesh_test_recv(5, cfg->addr, K_SECONDS(1)));
807 
808 	/* Send a group message to the LPN */
809 	ASSERT_OK(bt_mesh_test_send(GROUP_ADDR, 5, 0, K_SECONDS(1)),
810 		  "Failed to send to LPN");
811 	/* Send a virtual message to the LPN */
812 	ASSERT_OK(bt_mesh_test_send(virtual_addr, 5, 0, K_SECONDS(1)),
813 		  "Failed to send to LPN");
814 
815 	PASS();
816 }
817 
818 #define TEST_CASE(role, name, description)                                     \
819 	{                                                                      \
820 		.test_id = "friendship_" #role "_" #name,                      \
821 		.test_descr = description,                                     \
822 		.test_post_init_f = test_##role##_init,                        \
823 		.test_tick_f = bt_mesh_test_timeout,                           \
824 		.test_main_f = test_##role##_##name,                           \
825 	}
826 
827 static const struct bst_test_instance test_connect[] = {
828 	TEST_CASE(friend, est,       "Friend: establish friendship"),
829 	TEST_CASE(friend, est_multi, "Friend: establish multiple friendships"),
830 	TEST_CASE(friend, msg,       "Friend: message exchange"),
831 	TEST_CASE(friend, overflow,  "Friend: message queue overflow"),
832 	TEST_CASE(friend, group,     "Friend: send to group addrs"),
833 
834 	TEST_CASE(lpn,    est,       "LPN: establish friendship"),
835 	TEST_CASE(lpn,    msg_frnd,  "LPN: message exchange with friend"),
836 	TEST_CASE(lpn,    msg_mesh,  "LPN: message exchange with mesh"),
837 	TEST_CASE(lpn,    re_est,    "LPN: re-establish friendship"),
838 	TEST_CASE(lpn,    poll,      "LPN: poll before timeout"),
839 	TEST_CASE(lpn,    overflow,  "LPN: message queue overflow"),
840 	TEST_CASE(lpn,    group,     "LPN: receive on group addrs"),
841 	TEST_CASE(lpn,    loopback,  "LPN: send to loopback addrs"),
842 
843 	TEST_CASE(other,  msg,       "Other mesh device: message exchange"),
844 	TEST_CASE(other,  group,     "Other mesh device: send to group addrs"),
845 	BSTEST_END_MARKER
846 };
847 
test_friendship_install(struct bst_test_list * tests)848 struct bst_test_list *test_friendship_install(struct bst_test_list *tests)
849 {
850 	tests = bst_add_tests(tests, test_connect);
851 	return tests;
852 }
853