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