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/access.h"
9 #include "mesh/foundation.h"
10
11 #define LOG_MODULE_NAME test_access
12
13 #include <zephyr/logging/log.h>
14 LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF);
15
16 #define GROUP_ADDR 0xc000
17 #define UNICAST_ADDR1 0x0001
18 #define UNICAST_ADDR2 0x0006
19 #define WAIT_TIME 10 /*seconds*/
20
21 #define TEST_MODEL_ID_1 0x2a2a
22 #define TEST_MODEL_ID_2 0x2b2b
23 #define TEST_MODEL_ID_3 0x2c2c
24 #define TEST_MODEL_ID_4 0x2d2d
25 #define TEST_MODEL_ID_5 0x2e2e
26
27 #define TEST_MESSAGE_OP_1 BT_MESH_MODEL_OP_1(0x11)
28 #define TEST_MESSAGE_OP_2 BT_MESH_MODEL_OP_1(0x12)
29 #define TEST_MESSAGE_OP_3 BT_MESH_MODEL_OP_1(0x13)
30 #define TEST_MESSAGE_OP_4 BT_MESH_MODEL_OP_1(0x14)
31 #define TEST_MESSAGE_OP_5 BT_MESH_MODEL_OP_1(0x15)
32 #define TEST_MESSAGE_OP_F BT_MESH_MODEL_OP_1(0x1F)
33
34 #define PUB_PERIOD_COUNT 3
35 #define RX_JITTER_MAX (10 + CONFIG_BT_MESH_NETWORK_TRANSMIT_COUNT * \
36 (CONFIG_BT_MESH_NETWORK_TRANSMIT_INTERVAL + 10))
37
38 static int model1_init(struct bt_mesh_model *model);
39 static int model2_init(struct bt_mesh_model *model);
40 static int model3_init(struct bt_mesh_model *model);
41 static int model4_init(struct bt_mesh_model *model);
42 static int model5_init(struct bt_mesh_model *model);
43 static int test_msg_handler(struct bt_mesh_model *model,
44 struct bt_mesh_msg_ctx *ctx,
45 struct net_buf_simple *buf);
46 static int test_msg_ne_handler(struct bt_mesh_model *model,
47 struct bt_mesh_msg_ctx *ctx,
48 struct net_buf_simple *buf);
49
50 struct k_poll_signal model_pub_signal;
51
52 static uint8_t dev_key[16] = { 0xdd };
53 static uint8_t app_key[16] = { 0xaa };
54 static uint8_t net_key[16] = { 0xcc };
55 static struct bt_mesh_prov prov;
56
57 /* Test vector for periodic publication tests. */
58 static const struct {
59 uint8_t period;
60 uint8_t div;
61 int32_t period_ms;
62 } test_period[] = {
63 { BT_MESH_PUB_PERIOD_100MS(5), 0, 500 },
64 { BT_MESH_PUB_PERIOD_SEC(2), 0, 2000 },
65 { BT_MESH_PUB_PERIOD_10SEC(1), 0, 10000 },
66 { BT_MESH_PUB_PERIOD_SEC(3), 1, 1500 },
67 { BT_MESH_PUB_PERIOD_10SEC(3), 3, 3750 },
68 };
69
70 /* Test vector for publication retransmissions tests. */
71 static const uint8_t test_transmit[] = {
72 BT_MESH_PUB_TRANSMIT(4, 50),
73 BT_MESH_PUB_TRANSMIT(3, 100),
74 BT_MESH_PUB_TRANSMIT(2, 200),
75 };
76
77 /* Test vector for canceling a message publication. */
78 static const struct {
79 uint8_t period;
80 uint8_t transmit;
81 uint8_t msgs;
82 int32_t sleep;
83 int32_t duration;
84 } test_cancel[] = {
85 /* Test canceling periodic publication. */
86 {
87 BT_MESH_PUB_PERIOD_SEC(2), 0, 2,
88 2000 /* period */ + 100 /* margin */,
89 3 /* messages */ * 2000 /* period */
90 },
91 /* Test canceling publication retransmission. */
92 {
93 BT_MESH_PUB_PERIOD_SEC(3), BT_MESH_PUB_TRANSMIT(3, 200), 3,
94 200 /* retransmission interval */ + 50 /* margin */,
95 3000 /* one period */
96 },
97 };
98
99 static struct k_sem publish_sem;
100 static bool publish_allow;
101
model1_update(struct bt_mesh_model * model)102 static int model1_update(struct bt_mesh_model *model)
103 {
104 model->pub->msg->data[1]++;
105
106 LOG_DBG("New pub: n: %d t: %d", model->pub->msg->data[1], k_uptime_get_32());
107
108 return publish_allow ? k_sem_give(&publish_sem), 0 : -1;
109 }
110
test_msgf_handler(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)111 static int test_msgf_handler(struct bt_mesh_model *model,
112 struct bt_mesh_msg_ctx *ctx,
113 struct net_buf_simple *buf)
114 {
115 static uint8_t prev_num;
116 uint8_t num = net_buf_simple_pull_u8(buf);
117
118 LOG_DBG("Recv msg: n: %d t: %u", num, k_uptime_get_32());
119
120 /* Ensure that payload changes. */
121 ASSERT_TRUE(prev_num != num);
122 prev_num = num;
123
124 k_sem_give(&publish_sem);
125 return 0;
126 }
127
128 static struct bt_mesh_model_pub model_pub1 = {
129 .msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX),
130 .update = model1_update,
131 };
132
133 static const struct bt_mesh_model_cb test_model1_cb = {
134 .init = model1_init,
135 };
136
137 static const struct bt_mesh_model_cb test_model2_cb = {
138 .init = model2_init,
139 };
140
141 static const struct bt_mesh_model_cb test_model3_cb = {
142 .init = model3_init,
143 };
144
145 static const struct bt_mesh_model_cb test_model4_cb = {
146 .init = model4_init,
147 };
148
149 static const struct bt_mesh_model_cb test_model5_cb = {
150 .init = model5_init,
151 };
152
153 static const struct bt_mesh_model_op model_op1[] = {
154 { TEST_MESSAGE_OP_1, 0, test_msg_handler },
155 { TEST_MESSAGE_OP_F, 0, test_msgf_handler },
156 BT_MESH_MODEL_OP_END
157 };
158
159 static const struct bt_mesh_model_op model_op2[] = {
160 { TEST_MESSAGE_OP_2, 0, test_msg_handler },
161 BT_MESH_MODEL_OP_END
162 };
163
164 static const struct bt_mesh_model_op model_op3[] = {
165 { TEST_MESSAGE_OP_3, 0, test_msg_handler },
166 BT_MESH_MODEL_OP_END
167 };
168
169 static const struct bt_mesh_model_op model_op4[] = {
170 { TEST_MESSAGE_OP_4, 0, test_msg_handler },
171 BT_MESH_MODEL_OP_END
172 };
173
174 static const struct bt_mesh_model_op model_op5[] = {
175 { TEST_MESSAGE_OP_5, 0, test_msg_handler },
176 BT_MESH_MODEL_OP_END
177 };
178
179 static const struct bt_mesh_model_op model_ne_op1[] = {
180 { TEST_MESSAGE_OP_1, 0, test_msg_ne_handler },
181 BT_MESH_MODEL_OP_END
182 };
183
184 static const struct bt_mesh_model_op model_ne_op2[] = {
185 { TEST_MESSAGE_OP_2, 0, test_msg_ne_handler },
186 BT_MESH_MODEL_OP_END
187 };
188
189 static const struct bt_mesh_model_op model_ne_op3[] = {
190 { TEST_MESSAGE_OP_3, 0, test_msg_ne_handler },
191 BT_MESH_MODEL_OP_END
192 };
193
194 static const struct bt_mesh_model_op model_ne_op4[] = {
195 { TEST_MESSAGE_OP_4, 0, test_msg_ne_handler },
196 BT_MESH_MODEL_OP_END
197 };
198
199 static const struct bt_mesh_model_op model_ne_op5[] = {
200 { TEST_MESSAGE_OP_5, 0, test_msg_ne_handler },
201 BT_MESH_MODEL_OP_END
202 };
203
204 static struct bt_mesh_cfg_cli cfg_cli;
205
206 /* do not change model sequence. it will break pointer arithmetic. */
207 static struct bt_mesh_model models[] = {
208 BT_MESH_MODEL_CFG_SRV,
209 BT_MESH_MODEL_CFG_CLI(&cfg_cli),
210 BT_MESH_MODEL_CB(TEST_MODEL_ID_1, model_op1, &model_pub1, NULL, &test_model1_cb),
211 BT_MESH_MODEL_CB(TEST_MODEL_ID_2, model_op2, NULL, NULL, &test_model2_cb),
212 BT_MESH_MODEL_CB(TEST_MODEL_ID_3, model_op3, NULL, NULL, &test_model3_cb),
213 BT_MESH_MODEL_CB(TEST_MODEL_ID_4, model_op4, NULL, NULL, &test_model4_cb),
214 BT_MESH_MODEL_CB(TEST_MODEL_ID_5, model_op5, NULL, NULL, &test_model5_cb),
215 };
216
217 /* do not change model sequence. it will break pointer arithmetic. */
218 static struct bt_mesh_model models_ne[] = {
219 BT_MESH_MODEL_CB(TEST_MODEL_ID_1, model_ne_op1, NULL, NULL, &test_model1_cb),
220 BT_MESH_MODEL_CB(TEST_MODEL_ID_2, model_ne_op2, NULL, NULL, &test_model2_cb),
221 BT_MESH_MODEL_CB(TEST_MODEL_ID_3, model_ne_op3, NULL, NULL, &test_model3_cb),
222 BT_MESH_MODEL_CB(TEST_MODEL_ID_4, model_ne_op4, NULL, NULL, &test_model4_cb),
223 BT_MESH_MODEL_CB(TEST_MODEL_ID_5, model_ne_op5, NULL, NULL, &test_model5_cb),
224 };
225
226 static struct bt_mesh_model vnd_models[] = {};
227
228 static struct bt_mesh_elem elems[] = {
229 BT_MESH_ELEM(0, models, vnd_models),
230 BT_MESH_ELEM(1, models_ne, vnd_models),
231 };
232
233 const struct bt_mesh_comp local_comp = {
234 .elem = elems,
235 .elem_count = ARRAY_SIZE(elems),
236 };
237 /* extension dependency (basic models are on top)
238 *
239 * element idx0 element idx1
240 *
241 * m1 m2 mne2 mne1
242 * / \ / | / \
243 * / \ / | / \
244 * m5 m3------->mne3 mne5
245 * | |
246 * m4 mne4
247 */
248
model1_init(struct bt_mesh_model * model)249 static int model1_init(struct bt_mesh_model *model)
250 {
251 return 0;
252 }
253
model2_init(struct bt_mesh_model * model)254 static int model2_init(struct bt_mesh_model *model)
255 {
256 return 0;
257 }
258
model3_init(struct bt_mesh_model * model)259 static int model3_init(struct bt_mesh_model *model)
260 {
261 ASSERT_OK(bt_mesh_model_extend(model, model - 2));
262 ASSERT_OK(bt_mesh_model_extend(model, model - 1));
263
264 if (model->elem_idx == 1) {
265 ASSERT_OK(bt_mesh_model_extend(model, &models[4]));
266 }
267
268 return 0;
269 }
270
model4_init(struct bt_mesh_model * model)271 static int model4_init(struct bt_mesh_model *model)
272 {
273 ASSERT_OK(bt_mesh_model_extend(model, model - 1));
274
275 return 0;
276 }
277
model5_init(struct bt_mesh_model * model)278 static int model5_init(struct bt_mesh_model *model)
279 {
280 ASSERT_OK(bt_mesh_model_extend(model, model - 4));
281
282 return 0;
283 }
284
test_msg_handler(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)285 static int test_msg_handler(struct bt_mesh_model *model,
286 struct bt_mesh_msg_ctx *ctx,
287 struct net_buf_simple *buf)
288 {
289 LOG_DBG("msg rx model id: %u", model->id);
290 k_poll_signal_raise(&model_pub_signal, model->id);
291
292 return 0;
293 }
294
test_msg_ne_handler(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)295 static int test_msg_ne_handler(struct bt_mesh_model *model,
296 struct bt_mesh_msg_ctx *ctx,
297 struct net_buf_simple *buf)
298 {
299 FAIL("Model %#4x on neighbor element received msg", model->id);
300
301 return 0;
302 }
303
provision(uint16_t addr)304 static void provision(uint16_t addr)
305 {
306 int err;
307
308 err = bt_mesh_provision(net_key, 0, 0, 0, addr, dev_key);
309 if (err) {
310 FAIL("Provisioning failed (err %d)", err);
311 return;
312 }
313 }
314
common_configure(uint16_t addr)315 static void common_configure(uint16_t addr)
316 {
317 uint8_t status;
318 int err;
319 uint16_t model_ids[] = {TEST_MODEL_ID_1, TEST_MODEL_ID_2,
320 TEST_MODEL_ID_3, TEST_MODEL_ID_4, TEST_MODEL_ID_5};
321
322 err = bt_mesh_cfg_cli_app_key_add(0, addr, 0, 0, app_key, &status);
323 if (err || status) {
324 FAIL("AppKey add failed (err %d, status %u)", err, status);
325 return;
326 }
327
328 for (int i = 0; i < ARRAY_SIZE(model_ids); i++) {
329 err = bt_mesh_cfg_cli_mod_app_bind(0, addr, addr, 0, model_ids[i], &status);
330 if (err || status) {
331 FAIL("Model %#4x bind failed (err %d, status %u)",
332 model_ids[i], err, status);
333 return;
334 }
335
336 err = bt_mesh_cfg_cli_mod_app_bind(0, addr, addr + 1, 0, model_ids[i], &status);
337 if (err || status) {
338 FAIL("Model %#4x bind failed (err %d, status %u)",
339 model_ids[i], err, status);
340 return;
341 }
342 }
343
344 err = bt_mesh_cfg_cli_net_transmit_set(0, addr, BT_MESH_TRANSMIT(2, 20), &status);
345 if (err || status != BT_MESH_TRANSMIT(2, 20)) {
346 FAIL("Net transmit set failed (err %d, status %u)", err,
347 status);
348 return;
349 }
350 }
351
subscription_configure(uint16_t addr)352 static void subscription_configure(uint16_t addr)
353 {
354 uint8_t status;
355 int err;
356
357 err = bt_mesh_cfg_cli_mod_sub_add(0, addr, addr, GROUP_ADDR, TEST_MODEL_ID_2, &status);
358
359 if (err || status) {
360 FAIL("Model %#4x subscription configuration failed (err %d, status %u)",
361 TEST_MODEL_ID_2, err, status);
362 return;
363 }
364 }
365
test_tx_ext_model(void)366 static void test_tx_ext_model(void)
367 {
368 bt_mesh_test_cfg_set(NULL, WAIT_TIME);
369 bt_mesh_device_setup(&prov, &local_comp);
370 provision(UNICAST_ADDR1);
371 common_configure(UNICAST_ADDR1);
372
373 struct bt_mesh_msg_ctx ctx = {
374 .net_idx = 0,
375 .app_idx = 0,
376 .addr = GROUP_ADDR,
377 .send_rel = false,
378 .send_ttl = BT_MESH_TTL_DEFAULT,
379 };
380 BT_MESH_MODEL_BUF_DEFINE(msg, TEST_MESSAGE_OP_1, 0);
381
382 bt_mesh_model_msg_init(&msg, TEST_MESSAGE_OP_1);
383 bt_mesh_model_send(&models[2], &ctx, &msg, NULL, NULL);
384
385 bt_mesh_model_msg_init(&msg, TEST_MESSAGE_OP_2);
386 bt_mesh_model_send(&models[3], &ctx, &msg, NULL, NULL);
387
388 bt_mesh_model_msg_init(&msg, TEST_MESSAGE_OP_3);
389 bt_mesh_model_send(&models[4], &ctx, &msg, NULL, NULL);
390
391 bt_mesh_model_msg_init(&msg, TEST_MESSAGE_OP_4);
392 bt_mesh_model_send(&models[5], &ctx, &msg, NULL, NULL);
393
394 bt_mesh_model_msg_init(&msg, TEST_MESSAGE_OP_5);
395 bt_mesh_model_send(&models[6], &ctx, &msg, NULL, NULL);
396
397 PASS();
398 }
399
test_sub_ext_model(void)400 static void test_sub_ext_model(void)
401 {
402 k_poll_signal_init(&model_pub_signal);
403
404 struct k_poll_event events[1] = {
405 K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
406 K_POLL_MODE_NOTIFY_ONLY, &model_pub_signal)
407 };
408
409 bt_mesh_test_cfg_set(NULL, WAIT_TIME);
410 bt_mesh_device_setup(&prov, &local_comp);
411 provision(UNICAST_ADDR2);
412 common_configure(UNICAST_ADDR2);
413 subscription_configure(UNICAST_ADDR2);
414
415 bool m1_fired = false;
416 bool m2_fired = false;
417 bool m3_fired = false;
418 bool m4_fired = false;
419 bool m5_fired = false;
420
421 while (!m1_fired || !m2_fired || !m3_fired || !m4_fired || !m5_fired) {
422 ASSERT_OK(k_poll(events, 1, K_SECONDS(3)));
423
424 switch (model_pub_signal.result) {
425 case TEST_MODEL_ID_1:
426 ASSERT_FALSE(m1_fired);
427 m1_fired = true;
428 break;
429 case TEST_MODEL_ID_2:
430 ASSERT_FALSE(m2_fired);
431 m2_fired = true;
432 break;
433 case TEST_MODEL_ID_3:
434 ASSERT_FALSE(m3_fired);
435 m3_fired = true;
436 break;
437 case TEST_MODEL_ID_4:
438 ASSERT_FALSE(m4_fired);
439 m4_fired = true;
440 break;
441 case TEST_MODEL_ID_5:
442 ASSERT_FALSE(m5_fired);
443 m5_fired = true;
444 break;
445 default:
446 FAIL();
447 break;
448 }
449
450 events[0].signal->signaled = 0;
451 events[0].state = K_POLL_STATE_NOT_READY;
452 }
453
454
455 PASS();
456 }
457
test_sub_capacity_ext_model(void)458 static void test_sub_capacity_ext_model(void)
459 {
460 bt_mesh_test_cfg_set(NULL, WAIT_TIME);
461 bt_mesh_device_setup(&prov, &local_comp);
462 provision(UNICAST_ADDR2);
463 common_configure(UNICAST_ADDR2);
464
465 uint8_t status;
466 int i;
467
468 /* Models in the extension linked list use the subscription list capacity of
469 * each other to the full extent. If a model cannot put a subscription address in
470 * its own subscription list it looks for the closest empty cell in model
471 * in the extension linked list.
472 */
473 for (i = 0; i < 5 * CONFIG_BT_MESH_MODEL_GROUP_COUNT; i++) {
474 ASSERT_OK_MSG(bt_mesh_cfg_cli_mod_sub_add(0, UNICAST_ADDR2, UNICAST_ADDR2,
475 GROUP_ADDR + i, TEST_MODEL_ID_2, &status),
476 "Can't deliver subscription on address %#4x", GROUP_ADDR + i);
477
478 ASSERT_EQUAL(STATUS_SUCCESS, status);
479 }
480
481 uint16_t model_ids[] = {TEST_MODEL_ID_1, TEST_MODEL_ID_2,
482 TEST_MODEL_ID_3, TEST_MODEL_ID_4, TEST_MODEL_ID_5};
483
484 for (int j = 0; j < ARRAY_SIZE(model_ids); j++) {
485 ASSERT_OK_MSG(bt_mesh_cfg_cli_mod_sub_add(0, UNICAST_ADDR2, UNICAST_ADDR2,
486 GROUP_ADDR + i, model_ids[j], &status),
487 "Can't deliver subscription on address %#4x", GROUP_ADDR + i);
488
489 ASSERT_EQUAL(STATUS_INSUFF_RESOURCES, status);
490 }
491
492 PASS();
493 }
494
pub_param_set(uint8_t period,uint8_t transmit)495 static void pub_param_set(uint8_t period, uint8_t transmit)
496 {
497 struct bt_mesh_cfg_cli_mod_pub pub_params = {
498 .addr = UNICAST_ADDR2,
499 .uuid = NULL,
500 .cred_flag = false,
501 .app_idx = 0,
502 .ttl = 5,
503 .period = period,
504 .transmit = transmit,
505 };
506 uint8_t status;
507 int err;
508
509 err = bt_mesh_cfg_cli_mod_pub_set(0, UNICAST_ADDR1, UNICAST_ADDR1, TEST_MODEL_ID_1,
510 &pub_params, &status);
511 if (err || status) {
512 FAIL("Mod pub set failed (err %d, status %u)", err, status);
513 }
514 }
515
msgf_publish(void)516 static void msgf_publish(void)
517 {
518 struct bt_mesh_model *model = &models[2];
519
520 bt_mesh_model_msg_init(model->pub->msg, TEST_MESSAGE_OP_F);
521 net_buf_simple_add_u8(model->pub->msg, 1);
522 bt_mesh_model_publish(model);
523 }
524
pub_jitter_check(int32_t interval,uint8_t count)525 static void pub_jitter_check(int32_t interval, uint8_t count)
526 {
527 int64_t timestamp = k_uptime_get();
528 int32_t jitter = 0;
529 int err;
530
531 for (size_t j = 0; j < count; j++) {
532 /* Every new publication will release semaphore in the update handler and the time
533 * between two consecutive publications will be measured.
534 */
535 err = k_sem_take(&publish_sem, K_SECONDS(20));
536 if (err) {
537 FAIL("Send timed out");
538 }
539
540 int32_t time_delta = k_uptime_delta(×tamp);
541 int32_t pub_delta = llabs(time_delta - interval);
542
543 jitter = MAX(pub_delta, jitter);
544
545 LOG_DBG("Send time: %d delta: %d jitter: %d", (int32_t)timestamp, time_delta,
546 jitter);
547 }
548
549 LOG_INF("Send jitter: %d", jitter);
550 ASSERT_TRUE(jitter <= 10);
551 }
552
recv_jitter_check(int32_t interval,uint8_t count)553 static void recv_jitter_check(int32_t interval, uint8_t count)
554 {
555 int64_t timestamp;
556 uint32_t jitter = 0;
557 int err;
558
559 /* The measurement starts by the first received message. */
560 err = k_sem_take(&publish_sem, K_SECONDS(20));
561 if (err) {
562 FAIL("Recv timed out");
563 }
564
565 timestamp = k_uptime_get();
566
567 for (size_t j = 0; j < count; j++) {
568 /* Every new received message will release semaphore in the message handler and
569 * the time between two consecutive publications will be measured.
570 */
571 err = k_sem_take(&publish_sem, K_SECONDS(20));
572 if (err) {
573 FAIL("Recv timed out");
574 }
575
576 int32_t time_delta = k_uptime_delta(×tamp);
577 int32_t pub_delta = llabs(time_delta - interval);
578
579 jitter = MAX(pub_delta, jitter);
580
581 LOG_DBG("Recv time: %d delta: %d jitter: %d", (int32_t)timestamp, time_delta,
582 jitter);
583 }
584
585 LOG_INF("Recv jitter: %d", jitter);
586 ASSERT_TRUE(jitter <= RX_JITTER_MAX);
587 }
588
589 /* Test publish period states by publishing a message and checking interval between update handler
590 * calls.
591 */
test_tx_period(void)592 static void test_tx_period(void)
593 {
594 struct bt_mesh_model *model = &models[2];
595
596 bt_mesh_test_cfg_set(NULL, 60);
597 bt_mesh_device_setup(&prov, &local_comp);
598 provision(UNICAST_ADDR1);
599 common_configure(UNICAST_ADDR1);
600
601 k_sem_init(&publish_sem, 0, 1);
602
603 for (size_t i = 0; i < ARRAY_SIZE(test_period); i++) {
604 pub_param_set(test_period[i].period, 0);
605
606 model->pub->fast_period = test_period[i].div > 0;
607 model->pub->period_div = test_period[i].div;
608
609 LOG_INF("Publication period: %d", test_period[i].period_ms);
610
611 /* Start publishing messages and measure jitter. */
612 msgf_publish();
613 publish_allow = true;
614 pub_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT);
615
616 /* Disable periodic publication before the next test iteration. */
617 publish_allow = false;
618
619 /* Let the receiver hit the first semaphore. */
620 k_sleep(K_SECONDS(1));
621 }
622
623 PASS();
624 }
625
626 /* Receive a periodically published message and check publication period by measuring interval
627 * between message handler calls.
628 */
test_rx_period(void)629 static void test_rx_period(void)
630 {
631 bt_mesh_test_cfg_set(NULL, 60);
632 bt_mesh_device_setup(&prov, &local_comp);
633 provision(UNICAST_ADDR2);
634 common_configure(UNICAST_ADDR2);
635
636 k_sem_init(&publish_sem, 0, 1);
637
638 for (size_t i = 0; i < ARRAY_SIZE(test_period); i++) {
639 recv_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT);
640 }
641
642 PASS();
643 }
644
645 /* Test publish retransmit interval and count states by publishing a message and checking interval
646 * between update handler calls.
647 */
test_tx_transmit(void)648 static void test_tx_transmit(void)
649 {
650 struct bt_mesh_model *model = &models[2];
651 uint8_t status;
652 int err;
653
654 bt_mesh_test_cfg_set(NULL, 60);
655 bt_mesh_device_setup(&prov, &local_comp);
656 provision(UNICAST_ADDR1);
657 common_configure(UNICAST_ADDR1);
658
659 k_sem_init(&publish_sem, 0, 1);
660
661 /* Network retransmissions has to be disabled so that the legacy advertiser sleeps for the
662 * least possible time, which is 50ms. This will let the access layer publish a message
663 * with 50ms retransmission interval.
664 */
665 err = bt_mesh_cfg_cli_net_transmit_set(0, UNICAST_ADDR1,
666 BT_MESH_TRANSMIT(0, CONFIG_BT_MESH_NETWORK_TRANSMIT_INTERVAL),
667 &status);
668 if (err || status != BT_MESH_TRANSMIT(0, CONFIG_BT_MESH_NETWORK_TRANSMIT_INTERVAL)) {
669 FAIL("Net transmit set failed (err %d, status %u)", err,
670 status);
671 }
672
673 publish_allow = true;
674 model->pub->retr_update = true;
675
676 for (size_t i = 0; i < ARRAY_SIZE(test_transmit); i++) {
677 pub_param_set(0, test_transmit[i]);
678
679 int32_t interval = BT_MESH_PUB_TRANSMIT_INT(test_transmit[i]);
680 int count = BT_MESH_PUB_TRANSMIT_COUNT(test_transmit[i]);
681
682 LOG_INF("Retransmission interval: %d, count: %d", interval, count);
683
684 /* Start publishing messages and measure jitter. */
685 msgf_publish();
686 pub_jitter_check(interval, count);
687
688 /* Let the receiver hit the first semaphore. */
689 k_sleep(K_SECONDS(1));
690 }
691
692 PASS();
693 }
694
695 /* Receive a published message and check retransmission interval by measuring interval between
696 * message handler calls.
697 */
test_rx_transmit(void)698 static void test_rx_transmit(void)
699 {
700 bt_mesh_test_cfg_set(NULL, 60);
701 bt_mesh_device_setup(&prov, &local_comp);
702 provision(UNICAST_ADDR2);
703 common_configure(UNICAST_ADDR2);
704
705 k_sem_init(&publish_sem, 0, 1);
706
707 for (size_t i = 0; i < ARRAY_SIZE(test_transmit); i++) {
708 int32_t interval = BT_MESH_PUB_TRANSMIT_INT(test_transmit[i]);
709 int count = BT_MESH_PUB_TRANSMIT_COUNT(test_transmit[i]);
710
711 recv_jitter_check(interval, count);
712 }
713
714 PASS();
715 }
716
717 /* Cancel one of messages to be published and check that the next one is published when next period
718 * starts.
719 */
test_tx_cancel(void)720 static void test_tx_cancel(void)
721 {
722 struct bt_mesh_model *model = &models[2];
723 int err;
724
725 bt_mesh_test_cfg_set(NULL, 20);
726 bt_mesh_device_setup(&prov, &local_comp);
727 provision(UNICAST_ADDR1);
728 common_configure(UNICAST_ADDR1);
729
730 k_sem_init(&publish_sem, 0, 1);
731
732 model->pub->retr_update = true;
733
734 for (size_t i = 0; i < ARRAY_SIZE(test_cancel); i++) {
735 pub_param_set(test_cancel[i].period, test_cancel[i].transmit);
736
737 msgf_publish();
738 publish_allow = true;
739 int64_t timestamp = k_uptime_get();
740
741 /* Send few messages except one that is to be cancelled. */
742 for (size_t j = 0; j < test_cancel[i].msgs - 1; j++) {
743 err = k_sem_take(&publish_sem, K_SECONDS(20));
744 if (err) {
745 FAIL("Send timed out");
746 }
747 }
748
749 /* Cancel the next publication. */
750 publish_allow = false;
751 k_sleep(K_MSEC(test_cancel[i].sleep));
752
753 /* Reenable publication a wait for a next message to be published. */
754 publish_allow = true;
755 err = k_sem_take(&publish_sem, K_SECONDS(20));
756 if (err) {
757 FAIL("Send timed out");
758 }
759
760 /* Disable periodic publication before the next test iteration. */
761 publish_allow = false;
762
763 /* If the canceled message is also sent, the semaphore will be released earlier than
764 * expected.
765 */
766 int32_t time_delta = k_uptime_delta(×tamp);
767 int32_t jitter = llabs(time_delta - test_cancel[i].duration);
768
769 LOG_DBG("Send time: %d delta: %d", (int32_t)timestamp, time_delta);
770 LOG_INF("Send jitter: %d", jitter);
771 ASSERT_TRUE(jitter <= 10);
772
773 /* Let the receiver hit the first semaphore. */
774 k_sleep(K_SECONDS(1));
775 }
776
777 PASS();
778 }
779
780 /* Receive all published messages and ensure that cancelled message is not received. */
test_rx_cancel(void)781 static void test_rx_cancel(void)
782 {
783 bt_mesh_test_cfg_set(NULL, 20);
784 bt_mesh_device_setup(&prov, &local_comp);
785 provision(UNICAST_ADDR2);
786 common_configure(UNICAST_ADDR2);
787
788 k_sem_init(&publish_sem, 0, 1);
789
790 for (size_t i = 0; i < ARRAY_SIZE(test_cancel); i++) {
791 int64_t timestamp;
792 int err;
793
794 /* Wait for the first published message. */
795 err = k_sem_take(&publish_sem, K_SECONDS(20));
796 if (err) {
797 FAIL("Recv timed out");
798 }
799
800 timestamp = k_uptime_get();
801
802 /* Wait for the rest messages to be published (incl. the next after cancelled one).
803 */
804 for (size_t j = 0; j < test_cancel[i].msgs; j++) {
805 err = k_sem_take(&publish_sem, K_SECONDS(20));
806 if (err) {
807 FAIL("Recv timed out");
808 }
809 }
810
811 /* If the canceled message is received, the semaphore will be released earlier than
812 * expected.
813 */
814 int32_t time_delta = k_uptime_delta(×tamp);
815 int32_t jitter = llabs(time_delta - test_cancel[i].duration);
816
817 LOG_DBG("Recv time: %d delta: %d", (int32_t)timestamp, time_delta);
818 LOG_INF("Recv jitter: %d", jitter);
819 ASSERT_TRUE(jitter <= RX_JITTER_MAX);
820 }
821
822 PASS();
823 }
824
825 #define TEST_CASE(role, name, description) \
826 { \
827 .test_id = "access_" #role "_" #name, \
828 .test_descr = description, \
829 .test_tick_f = bt_mesh_test_timeout, \
830 .test_main_f = test_##role##_##name, \
831 }
832
833 static const struct bst_test_instance test_access[] = {
834 TEST_CASE(tx, ext_model, "Access: tx data of extended models"),
835 TEST_CASE(sub, ext_model, "Access: data subscription of extended models"),
836 TEST_CASE(sub_capacity, ext_model, "Access: subscription capacity of extended models"),
837 TEST_CASE(tx, period, "Access: Publish a message periodically"),
838 TEST_CASE(rx, period, "Access: Receive periodically published message"),
839 TEST_CASE(tx, transmit, "Access: Publish and retransmit message"),
840 TEST_CASE(rx, transmit, "Access: Receive retransmitted messages"),
841 TEST_CASE(tx, cancel, "Access: Cancel a message during publication"),
842 TEST_CASE(rx, cancel, "Access: Receive published messages except cancelled"),
843
844 BSTEST_END_MARKER
845 };
846
test_access_install(struct bst_test_list * tests)847 struct bst_test_list *test_access_install(struct bst_test_list *tests)
848 {
849 tests = bst_add_tests(tests, test_access);
850 return tests;
851 }
852