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