1 /*
2 * Copyright (c) 2022 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/bluetooth/hci.h>
9 #include "mesh_test.h"
10 #include "mesh/adv.h"
11 #include "mesh/net.h"
12 #include "mesh/mesh.h"
13 #include "mesh/foundation.h"
14
15 #define LOG_MODULE_NAME test_adv
16
17 #include <zephyr/logging/log.h>
18 LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF);
19
20 #define WAIT_TIME 60 /*seconds*/
21
22 enum bt_mesh_gatt_service {
23 MESH_SERVICE_PROVISIONING,
24 MESH_SERVICE_PROXY,
25 };
26
27 struct bt_mesh_test_adv {
28 uint8_t retr; /* number of retransmits of adv frame */
29 int64_t interval; /* interval of transmitted frames */
30 };
31
32 struct bt_mesh_test_gatt {
33 uint8_t transmits; /* number of frame (pb gatt or proxy beacon) transmits */
34 int64_t interval; /* interval of transmitted frames */
35 enum bt_mesh_gatt_service service;
36 };
37
38 extern const struct bt_mesh_comp comp;
39
40 static uint8_t test_prov_uuid[16] = { 0x6c, 0x69, 0x6e, 0x67, 0x61, 0xaa };
41
42 static const struct bt_mesh_test_cfg adv_cfg = {
43 .addr = 0x0001,
44 .dev_key = { 0x01 },
45 };
46
47 static struct bt_mesh_send_cb send_cb;
48 static struct bt_mesh_test_adv xmit_param;
49 static const char txt_msg[] = "adv test";
50 static const char cb_msg[] = "cb test";
51 static int64_t tx_timestamp;
52 static int seq_checker;
53 static struct bt_mesh_test_gatt gatt_param;
54 static int num_adv_sent;
55 static uint8_t previous_checker = 0xff;
56
57 static K_SEM_DEFINE(observer_sem, 0, 1);
58
test_tx_init(void)59 static void test_tx_init(void)
60 {
61 bt_mesh_test_cfg_set(NULL, WAIT_TIME);
62 }
63
test_rx_init(void)64 static void test_rx_init(void)
65 {
66 bt_mesh_test_cfg_set(NULL, WAIT_TIME);
67 }
68
bt_init(void)69 static void bt_init(void)
70 {
71 ASSERT_OK_MSG(bt_enable(NULL), "Bluetooth init failed");
72 LOG_INF("Bluetooth initialized");
73 }
74
adv_init(void)75 static void adv_init(void)
76 {
77 bt_mesh_adv_init();
78 ASSERT_OK_MSG(bt_mesh_adv_enable(), "Mesh adv init failed");
79 }
80
allocate_all_array(struct net_buf ** buf,size_t num_buf,uint8_t xmit)81 static void allocate_all_array(struct net_buf **buf, size_t num_buf, uint8_t xmit)
82 {
83 for (int i = 0; i < num_buf; i++) {
84 *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
85 xmit, K_NO_WAIT);
86
87 ASSERT_FALSE_MSG(!*buf, "Out of buffers\n");
88 buf++;
89 }
90 }
91
verify_adv_queue_overflow(void)92 static void verify_adv_queue_overflow(void)
93 {
94 struct net_buf *dummy_buf;
95
96 /* Verity Queue overflow */
97 dummy_buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
98 BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
99 ASSERT_TRUE_MSG(!dummy_buf, "Unexpected extra buffer\n");
100 }
101
check_delta_time(uint8_t transmit,uint64_t interval)102 static bool check_delta_time(uint8_t transmit, uint64_t interval)
103 {
104 static int cnt;
105 static int64_t timestamp;
106
107 if (cnt) {
108 int64_t delta = k_uptime_delta(×tamp);
109
110 LOG_INF("rx: cnt(%d) delta(%dms) interval(%ums)",
111 cnt, (int32_t)delta, (uint32_t)interval);
112
113 ASSERT_TRUE(delta >= (interval - 5) &&
114 delta < (interval + 15));
115 } else {
116 timestamp = k_uptime_get();
117
118 LOG_INF("rx: cnt(%d) delta(0ms)", cnt);
119 }
120
121 cnt++;
122
123 if (cnt >= transmit) {
124 cnt = 0;
125 timestamp = 0;
126 return true;
127 }
128
129 return false;
130 }
131
single_start_cb(uint16_t duration,int err,void * cb_data)132 static void single_start_cb(uint16_t duration, int err, void *cb_data)
133 {
134 int64_t delta;
135
136 delta = k_uptime_delta(&tx_timestamp);
137 LOG_INF("tx start: +%d ms", delta);
138 ASSERT_TRUE(duration >= 90 && duration <= 200);
139 ASSERT_EQUAL(0, err);
140 ASSERT_EQUAL(cb_msg, cb_data);
141 ASSERT_EQUAL(0, seq_checker & 1);
142 seq_checker++;
143 }
144
single_end_cb(int err,void * cb_data)145 static void single_end_cb(int err, void *cb_data)
146 {
147 int64_t delta;
148
149 delta = k_uptime_delta(&tx_timestamp);
150 LOG_INF("tx end: +%d ms", delta);
151 ASSERT_EQUAL(0, err);
152 ASSERT_EQUAL(cb_msg, cb_data);
153 ASSERT_EQUAL(1, seq_checker & 1);
154 seq_checker++;
155 k_sem_give(&observer_sem);
156 }
157
realloc_end_cb(int err,void * cb_data)158 static void realloc_end_cb(int err, void *cb_data)
159 {
160 struct net_buf *buf = (struct net_buf *)cb_data;
161
162 ASSERT_EQUAL(0, err);
163 buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
164 BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
165 ASSERT_FALSE_MSG(!buf, "Out of buffers\n");
166
167 k_sem_give(&observer_sem);
168 }
169
seq_start_cb(uint16_t duration,int err,void * cb_data)170 static void seq_start_cb(uint16_t duration, int err, void *cb_data)
171 {
172 ASSERT_EQUAL(0, err);
173 ASSERT_EQUAL(seq_checker, (intptr_t)cb_data);
174 }
175
seq_end_cb(int err,void * cb_data)176 static void seq_end_cb(int err, void *cb_data)
177 {
178 ASSERT_EQUAL(0, err);
179 ASSERT_EQUAL(seq_checker, (intptr_t)cb_data);
180 seq_checker++;
181
182 if (seq_checker == CONFIG_BT_MESH_ADV_BUF_COUNT) {
183 k_sem_give(&observer_sem);
184 }
185 }
186
parse_mesh_gatt_preamble(struct net_buf_simple * buf)187 static void parse_mesh_gatt_preamble(struct net_buf_simple *buf)
188 {
189 ASSERT_EQUAL(0x0201, net_buf_simple_pull_be16(buf));
190 /* flags */
191 (void)net_buf_simple_pull_u8(buf);
192 ASSERT_EQUAL(0x0303, net_buf_simple_pull_be16(buf));
193 }
194
parse_mesh_pb_gatt_service(struct net_buf_simple * buf)195 static void parse_mesh_pb_gatt_service(struct net_buf_simple *buf)
196 {
197 /* Figure 7.1: PB-GATT Advertising Data */
198 /* mesh provisioning service */
199 ASSERT_EQUAL(0x2718, net_buf_simple_pull_be16(buf));
200 ASSERT_EQUAL(0x1516, net_buf_simple_pull_be16(buf));
201 /* mesh provisioning service */
202 ASSERT_EQUAL(0x2718, net_buf_simple_pull_be16(buf));
203 }
204
parse_mesh_proxy_service(struct net_buf_simple * buf)205 static void parse_mesh_proxy_service(struct net_buf_simple *buf)
206 {
207 /* Figure 7.2: Advertising with Network ID (Identification Type 0x00) */
208 /* mesh proxy service */
209 ASSERT_EQUAL(0x2818, net_buf_simple_pull_be16(buf));
210 ASSERT_EQUAL(0x0c16, net_buf_simple_pull_be16(buf));
211 /* mesh proxy service */
212 ASSERT_EQUAL(0x2818, net_buf_simple_pull_be16(buf));
213 /* network ID */
214 ASSERT_EQUAL(0x00, net_buf_simple_pull_u8(buf));
215 }
216
gatt_scan_cb(const bt_addr_le_t * addr,int8_t rssi,uint8_t adv_type,struct net_buf_simple * buf)217 static void gatt_scan_cb(const bt_addr_le_t *addr, int8_t rssi,
218 uint8_t adv_type, struct net_buf_simple *buf)
219 {
220 if (adv_type != BT_GAP_ADV_TYPE_ADV_IND) {
221 return;
222 }
223
224 parse_mesh_gatt_preamble(buf);
225
226 if (gatt_param.service == MESH_SERVICE_PROVISIONING) {
227 parse_mesh_pb_gatt_service(buf);
228 } else {
229 parse_mesh_proxy_service(buf);
230 }
231
232 LOG_INF("rx: %s", txt_msg);
233
234 if (check_delta_time(gatt_param.transmits, gatt_param.interval)) {
235 LOG_INF("rx completed. stop observer.");
236 k_sem_give(&observer_sem);
237 }
238 }
239
rx_gatt_beacons(void)240 static void rx_gatt_beacons(void)
241 {
242 struct bt_le_scan_param scan_param = {
243 .type = BT_HCI_LE_SCAN_PASSIVE,
244 .options = BT_LE_SCAN_OPT_NONE,
245 .interval = BT_MESH_ADV_SCAN_UNIT(1000),
246 .window = BT_MESH_ADV_SCAN_UNIT(1000)
247 };
248 int err;
249
250 err = bt_le_scan_start(&scan_param, gatt_scan_cb);
251 ASSERT_FALSE_MSG(err && err != -EALREADY, "Starting scan failed (err %d)\n", err);
252
253 err = k_sem_take(&observer_sem, K_SECONDS(20));
254 ASSERT_OK(err);
255
256 err = bt_le_scan_stop();
257 ASSERT_FALSE_MSG(err && err != -EALREADY, "Stopping scan failed (err %d)\n", err);
258 }
259
xmit_scan_cb(const bt_addr_le_t * addr,int8_t rssi,uint8_t adv_type,struct net_buf_simple * buf)260 static void xmit_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
261 struct net_buf_simple *buf)
262 {
263 uint8_t length;
264
265 if (adv_type != BT_GAP_ADV_TYPE_ADV_NONCONN_IND) {
266 return;
267 }
268
269 length = net_buf_simple_pull_u8(buf);
270 ASSERT_EQUAL(buf->len, length);
271 ASSERT_EQUAL(length, sizeof(uint8_t) + sizeof(txt_msg));
272 ASSERT_EQUAL(BT_DATA_MESH_MESSAGE, net_buf_simple_pull_u8(buf));
273
274 char *data = net_buf_simple_pull_mem(buf, sizeof(txt_msg));
275
276 LOG_INF("rx: %s", txt_msg);
277 ASSERT_EQUAL(0, memcmp(txt_msg, data, sizeof(txt_msg)));
278
279 /* Add 1 initial transmit to the retransmit. */
280 if (check_delta_time(xmit_param.retr + 1, xmit_param.interval)) {
281 LOG_INF("rx completed. stop observer.");
282 k_sem_give(&observer_sem);
283 }
284 }
285
rx_xmit_adv(void)286 static void rx_xmit_adv(void)
287 {
288 struct bt_le_scan_param scan_param = {
289 .type = BT_HCI_LE_SCAN_PASSIVE,
290 .options = BT_LE_SCAN_OPT_NONE,
291 .interval = BT_MESH_ADV_SCAN_UNIT(1000),
292 .window = BT_MESH_ADV_SCAN_UNIT(1000)
293 };
294 int err;
295
296 err = bt_le_scan_start(&scan_param, xmit_scan_cb);
297 ASSERT_FALSE_MSG(err && err != -EALREADY, "Starting scan failed (err %d)\n", err);
298
299 err = k_sem_take(&observer_sem, K_SECONDS(20));
300 ASSERT_OK(err);
301
302 err = bt_le_scan_stop();
303 ASSERT_FALSE_MSG(err && err != -EALREADY, "Stopping scan failed (err %d)\n", err);
304 }
305
send_order_start_cb(uint16_t duration,int err,void * user_data)306 static void send_order_start_cb(uint16_t duration, int err, void *user_data)
307 {
308 struct net_buf *buf = (struct net_buf *)user_data;
309
310 ASSERT_OK_MSG(err, "Failed adv start cb err (%d)", err);
311 ASSERT_EQUAL(2, buf->len);
312
313 uint8_t current = buf->data[0];
314 uint8_t previous = buf->data[1];
315
316 LOG_INF("tx start: current(%d) previous(%d)", current, previous);
317
318 ASSERT_EQUAL(previous_checker, previous);
319 previous_checker = current;
320 }
321
send_order_end_cb(int err,void * user_data)322 static void send_order_end_cb(int err, void *user_data)
323 {
324 struct net_buf *buf = (struct net_buf *)user_data;
325
326 ASSERT_OK_MSG(err, "Failed adv start cb err (%d)", err);
327 ASSERT_TRUE_MSG(!buf->data, "Data not cleared!\n");
328 seq_checker++;
329 LOG_INF("tx end: seq(%d)", seq_checker);
330
331 if (seq_checker == num_adv_sent) {
332 seq_checker = 0;
333 previous_checker = 0xff;
334 k_sem_give(&observer_sem);
335 }
336 }
337
receive_order_scan_cb(const bt_addr_le_t * addr,int8_t rssi,uint8_t adv_type,struct net_buf_simple * buf)338 static void receive_order_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type,
339 struct net_buf_simple *buf)
340 {
341 uint8_t length;
342 uint8_t current;
343 uint8_t previous;
344
345 length = net_buf_simple_pull_u8(buf);
346 ASSERT_EQUAL(buf->len, length);
347 ASSERT_EQUAL(BT_DATA_MESH_MESSAGE, net_buf_simple_pull_u8(buf));
348 current = net_buf_simple_pull_u8(buf);
349 previous = net_buf_simple_pull_u8(buf);
350 LOG_INF("rx: current(%d) previous(%d)", current, previous);
351 ASSERT_EQUAL(previous_checker, previous);
352
353 /* Add 1 initial transmit to the retransmit. */
354 if (check_delta_time(xmit_param.retr + 1, xmit_param.interval)) {
355 previous_checker = current;
356 k_sem_give(&observer_sem);
357 }
358 }
359
receive_order(int expect_adv)360 static void receive_order(int expect_adv)
361 {
362 struct bt_le_scan_param scan_param = {
363 .type = BT_HCI_LE_SCAN_PASSIVE,
364 .options = BT_LE_SCAN_OPT_NONE,
365 .interval = BT_MESH_ADV_SCAN_UNIT(1000),
366 .window = BT_MESH_ADV_SCAN_UNIT(1000)
367 };
368 int err;
369
370 err = bt_le_scan_start(&scan_param, receive_order_scan_cb);
371 ASSERT_FALSE_MSG(err && err != -EALREADY, "Starting scan failed (err %d)\n", err);
372
373 previous_checker = 0xff;
374 for (int i = 0; i < expect_adv; i++) {
375 err = k_sem_take(&observer_sem, K_SECONDS(10));
376 ASSERT_OK_MSG(err, "Didn't receive adv in time");
377 }
378
379 err = bt_le_scan_stop();
380 ASSERT_FALSE_MSG(err && err != -EALREADY, "Stopping scan failed (err %d)\n", err);
381 }
382
send_adv_buf(struct net_buf * buf,uint8_t curr,uint8_t prev)383 static void send_adv_buf(struct net_buf *buf, uint8_t curr, uint8_t prev)
384 {
385 send_cb.start = send_order_start_cb;
386 send_cb.end = send_order_end_cb;
387
388 (void)net_buf_add_u8(buf, curr);
389 (void)net_buf_add_u8(buf, prev);
390
391 bt_mesh_adv_send(buf, &send_cb, buf);
392 net_buf_unref(buf);
393 }
394
send_adv_array(struct net_buf ** buf,size_t num_buf,bool reverse)395 static void send_adv_array(struct net_buf **buf, size_t num_buf, bool reverse)
396 {
397 uint8_t previous;
398 int i;
399
400 num_adv_sent = num_buf;
401 previous = 0xff;
402 if (!reverse) {
403 i = 0;
404 } else {
405 i = num_buf - 1;
406 }
407 while ((!reverse && i < num_buf) || (reverse && i >= 0)) {
408 send_adv_buf(*buf, (uint8_t)i, previous);
409 previous = (uint8_t)i;
410 if (!reverse) {
411 buf++;
412 i++;
413 } else {
414 buf--;
415 i--;
416 }
417 }
418 }
419
test_tx_cb_single(void)420 static void test_tx_cb_single(void)
421 {
422 struct net_buf *buf;
423 int err;
424
425 bt_init();
426 adv_init();
427
428 buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
429 BT_MESH_TRANSMIT(2, 20), K_NO_WAIT);
430 ASSERT_FALSE_MSG(!buf, "Out of buffers\n");
431
432 send_cb.start = single_start_cb;
433 send_cb.end = single_end_cb;
434
435 net_buf_add_mem(buf, txt_msg, sizeof(txt_msg));
436 seq_checker = 0;
437 tx_timestamp = k_uptime_get();
438 bt_mesh_adv_send(buf, &send_cb, (void *)cb_msg);
439 net_buf_unref(buf);
440
441 err = k_sem_take(&observer_sem, K_SECONDS(1));
442 ASSERT_OK_MSG(err, "Didn't call end tx cb.");
443
444 PASS();
445 }
446
test_rx_xmit(void)447 static void test_rx_xmit(void)
448 {
449 xmit_param.retr = 2;
450 xmit_param.interval = 20;
451
452 bt_init();
453 rx_xmit_adv();
454
455 PASS();
456 }
457
test_tx_cb_multi(void)458 static void test_tx_cb_multi(void)
459 {
460 struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT];
461 int err;
462
463 bt_init();
464 adv_init();
465
466 /* Allocate all network buffers. */
467 allocate_all_array(buf, ARRAY_SIZE(buf), BT_MESH_TRANSMIT(2, 20));
468
469 /* Start single adv to reallocate one network buffer in callback.
470 * Check that the buffer is freed before cb is triggered.
471 */
472 send_cb.start = NULL;
473 send_cb.end = realloc_end_cb;
474 net_buf_add_mem(buf[0], txt_msg, sizeof(txt_msg));
475
476 bt_mesh_adv_send(buf[0], &send_cb, buf[0]);
477 net_buf_unref(buf[0]);
478
479 err = k_sem_take(&observer_sem, K_SECONDS(1));
480 ASSERT_OK_MSG(err, "Didn't call the end tx cb that reallocates buffer one more time.");
481
482 /* Start multi advs to check that all buffers are sent and cbs are triggered. */
483 send_cb.start = seq_start_cb;
484 send_cb.end = seq_end_cb;
485 seq_checker = 0;
486
487 for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) {
488 net_buf_add_le32(buf[i], i);
489 bt_mesh_adv_send(buf[i], &send_cb, (void *)(intptr_t)i);
490 net_buf_unref(buf[i]);
491 }
492
493 err = k_sem_take(&observer_sem, K_SECONDS(10));
494 ASSERT_OK_MSG(err, "Didn't call the last end tx cb.");
495
496 PASS();
497 }
498
test_tx_proxy_mixin(void)499 static void test_tx_proxy_mixin(void)
500 {
501 static struct bt_mesh_prov prov = {
502 .uuid = test_prov_uuid,
503 };
504 uint8_t status;
505 int err;
506
507 /* Initialize mesh stack and enable pb gatt bearer to emit beacons. */
508 bt_mesh_device_setup(&prov, &comp);
509 err = bt_mesh_prov_enable(BT_MESH_PROV_GATT);
510 ASSERT_OK_MSG(err, "Failed to enable GATT provisioner");
511
512 /* Let the tester to measure an interval between advertisements.
513 * The node should advertise pb gatt service with 100 msec interval.
514 */
515 k_sleep(K_MSEC(1800));
516
517 LOG_INF("Provision device under test");
518 /* Provision dut and start gatt proxy beacons. */
519 bt_mesh_provision(test_net_key, 0, 0, 0, adv_cfg.addr, adv_cfg.dev_key);
520 /* Disable secured network beacons to exclude influence of them on proxy beaconing. */
521 ASSERT_OK(bt_mesh_cfg_cli_beacon_set(0, adv_cfg.addr, BT_MESH_BEACON_DISABLED, &status));
522 ASSERT_EQUAL(BT_MESH_BEACON_DISABLED, status);
523
524 /* Let the tester to measure an interval between advertisements.
525 * The node should advertise proxy service with 1 second interval.
526 */
527 k_sleep(K_MSEC(6000));
528
529 /* Send a mesh message while advertising proxy service.
530 * Advertising the proxy service should be resumed after
531 * finishing advertising the message.
532 */
533 struct net_buf *buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
534 BT_MESH_TRANSMIT(5, 20), K_NO_WAIT);
535 net_buf_add_mem(buf, txt_msg, sizeof(txt_msg));
536 bt_mesh_adv_send(buf, NULL, NULL);
537 k_sleep(K_MSEC(150));
538
539 /* Let the tester to measure an interval between advertisements again. */
540 k_sleep(K_MSEC(6000));
541
542 PASS();
543 }
544
test_rx_proxy_mixin(void)545 static void test_rx_proxy_mixin(void)
546 {
547 /* (total transmit duration) / (transmit interval) */
548 gatt_param.transmits = 1500 / 100;
549 gatt_param.interval = 100;
550 gatt_param.service = MESH_SERVICE_PROVISIONING;
551
552 bt_init();
553
554 /* Scan pb gatt beacons. */
555 rx_gatt_beacons();
556
557 /* Delay to provision dut */
558 k_sleep(K_MSEC(1000));
559
560 /* Scan proxy beacons. */
561 /* (total transmit duration) / (transmit interval) */
562 gatt_param.transmits = 5000 / 1000;
563 gatt_param.interval = 1000;
564 gatt_param.service = MESH_SERVICE_PROXY;
565 rx_gatt_beacons();
566
567 /* Scan adv data. */
568 xmit_param.retr = 5;
569 xmit_param.interval = 20;
570 rx_xmit_adv();
571
572 /* Scan proxy beacons again. */
573 rx_gatt_beacons();
574
575 PASS();
576 }
577
test_tx_send_order(void)578 static void test_tx_send_order(void)
579 {
580 struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT];
581 uint8_t xmit = BT_MESH_TRANSMIT(2, 20);
582
583 bt_init();
584 adv_init();
585
586 /* Verify sending order */
587 allocate_all_array(buf, ARRAY_SIZE(buf), xmit);
588 verify_adv_queue_overflow();
589 send_adv_array(&buf[0], ARRAY_SIZE(buf), false);
590
591 /* Wait for no message receive window to end. */
592 ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
593 "Didn't call the last end tx cb.");
594
595 /* Verify buffer allocation/deallocation after sending */
596 allocate_all_array(buf, ARRAY_SIZE(buf), xmit);
597 verify_adv_queue_overflow();
598 for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) {
599 net_buf_unref(buf[i]);
600 buf[i] = NULL;
601 }
602 /* Check that it possible to add just one net buf. */
603 allocate_all_array(buf, 1, xmit);
604
605 PASS();
606 }
607
test_tx_reverse_order(void)608 static void test_tx_reverse_order(void)
609 {
610 struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT];
611 uint8_t xmit = BT_MESH_TRANSMIT(2, 20);
612
613 bt_init();
614 adv_init();
615
616 /* Verify reversed sending order */
617 allocate_all_array(buf, ARRAY_SIZE(buf), xmit);
618
619 send_adv_array(&buf[CONFIG_BT_MESH_ADV_BUF_COUNT - 1], ARRAY_SIZE(buf), true);
620
621 /* Wait for no message receive window to end. */
622 ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
623 "Didn't call the last end tx cb.");
624
625 PASS();
626 }
627
test_tx_random_order(void)628 static void test_tx_random_order(void)
629 {
630 struct net_buf *buf[3];
631 uint8_t xmit = BT_MESH_TRANSMIT(0, 20);
632
633 bt_init();
634 adv_init();
635
636 /* Verify random order calls */
637 num_adv_sent = ARRAY_SIZE(buf);
638 previous_checker = 0xff;
639 buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
640 xmit, K_NO_WAIT);
641 ASSERT_FALSE_MSG(!buf[0], "Out of buffers\n");
642 buf[1] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
643 xmit, K_NO_WAIT);
644 ASSERT_FALSE_MSG(!buf[1], "Out of buffers\n");
645
646 send_adv_buf(buf[0], 0, 0xff);
647
648 buf[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_LOCAL_ADV,
649 xmit, K_NO_WAIT);
650 ASSERT_FALSE_MSG(!buf[2], "Out of buffers\n");
651
652 send_adv_buf(buf[2], 2, 0);
653
654 send_adv_buf(buf[1], 1, 2);
655
656 /* Wait for no message receive window to end. */
657 ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)),
658 "Didn't call the last end tx cb.");
659
660 PASS();
661 }
662
test_rx_receive_order(void)663 static void test_rx_receive_order(void)
664 {
665 bt_init();
666
667 xmit_param.retr = 2;
668 xmit_param.interval = 20;
669
670 receive_order(CONFIG_BT_MESH_ADV_BUF_COUNT);
671
672 PASS();
673 }
674
test_rx_random_order(void)675 static void test_rx_random_order(void)
676 {
677 bt_init();
678
679 xmit_param.retr = 0;
680 xmit_param.interval = 20;
681
682 receive_order(3);
683
684 PASS();
685 }
686
687 #define TEST_CASE(role, name, description) \
688 { \
689 .test_id = "adv_" #role "_" #name, \
690 .test_descr = description, \
691 .test_pre_init_f = test_##role##_init, \
692 .test_tick_f = bt_mesh_test_timeout, \
693 .test_main_f = test_##role##_##name, \
694 }
695
696 static const struct bst_test_instance test_adv[] = {
697 TEST_CASE(tx, cb_single, "ADV: tx cb parameter checker"),
698 TEST_CASE(tx, cb_multi, "ADV: tx cb sequence checker"),
699 TEST_CASE(tx, proxy_mixin, "ADV: proxy mix-in gatt adv"),
700 TEST_CASE(tx, send_order, "ADV: tx send order"),
701 TEST_CASE(tx, reverse_order, "ADV: tx reversed order"),
702 TEST_CASE(tx, random_order, "ADV: tx random order"),
703
704 TEST_CASE(rx, xmit, "ADV: xmit checker"),
705 TEST_CASE(rx, proxy_mixin, "ADV: proxy mix-in scanner"),
706 TEST_CASE(rx, receive_order, "ADV: rx receive order"),
707 TEST_CASE(rx, random_order, "ADV: rx random order"),
708
709 BSTEST_END_MARKER
710 };
711
test_adv_install(struct bst_test_list * tests)712 struct bst_test_list *test_adv_install(struct bst_test_list *tests)
713 {
714 tests = bst_add_tests(tests, test_adv);
715 return tests;
716 }
717