1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stddef.h>
8
9 #include <zephyr/sys/byteorder.h>
10 #include <zephyr/sys/printk.h>
11 #include <zephyr/sys/util.h>
12
13 #include <zephyr/bluetooth/bluetooth.h>
14 #include <zephyr/bluetooth/hci.h>
15 #include <zephyr/bluetooth/iso.h>
16
17 #include "subsys/bluetooth/host/hci_core.h"
18 #include "subsys/bluetooth/controller/include/ll.h"
19 #include "subsys/bluetooth/controller/util/memq.h"
20 #include "subsys/bluetooth/controller/ll_sw/lll.h"
21
22 /* For VS data path */
23 #include "subsys/bluetooth/controller/ll_sw/isoal.h"
24 #include "subsys/bluetooth/controller/ll_sw/ull_iso_types.h"
25
26 #include "bs_types.h"
27 #include "bs_tracing.h"
28 #include "time_machine.h"
29 #include "bstests.h"
30
31 #define FAIL(...) \
32 do { \
33 bst_result = Failed; \
34 bs_trace_error_time_line(__VA_ARGS__); \
35 } while (0)
36
37 #define PASS(...) \
38 do { \
39 bst_result = Passed; \
40 bs_trace_info_time(1, __VA_ARGS__); \
41 } while (0)
42
43 extern enum bst_result_t bst_result;
44
45 static uint8_t mfg_data1[] = { 0xff, 0xff, 0x01, 0x02, 0x03, 0x04 };
46 static uint8_t mfg_data2[] = { 0xff, 0xff, 0x05 };
47
48 static const struct bt_data per_ad_data1[] = {
49 BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data1, 6),
50 };
51
52 static const struct bt_data per_ad_data2[] = {
53 BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data2, 3),
54 };
55
56 static uint8_t chan_map[] = { 0x1F, 0XF1, 0x1F, 0xF1, 0x1F };
57
58 static bool volatile is_iso_connected;
59 static uint8_t volatile is_iso_disconnected;
60 static bool volatile deleting_pa_sync;
61
62 #if !defined(CONFIG_TEST_LL_INTERFACE)
63 static void iso_connected(struct bt_iso_chan *chan);
64 static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason);
65 static void iso_recv(struct bt_iso_chan *chan,
66 const struct bt_iso_recv_info *info, struct net_buf *buf);
67
68 static struct bt_iso_chan_ops iso_ops = {
69 .connected = iso_connected,
70 .disconnected = iso_disconnected,
71 .recv = iso_recv,
72 };
73
74 static struct bt_iso_chan_path iso_path_rx = {
75 .pid = BT_HCI_DATAPATH_ID_HCI
76 };
77
78 static struct bt_iso_chan_qos bis_iso_qos;
79 static struct bt_iso_chan_io_qos iso_tx_qos;
80 static struct bt_iso_chan_io_qos iso_rx_qos = {
81 .path = &iso_path_rx
82 };
83
84 static struct bt_iso_chan bis_iso_chan = {
85 .ops = &iso_ops,
86 .qos = &bis_iso_qos,
87 };
88
89 #define BIS_ISO_CHAN_COUNT 1
90 static struct bt_iso_chan *bis_channels[BIS_ISO_CHAN_COUNT] = { &bis_iso_chan };
91 static uint16_t seq_num;
92
93 NET_BUF_POOL_FIXED_DEFINE(bis_tx_pool, BIS_ISO_CHAN_COUNT,
94 BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
95 CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
96
97 #if defined(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH)
98 static uint8_t test_rx_buffer[CONFIG_BT_CTLR_SYNC_ISO_PDU_LEN_MAX];
99 static bool is_iso_vs_emitted;
100
test_sink_sdu_alloc(const struct isoal_sink * sink_ctx,const struct isoal_pdu_rx * valid_pdu,struct isoal_sdu_buffer * sdu_buffer)101 static isoal_status_t test_sink_sdu_alloc(const struct isoal_sink *sink_ctx,
102 const struct isoal_pdu_rx *valid_pdu,
103 struct isoal_sdu_buffer *sdu_buffer)
104 {
105 sdu_buffer->dbuf = test_rx_buffer;
106 sdu_buffer->size = sizeof(test_rx_buffer);
107
108 return ISOAL_STATUS_OK;
109 }
110
111
test_sink_sdu_emit(const struct isoal_sink * sink_ctx,const struct isoal_emitted_sdu_frag * sdu_frag,const struct isoal_emitted_sdu * sdu)112 static isoal_status_t test_sink_sdu_emit(const struct isoal_sink *sink_ctx,
113 const struct isoal_emitted_sdu_frag *sdu_frag,
114 const struct isoal_emitted_sdu *sdu)
115 {
116 printk("Vendor sink SDU fragment size %u / %u, seq_num %u, ts %u\n",
117 sdu_frag->sdu_frag_size, sdu->total_sdu_size, sdu_frag->sdu.sn,
118 sdu_frag->sdu.timestamp);
119 is_iso_vs_emitted = true;
120
121 return ISOAL_STATUS_OK;
122 }
123
test_sink_sdu_write(void * dbuf,const size_t sdu_written,const uint8_t * pdu_payload,const size_t consume_len)124 static isoal_status_t test_sink_sdu_write(void *dbuf,
125 const size_t sdu_written,
126 const uint8_t *pdu_payload,
127 const size_t consume_len)
128 {
129 memcpy((uint8_t *)dbuf + sdu_written, pdu_payload, consume_len);
130
131 return ISOAL_STATUS_OK;
132 }
133
134
ll_data_path_sink_create(uint16_t handle,struct ll_iso_datapath * datapath,isoal_sink_sdu_alloc_cb * sdu_alloc,isoal_sink_sdu_emit_cb * sdu_emit,isoal_sink_sdu_write_cb * sdu_write)135 bool ll_data_path_sink_create(uint16_t handle, struct ll_iso_datapath *datapath,
136 isoal_sink_sdu_alloc_cb *sdu_alloc,
137 isoal_sink_sdu_emit_cb *sdu_emit,
138 isoal_sink_sdu_write_cb *sdu_write)
139 {
140 ARG_UNUSED(handle);
141 ARG_UNUSED(datapath);
142
143 *sdu_alloc = test_sink_sdu_alloc;
144 *sdu_emit = test_sink_sdu_emit;
145 *sdu_write = test_sink_sdu_write;
146
147 printk("VS data path sink created\n");
148 return true;
149 }
150 #endif /* CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH */
151
152 #define BUF_ALLOC_TIMEOUT_MS (30) /* milliseconds */
153 NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT,
154 BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
155 CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
156
157 static struct k_work_delayable iso_send_work;
158
159 BUILD_ASSERT(sizeof(seq_num) <= CONFIG_BT_ISO_TX_MTU);
160
iso_send(struct k_work * work)161 static void iso_send(struct k_work *work)
162 {
163 static uint8_t iso_data[CONFIG_BT_ISO_TX_MTU];
164 static bool data_initialized;
165 struct net_buf *buf;
166 size_t iso_data_len;
167 int ret;
168
169 if (!data_initialized) {
170 data_initialized = true;
171
172 for (size_t i = 0; i < ARRAY_SIZE(iso_data); i++) {
173 iso_data[i] = (uint8_t)i;
174 }
175 }
176
177 buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT_MS));
178 if (!buf) {
179 FAIL("Data buffer allocate timeout on channel\n");
180 return;
181 }
182
183 net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
184 sys_put_le16(seq_num, iso_data);
185 iso_data_len = MAX(sizeof(seq_num), ((seq_num % CONFIG_BT_ISO_TX_MTU) + 1));
186 net_buf_add_mem(buf, iso_data, iso_data_len);
187
188 bs_trace_info_time(4, "ISO send: seq_num %u\n", seq_num);
189 ret = bt_iso_chan_send(&bis_iso_chan, buf, seq_num++);
190 if (ret < 0) {
191 FAIL("Unable to broadcast data on channel (%d)\n", ret);
192 net_buf_unref(buf);
193 return;
194 }
195
196 k_work_schedule(&iso_send_work, K_USEC(9970));
197 }
198 #endif /* !CONFIG_TEST_LL_INTERFACE */
199
setup_ext_adv(struct bt_le_ext_adv ** adv)200 static void setup_ext_adv(struct bt_le_ext_adv **adv)
201 {
202 int err;
203
204 printk("Create advertising set...");
205 err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, NULL, adv);
206 if (err) {
207 FAIL("Failed to create advertising set (err %d)\n", err);
208 return;
209 }
210 printk("success.\n");
211
212 printk("Setting Periodic Advertising parameters...");
213 err = bt_le_per_adv_set_param(*adv, BT_LE_PER_ADV_DEFAULT);
214 if (err) {
215 FAIL("Failed to set periodic advertising parameters (err %d)\n",
216 err);
217 return;
218 }
219 printk("success.\n");
220
221 printk("Enable Periodic Advertising...");
222 err = bt_le_per_adv_start(*adv);
223 if (err) {
224 FAIL("Failed to enable periodic advertising (err %d)\n", err);
225 return;
226 }
227 printk("success.\n");
228
229 printk("Start extended advertising...");
230 err = bt_le_ext_adv_start(*adv, BT_LE_EXT_ADV_START_DEFAULT);
231 if (err) {
232 printk("Failed to start extended advertising (err %d)\n", err);
233 return;
234 }
235 printk("success.\n");
236 }
237
teardown_ext_adv(struct bt_le_ext_adv * adv)238 static void teardown_ext_adv(struct bt_le_ext_adv *adv)
239 {
240 int err;
241
242 printk("Stop Periodic Advertising...");
243 err = bt_le_per_adv_stop(adv);
244 if (err) {
245 FAIL("Failed to stop periodic advertising (err %d)\n", err);
246 return;
247 }
248 printk("success.\n");
249
250 printk("Stop Extended Advertising...");
251 err = bt_le_ext_adv_stop(adv);
252 if (err) {
253 FAIL("Failed to stop extended advertising (err %d)\n", err);
254 return;
255 }
256 printk("success.\n");
257
258 printk("Deleting Extended Advertising...");
259 err = bt_le_ext_adv_delete(adv);
260 if (err) {
261 FAIL("Failed to delete extended advertising (err %d)\n", err);
262 return;
263 }
264 printk("success.\n");
265 }
266
267 #if defined(CONFIG_TEST_LL_INTERFACE)
create_ll_big(uint8_t big_handle,struct bt_le_ext_adv * adv)268 static void create_ll_big(uint8_t big_handle, struct bt_le_ext_adv *adv)
269 {
270 uint16_t max_sdu = CONFIG_BT_CTLR_ADV_ISO_PDU_LEN_MAX;
271 uint8_t bcode[BT_ISO_BROADCAST_CODE_SIZE] = { 0 };
272 uint32_t sdu_interval = 10000; /* us */
273 uint16_t max_latency = 10; /* ms */
274 uint8_t encryption = 0;
275 uint8_t bis_count = 1; /* TODO: Add support for multiple BIS per BIG */
276 uint8_t phy = BIT(1);
277 uint8_t packing = 0;
278 uint8_t framing = 0;
279 uint8_t adv_handle;
280 uint8_t rtn = 0;
281 int err;
282
283 printk("Creating LL BIG...");
284 /* Assume that index == handle */
285 adv_handle = bt_le_ext_adv_get_index(adv);
286
287 err = ll_big_create(big_handle, adv_handle, bis_count, sdu_interval,
288 max_sdu, max_latency, rtn, phy, packing, framing,
289 encryption, bcode);
290 if (err) {
291 FAIL("Could not create BIG: %d\n", err);
292 return;
293 }
294 printk("success.\n");
295 }
296
terminate_ll_big(uint8_t big_handle)297 static void terminate_ll_big(uint8_t big_handle)
298 {
299 int err;
300
301 printk("Terminating LL BIG...");
302 err = ll_big_terminate(big_handle, BT_HCI_ERR_LOCALHOST_TERM_CONN);
303 if (err) {
304 FAIL("Could not terminate BIG: %d\n", err);
305 return;
306 }
307 printk("success.\n");
308 }
309
310 #else /* !CONFIG_TEST_LL_INTERFACE */
create_big(struct bt_le_ext_adv * adv,struct bt_iso_big ** big)311 static void create_big(struct bt_le_ext_adv *adv, struct bt_iso_big **big)
312 {
313 struct bt_iso_big_create_param big_create_param = { 0 };
314 int err;
315
316 printk("Creating BIG...\n");
317 big_create_param.bis_channels = bis_channels;
318 big_create_param.num_bis = BIS_ISO_CHAN_COUNT;
319 big_create_param.encryption = false;
320 big_create_param.interval = 10000; /* us */
321 big_create_param.latency = 10; /* milliseconds */
322 big_create_param.packing = 0; /* 0 - sequential; 1 - interleaved */
323 big_create_param.framing = 0; /* 0 - unframed; 1 - framed */
324 iso_tx_qos.sdu = CONFIG_BT_ISO_TX_MTU; /* bytes */
325 iso_tx_qos.rtn = 2;
326 iso_tx_qos.phy = BT_GAP_LE_PHY_2M;
327 bis_iso_qos.tx = &iso_tx_qos;
328 bis_iso_qos.rx = NULL;
329 err = bt_iso_big_create(adv, &big_create_param, big);
330 if (err) {
331 FAIL("Could not create BIG: %d\n", err);
332 return;
333 }
334 printk("success.\n");
335
336 printk("Wait for ISO connected callback...");
337 while (!is_iso_connected) {
338 k_sleep(K_MSEC(100));
339 }
340 printk("ISO connected\n");
341 }
342
terminate_big(struct bt_iso_big * big)343 static void terminate_big(struct bt_iso_big *big)
344 {
345 int err;
346
347 printk("Terminating BIG...\n");
348 err = bt_iso_big_terminate(big);
349 if (err) {
350 FAIL("Could not terminate BIG: %d\n", err);
351 return;
352 }
353 printk("success.\n");
354
355 printk("Wait for ISO disconnected callback...");
356 while (is_iso_disconnected == 0U) {
357 k_sleep(K_MSEC(100));
358 }
359 printk("ISO disconnected\n");
360 }
361 #endif /* !CONFIG_TEST_LL_INTERFACE */
362
363 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
create_advanced_big(struct bt_le_ext_adv * adv,struct bt_iso_big ** big)364 static void create_advanced_big(struct bt_le_ext_adv *adv, struct bt_iso_big **big)
365 {
366 struct bt_iso_big_create_param big_create_param;
367 int err;
368
369 printk("Creating BIG...\n");
370 big_create_param.bis_channels = bis_channels;
371 big_create_param.num_bis = BIS_ISO_CHAN_COUNT;
372 big_create_param.encryption = false;
373 big_create_param.interval = 10000; /* us */
374 big_create_param.packing = 0; /* 0 - sequential; 1 - interleaved */
375 big_create_param.framing = 0; /* 0 - unframed; 1 - framed */
376 big_create_param.irc = BT_ISO_IRC_MIN;
377 big_create_param.pto = BT_ISO_PTO_MIN;
378 big_create_param.iso_interval = big_create_param.interval / 1250U; /* N * 10 ms */
379
380 iso_tx_qos.sdu = 502; /* bytes */
381 iso_tx_qos.phy = BT_GAP_LE_PHY_2M;
382 iso_tx_qos.max_pdu = BT_ISO_PDU_MAX;
383 iso_tx_qos.burst_number = BT_ISO_BN_MIN;
384
385 bis_iso_qos.tx = &iso_tx_qos;
386 bis_iso_qos.rx = NULL;
387 bis_iso_qos.num_subevents = BT_ISO_NSE_MIN;
388
389 err = bt_iso_big_create(adv, &big_create_param, big);
390 if (err) {
391 FAIL("Could not create BIG: %d\n", err);
392 return;
393 }
394 printk("success.\n");
395
396 printk("Wait for ISO connected callback...");
397 while (!is_iso_connected) {
398 k_sleep(K_MSEC(100));
399 }
400 printk("ISO connected\n");
401 }
402 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
403
test_iso_main(void)404 static void test_iso_main(void)
405 {
406 struct bt_le_ext_adv *adv;
407 int err;
408
409 printk("\n*ISO broadcast test*\n");
410
411 printk("Bluetooth initializing...");
412 err = bt_enable(NULL);
413 if (err) {
414 FAIL("Could not init BT: %d\n", err);
415 return;
416 }
417 printk("success.\n");
418
419 setup_ext_adv(&adv);
420
421 #if defined(CONFIG_TEST_LL_INTERFACE)
422 uint8_t big_handle = 0;
423
424 create_ll_big(big_handle, adv);
425
426 #else /* !CONFIG_TEST_LL_INTERFACE */
427 struct bt_iso_big *big;
428
429 create_big(adv, &big);
430
431 k_work_init_delayable(&iso_send_work, iso_send);
432 k_work_schedule(&iso_send_work, K_NO_WAIT);
433 #endif /* !CONFIG_TEST_LL_INTERFACE */
434
435 k_sleep(K_MSEC(5000));
436
437 printk("Update periodic advertising data 1...");
438 err = bt_le_per_adv_set_data(adv, per_ad_data1,
439 ARRAY_SIZE(per_ad_data1));
440 if (err) {
441 FAIL("Failed to update periodic advertising data 1 (%d).\n",
442 err);
443 }
444 printk("success.\n");
445
446 k_sleep(K_MSEC(2500));
447
448 printk("Periodic Advertising and ISO Channel Map Update...");
449 err = bt_le_set_chan_map(chan_map);
450 if (err) {
451 FAIL("Channel Map Update failed.\n");
452 }
453 printk("success.\n");
454
455 k_sleep(K_MSEC(2500));
456
457 printk("Update periodic advertising data 2...");
458 err = bt_le_per_adv_set_data(adv, per_ad_data2,
459 ARRAY_SIZE(per_ad_data2));
460 if (err) {
461 FAIL("Failed to update periodic advertising data 2 (%d).\n",
462 err);
463 }
464 printk("success.\n");
465
466 k_sleep(K_MSEC(5000));
467
468 #if defined(CONFIG_TEST_LL_INTERFACE)
469 terminate_ll_big(big_handle);
470
471 #else /* !CONFIG_TEST_LL_INTERFACE */
472 k_work_cancel_delayable(&iso_send_work);
473
474 terminate_big(big);
475 big = NULL;
476
477 #if defined(CONFIG_BT_ISO_TEST_PARAMS)
478 /* Quick check to just verify that creating a BIG using advanced/test
479 * parameters work
480 */
481 create_advanced_big(adv, &big);
482
483 terminate_big(big);
484 big = NULL;
485 #endif /* CONFIG_BT_ISO_TEST_PARAMS */
486 #endif /* !CONFIG_TEST_LL_INTERFACE */
487
488 k_sleep(K_MSEC(10000));
489
490 teardown_ext_adv(adv);
491 adv = NULL;
492
493 PASS("ISO tests Passed\n");
494 }
495
phy2str(uint8_t phy)496 static const char *phy2str(uint8_t phy)
497 {
498 switch (phy) {
499 case 0: return "No packets";
500 case BT_GAP_LE_PHY_1M: return "LE 1M";
501 case BT_GAP_LE_PHY_2M: return "LE 2M";
502 case BT_GAP_LE_PHY_CODED: return "LE Coded";
503 default: return "Unknown";
504 }
505 }
506
507 #if !defined(CONFIG_TEST_LL_INTERFACE)
508 /** Print data as d_0 d_1 d_2 ... d_(n-2) d_(n-1) d_(n) to show the 3 first and 3 last octets
509 *
510 * Examples:
511 * 01
512 * 0102
513 * 010203
514 * 01020304
515 * 0102030405
516 * 010203040506
517 * 010203...050607
518 * 010203...060708
519 * etc.
520 */
iso_print_data(uint8_t * data,size_t data_len)521 static void iso_print_data(uint8_t *data, size_t data_len)
522 {
523 /* Maximum number of octets from each end of the data */
524 const uint8_t max_octets = 3;
525 char data_str[35];
526 size_t str_len;
527
528 str_len = bin2hex(data, MIN(max_octets, data_len), data_str, sizeof(data_str));
529 if (data_len > max_octets) {
530 if (data_len > (max_octets * 2)) {
531 static const char dots[] = "...";
532
533 strcat(&data_str[str_len], dots);
534 str_len += strlen(dots);
535 }
536
537 str_len += bin2hex(data + (data_len - MIN(max_octets, data_len - max_octets)),
538 MIN(max_octets, data_len - max_octets),
539 data_str + str_len,
540 sizeof(data_str) - str_len);
541 }
542
543 printk("\t %s\n", data_str);
544 }
545
546 #define SEQ_NUM_MAX 1000U
547 static uint16_t expected_seq_num[CONFIG_BT_ISO_MAX_CHAN];
548
iso_recv(struct bt_iso_chan * chan,const struct bt_iso_recv_info * info,struct net_buf * buf)549 static void iso_recv(struct bt_iso_chan *chan,
550 const struct bt_iso_recv_info *info, struct net_buf *buf)
551 {
552 uint16_t seq_num;
553 uint8_t index;
554
555 index = bt_conn_index(chan->iso);
556
557 printk("Incoming data channel %p (%u) flags 0x%x seq_num %u ts %u len %u:\n",
558 chan, index, info->flags, info->seq_num, info->ts, buf->len);
559 iso_print_data(buf->data, buf->len);
560
561 seq_num = sys_get_le16(buf->data);
562 if (info->flags & BT_ISO_FLAGS_VALID) {
563 if (seq_num != expected_seq_num[index]) {
564 if (expected_seq_num[index]) {
565 FAIL("ISO data miss match, expected %u actual %u\n",
566 expected_seq_num[index], seq_num);
567 }
568 expected_seq_num[index] = seq_num;
569 }
570
571 expected_seq_num[index]++;
572
573 } else if (expected_seq_num[index] &&
574 expected_seq_num[index] < SEQ_NUM_MAX) {
575 FAIL("%s: Invalid ISO data after valid ISO data reception.\n"
576 "Expected %u\n", __func__, expected_seq_num[index]);
577 }
578 }
579
iso_connected(struct bt_iso_chan * chan)580 static void iso_connected(struct bt_iso_chan *chan)
581 {
582 printk("ISO Channel %p connected\n", chan);
583
584 seq_num = 0U;
585 is_iso_connected = true;
586 }
587
iso_disconnected(struct bt_iso_chan * chan,uint8_t reason)588 static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
589 {
590 printk("ISO Channel %p disconnected with reason 0x%02x\n", chan, reason);
591
592 is_iso_disconnected = reason;
593 }
594 #endif /* !CONFIG_TEST_LL_INTERFACE */
595
596 static bool volatile is_sync;
597
pa_sync_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)598 static void pa_sync_cb(struct bt_le_per_adv_sync *sync,
599 struct bt_le_per_adv_sync_synced_info *info)
600 {
601 char le_addr[BT_ADDR_LE_STR_LEN];
602
603 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
604
605 printk("PER_ADV_SYNC[%u]: [DEVICE]: %s synced, "
606 "Interval 0x%04x (%u ms), PHY %s\n",
607 bt_le_per_adv_sync_get_index(sync), le_addr,
608 info->interval, info->interval * 5 / 4, phy2str(info->phy));
609
610 is_sync = true;
611 }
612
pa_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)613 static void pa_terminated_cb(struct bt_le_per_adv_sync *sync,
614 const struct bt_le_per_adv_sync_term_info *info)
615 {
616 char le_addr[BT_ADDR_LE_STR_LEN];
617
618 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
619
620 printk("PER_ADV_SYNC[%u]: [DEVICE]: %s sync terminated\n",
621 bt_le_per_adv_sync_get_index(sync), le_addr);
622
623 if (!deleting_pa_sync) {
624 FAIL("PA terminated unexpectedly\n");
625 } else {
626 deleting_pa_sync = false;
627 }
628 }
629
630 static bool volatile is_sync_recv;
631
pa_recv_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_recv_info * info,struct net_buf_simple * buf)632 static void pa_recv_cb(struct bt_le_per_adv_sync *sync,
633 const struct bt_le_per_adv_sync_recv_info *info,
634 struct net_buf_simple *buf)
635 {
636 char le_addr[BT_ADDR_LE_STR_LEN];
637
638 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
639
640 printk("PER_ADV_SYNC[%u]: [DEVICE]: %s, tx_power %i, "
641 "RSSI %i, CTE %u, data length %u\n",
642 bt_le_per_adv_sync_get_index(sync), le_addr, info->tx_power,
643 info->rssi, info->cte_type, buf->len);
644
645 is_sync_recv = true;
646 }
647
648 static void
pa_state_changed_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_state_info * info)649 pa_state_changed_cb(struct bt_le_per_adv_sync *sync,
650 const struct bt_le_per_adv_sync_state_info *info)
651 {
652 printk("PER_ADV_SYNC[%u]: state changed, receive %s.\n",
653 bt_le_per_adv_sync_get_index(sync),
654 info->recv_enabled ? "enabled" : "disabled");
655 }
656
657 static bool volatile is_big_info;
658
pa_biginfo_cb(struct bt_le_per_adv_sync * sync,const struct bt_iso_biginfo * biginfo)659 static void pa_biginfo_cb(struct bt_le_per_adv_sync *sync,
660 const struct bt_iso_biginfo *biginfo)
661 {
662 char le_addr[BT_ADDR_LE_STR_LEN];
663
664 bt_addr_le_to_str(biginfo->addr, le_addr, sizeof(le_addr));
665 printk("BIG INFO[%u]: [DEVICE]: %s, sid 0x%02x, "
666 "num_bis %u, nse %u, interval 0x%04x (%u ms), "
667 "bn %u, pto %u, irc %u, max_pdu %u, "
668 "sdu_interval %u us, max_sdu %u, phy %s, "
669 "%s framing, %sencrypted\n",
670 bt_le_per_adv_sync_get_index(sync), le_addr, biginfo->sid,
671 biginfo->num_bis, biginfo->sub_evt_count,
672 biginfo->iso_interval,
673 (biginfo->iso_interval * 5 / 4),
674 biginfo->burst_number, biginfo->offset,
675 biginfo->rep_count, biginfo->max_pdu, biginfo->sdu_interval,
676 biginfo->max_sdu, phy2str(biginfo->phy),
677 biginfo->framing ? "with" : "without",
678 biginfo->encryption ? "" : "not ");
679
680 if (!is_big_info) {
681 is_big_info = true;
682 }
683 }
684
685 static struct bt_le_per_adv_sync_cb sync_cb = {
686 .synced = pa_sync_cb,
687 .term = pa_terminated_cb,
688 .recv = pa_recv_cb,
689 .state_changed = pa_state_changed_cb,
690 .biginfo = pa_biginfo_cb,
691 };
692
693 #define NAME_LEN 30
694
data_cb(struct bt_data * data,void * user_data)695 static bool data_cb(struct bt_data *data, void *user_data)
696 {
697 char *name = user_data;
698
699 switch (data->type) {
700 case BT_DATA_NAME_SHORTENED:
701 case BT_DATA_NAME_COMPLETE:
702 memcpy(name, data->data, MIN(data->data_len, NAME_LEN - 1));
703 return false;
704 default:
705 return true;
706 }
707 }
708
709 static bool volatile is_periodic;
710 static bt_addr_le_t per_addr;
711 static uint8_t per_sid;
712
scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * buf)713 static void scan_recv(const struct bt_le_scan_recv_info *info,
714 struct net_buf_simple *buf)
715 {
716 char le_addr[BT_ADDR_LE_STR_LEN];
717 char name[NAME_LEN];
718
719 (void)memset(name, 0, sizeof(name));
720
721 bt_data_parse(buf, data_cb, name);
722
723 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
724 printk("[DEVICE]: %s, AD evt type %u, Tx Pwr: %i, RSSI %i %s "
725 "C:%u S:%u D:%u SR:%u E:%u Prim: %s, Secn: %s, "
726 "Interval: 0x%04x (%u ms), SID: %u\n",
727 le_addr, info->adv_type, info->tx_power, info->rssi, name,
728 (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0,
729 (info->adv_props & BT_GAP_ADV_PROP_SCANNABLE) != 0,
730 (info->adv_props & BT_GAP_ADV_PROP_DIRECTED) != 0,
731 (info->adv_props & BT_GAP_ADV_PROP_SCAN_RESPONSE) != 0,
732 (info->adv_props & BT_GAP_ADV_PROP_EXT_ADV) != 0,
733 phy2str(info->primary_phy), phy2str(info->secondary_phy),
734 info->interval, info->interval * 5 / 4, info->sid);
735
736 if (info->interval) {
737 if (!is_periodic) {
738 is_periodic = true;
739 per_sid = info->sid;
740 bt_addr_le_copy(&per_addr, info->addr);
741 }
742 }
743 }
744
745 static struct bt_le_scan_cb scan_callbacks = {
746 .recv = scan_recv,
747 };
748
test_iso_recv_main(void)749 static void test_iso_recv_main(void)
750 {
751 struct bt_le_scan_param scan_param = {
752 .type = BT_LE_SCAN_TYPE_ACTIVE,
753 .options = BT_LE_SCAN_OPT_NONE,
754 .interval = 0x0004,
755 .window = 0x0004,
756 };
757 struct bt_le_per_adv_sync_param sync_create_param;
758 struct bt_le_per_adv_sync *sync = NULL;
759 int err;
760
761 printk("\n*ISO broadcast test*\n");
762
763 printk("Bluetooth initializing...");
764 err = bt_enable(NULL);
765 if (err) {
766 FAIL("Could not init BT: %d\n", err);
767 return;
768 }
769 printk("success.\n");
770
771 printk("Scan callbacks register...");
772 bt_le_scan_cb_register(&scan_callbacks);
773 printk("success.\n");
774
775 printk("Periodic Advertising callbacks register...");
776 bt_le_per_adv_sync_cb_register(&sync_cb);
777 printk("Success.\n");
778
779 printk("Start scanning...");
780 is_periodic = false;
781 err = bt_le_scan_start(&scan_param, NULL);
782 if (err) {
783 FAIL("Could not start scan: %d\n", err);
784 return;
785 }
786 printk("success.\n");
787
788 while (!is_periodic) {
789 k_sleep(K_MSEC(100));
790 }
791 printk("Periodic Advertising found (SID: %u)\n", per_sid);
792
793 printk("Creating Periodic Advertising Sync...");
794 is_sync = false;
795 bt_addr_le_copy(&sync_create_param.addr, &per_addr);
796 sync_create_param.options =
797 BT_LE_PER_ADV_SYNC_OPT_REPORTING_INITIALLY_DISABLED;
798 sync_create_param.sid = per_sid;
799 sync_create_param.skip = 0;
800 sync_create_param.timeout = 0xa;
801 err = bt_le_per_adv_sync_create(&sync_create_param, &sync);
802 if (err) {
803 FAIL("Could not create sync: %d\n", err);
804 return;
805 }
806 printk("success.\n");
807
808 /* TODO: Enable when advertiser is added */
809 printk("Waiting for sync...");
810 while (!is_sync) {
811 k_sleep(K_MSEC(100));
812 }
813
814 printk("Stop scanning...");
815 err = bt_le_scan_stop();
816 if (err) {
817 FAIL("Could not stop scan: %d\n", err);
818 return;
819 }
820 printk("success.\n");
821
822 printk("Wait for BIG Info Advertising Report...");
823 is_big_info = false;
824 while (!is_big_info) {
825 k_sleep(K_MSEC(100));
826 }
827 printk("success.\n");
828
829 #if defined(CONFIG_TEST_LL_INTERFACE)
830 uint8_t bcode[BT_ISO_BROADCAST_CODE_SIZE] = { 0 };
831 uint16_t sync_timeout = 10;
832 uint8_t bis[1] = { 0x01, };
833 uint8_t big_handle = 0;
834 uint8_t encryption = 0;
835 uint8_t mse = 0;
836
837 printk("Creating BIG Sync...");
838 err = ll_big_sync_create(big_handle, sync->handle, encryption, bcode,
839 mse, sync_timeout, ARRAY_SIZE(bis), bis);
840 if (err) {
841 FAIL("Could not create BIG sync: %d\n", err);
842 return;
843 }
844 printk("success.\n");
845
846 k_sleep(K_MSEC(5000));
847
848 printk("Terminating BIG Sync...");
849 struct node_rx_pdu *node_rx = NULL;
850
851 err = ll_big_sync_terminate(big_handle, (void **)&node_rx);
852 if (err) {
853 FAIL("Could not terminate BIG sync: %d\n", err);
854 return;
855 }
856 printk("success.\n");
857
858 if (node_rx) {
859 FAIL("Generated Node Rx for synchronized BIG.\n");
860 }
861
862 k_sleep(K_MSEC(5000));
863
864 printk("Creating BIG Sync after terminate...");
865 err = ll_big_sync_create(big_handle, sync->handle, encryption, bcode,
866 mse, sync_timeout, ARRAY_SIZE(bis), bis);
867 if (err) {
868 FAIL("Could not create BIG sync: %d\n", err);
869 return;
870 }
871 printk("success.\n");
872
873 printk("Terminating BIG Sync...");
874 node_rx = NULL;
875 err = ll_big_sync_terminate(big_handle, (void **)&node_rx);
876 if (err) {
877 FAIL("Could not terminate BIG sync: %d\n", err);
878 return;
879 }
880 printk("success.\n");
881
882 if (node_rx) {
883 node_rx->hdr.next = NULL;
884 ll_rx_mem_release((void **)&node_rx);
885 }
886
887 printk("Deleting Periodic Advertising Sync...");
888 deleting_pa_sync = true;
889 err = bt_le_per_adv_sync_delete(sync);
890 if (err) {
891 FAIL("Failed to delete periodic advertising sync (err %d)\n",
892 err);
893 return;
894 }
895 printk("success.\n");
896
897 #else /* !CONFIG_TEST_LL_INTERFACE */
898 struct bt_iso_big_sync_param big_param = { 0, };
899 struct bt_iso_big *big;
900
901 printk("ISO BIG create sync...");
902 is_iso_connected = false;
903 bis_iso_qos.tx = NULL;
904 bis_iso_qos.rx = &iso_rx_qos;
905 big_param.bis_channels = bis_channels;
906 big_param.num_bis = BIS_ISO_CHAN_COUNT;
907 big_param.bis_bitfield = BT_ISO_BIS_INDEX_BIT(1); /* BIS 1 selected */
908 big_param.mse = 1;
909 big_param.sync_timeout = 100; /* 1000 ms */
910 big_param.encryption = false;
911 iso_path_rx.pid = BT_HCI_DATAPATH_ID_HCI;
912 memset(big_param.bcode, 0, sizeof(big_param.bcode));
913 err = bt_iso_big_sync(sync, &big_param, &big);
914 if (err) {
915 FAIL("Could not create BIG sync: %d\n", err);
916 return;
917 }
918 printk("success.\n");
919
920 printk("Wait for ISO connected callback...");
921 while (!is_iso_connected) {
922 k_sleep(K_MSEC(100));
923 }
924
925 printk("ISO terminate BIG...");
926 is_iso_disconnected = 0U;
927 err = bt_iso_big_terminate(big);
928 if (err) {
929 FAIL("Could not terminate BIG sync: %d\n", err);
930 return;
931 }
932 printk("success.\n");
933
934 printk("Waiting for ISO disconnected callback...\n");
935 while (!is_iso_disconnected) {
936 k_sleep(K_MSEC(100));
937 }
938 printk("disconnected.\n");
939
940 if (is_iso_disconnected != BT_HCI_ERR_LOCALHOST_TERM_CONN) {
941 FAIL("Local Host Terminate Failed.\n");
942 }
943
944 printk("ISO BIG create sync (test remote disconnect)...");
945 is_iso_connected = false;
946 is_iso_disconnected = 0U;
947 memset(expected_seq_num, 0U, sizeof(expected_seq_num));
948 err = bt_iso_big_sync(sync, &big_param, &big);
949 if (err) {
950 FAIL("Could not create BIG sync: %d\n", err);
951 return;
952 }
953 printk("success.\n");
954
955 printk("Wait for ISO connected callback...");
956 while (!is_iso_connected) {
957 k_sleep(K_MSEC(100));
958 }
959 printk("connected.\n");
960
961 printk("Waiting for ISO disconnected callback...\n");
962 while (!is_iso_disconnected) {
963 k_sleep(K_MSEC(100));
964 }
965 printk("disconnected.\n");
966
967 if (is_iso_disconnected != BT_HCI_ERR_REMOTE_USER_TERM_CONN) {
968 FAIL("Remote Host Terminate Failed.\n");
969 }
970
971 printk("Periodic sync receive enable...\n");
972 err = bt_le_per_adv_sync_recv_enable(sync);
973 if (err) {
974 printk("failed (err %d)\n", err);
975 return;
976 }
977 printk("receive enabled.\n");
978
979 uint8_t check_countdown = 3;
980
981 printk("Waiting for remote BIG terminate by checking for missing "
982 "%u BIG Info report...\n", check_countdown);
983 do {
984 is_sync_recv = false;
985 is_big_info = false;
986 while (!is_sync_recv) {
987 k_sleep(K_MSEC(100));
988 }
989
990 k_sleep(K_MSEC(100));
991
992 if (!is_big_info) {
993 if (!--check_countdown) {
994 break;
995 }
996 }
997 } while (1);
998 printk("success.\n");
999
1000 printk("Deleting Periodic Advertising Sync...");
1001 deleting_pa_sync = true;
1002 err = bt_le_per_adv_sync_delete(sync);
1003 if (err) {
1004 FAIL("Failed to delete periodic advertising sync (err %d)\n",
1005 err);
1006 return;
1007 }
1008 printk("success.\n");
1009
1010 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
1011 if (expected_seq_num[chan] < SEQ_NUM_MAX) {
1012 FAIL("ISO Data reception incomplete %u (%u).\n",
1013 expected_seq_num[chan], SEQ_NUM_MAX);
1014 return;
1015 }
1016 }
1017 #endif /* !CONFIG_TEST_LL_INTERFACE */
1018
1019 PASS("ISO recv test Passed\n");
1020 }
1021
1022 #if defined(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH)
test_iso_recv_vs_dp_main(void)1023 static void test_iso_recv_vs_dp_main(void)
1024 {
1025 struct bt_le_scan_param scan_param = {
1026 .type = BT_LE_SCAN_TYPE_ACTIVE,
1027 .options = BT_LE_SCAN_OPT_NONE,
1028 .interval = 0x0004,
1029 .window = 0x0004,
1030 };
1031 struct bt_le_per_adv_sync_param sync_create_param;
1032 struct bt_le_per_adv_sync *sync = NULL;
1033 int err;
1034
1035 printk("Bluetooth initializing... ");
1036 err = bt_enable(NULL);
1037 if (err) {
1038 FAIL("Could not init BT: %d\n", err);
1039 return;
1040 }
1041 printk("success.\n");
1042
1043 printk("Scan callbacks register... ");
1044 bt_le_scan_cb_register(&scan_callbacks);
1045 printk("success.\n");
1046
1047 printk("Periodic Advertising callbacks register... ");
1048 bt_le_per_adv_sync_cb_register(&sync_cb);
1049 printk("success.\n");
1050
1051 printk("Configure vendor data path... ");
1052 err = bt_configure_data_path(BT_HCI_DATAPATH_DIR_CTLR_TO_HOST,
1053 BT_HCI_DATAPATH_ID_VS, 0U, NULL);
1054 if (err) {
1055 FAIL("Failed (err %d)\n", err);
1056 return;
1057 }
1058
1059 printk("success.\n");
1060 printk("Start scanning... ");
1061 is_periodic = false;
1062 err = bt_le_scan_start(&scan_param, NULL);
1063 if (err) {
1064 FAIL("Could not start scan: %d\n", err);
1065 return;
1066 }
1067 printk("success.\n");
1068
1069 while (!is_periodic) {
1070 k_sleep(K_MSEC(100));
1071 }
1072 printk("Periodic Advertising found (SID: %u)\n", per_sid);
1073
1074 printk("Creating Periodic Advertising Sync... ");
1075 is_sync = false;
1076
1077 bt_addr_le_copy(&sync_create_param.addr, &per_addr);
1078 sync_create_param.options =
1079 BT_LE_PER_ADV_SYNC_OPT_REPORTING_INITIALLY_DISABLED;
1080 sync_create_param.sid = per_sid;
1081 sync_create_param.skip = 0;
1082 sync_create_param.timeout = 0xa;
1083
1084 err = bt_le_per_adv_sync_create(&sync_create_param, &sync);
1085 if (err) {
1086 FAIL("Could not create sync: %d\n", err);
1087 return;
1088 }
1089 printk("success.\n");
1090
1091 /* TODO: Enable when advertiser is added */
1092 printk("Waiting for sync...\n");
1093 while (!is_sync) {
1094 k_sleep(K_MSEC(100));
1095 }
1096 printk("success.\n");
1097
1098 printk("Stop scanning... ");
1099 err = bt_le_scan_stop();
1100 if (err) {
1101 FAIL("Could not stop scan: %d\n", err);
1102 return;
1103 }
1104 printk("success.\n");
1105
1106 printk("Wait for BIG Info Advertising Report...\n");
1107 is_big_info = false;
1108 while (!is_big_info) {
1109 k_sleep(K_MSEC(100));
1110 }
1111 printk("success.\n");
1112
1113 struct bt_iso_big_sync_param big_param = { 0, };
1114 struct bt_iso_big *big;
1115
1116 printk("ISO BIG create sync... ");
1117 is_iso_connected = false;
1118 bis_iso_qos.tx = NULL;
1119 bis_iso_qos.rx = &iso_rx_qos;
1120 big_param.bis_channels = bis_channels;
1121 big_param.num_bis = BIS_ISO_CHAN_COUNT;
1122 big_param.bis_bitfield = BT_ISO_BIS_INDEX_BIT(1); /* BIS 1 selected */
1123 big_param.mse = 1;
1124 big_param.sync_timeout = 100; /* 1000 ms */
1125 big_param.encryption = false;
1126 memset(big_param.bcode, 0, sizeof(big_param.bcode));
1127
1128 is_iso_connected = false;
1129 is_iso_disconnected = 0U;
1130 is_iso_vs_emitted = false;
1131 iso_path_rx.pid = BT_HCI_DATAPATH_ID_VS;
1132
1133 err = bt_iso_big_sync(sync, &big_param, &big);
1134 if (err) {
1135 FAIL("Could not create BIG sync: %d\n", err);
1136 return;
1137 }
1138 printk("success.\n");
1139
1140 printk("Wait for ISO connected callback... ");
1141 while (!is_iso_connected) {
1142 k_sleep(K_MSEC(100));
1143 }
1144
1145 /* Allow some SDUs to be received */
1146 k_sleep(K_MSEC(100));
1147
1148 printk("ISO terminate BIG... ");
1149 is_iso_disconnected = 0U;
1150 err = bt_iso_big_terminate(big);
1151 if (err) {
1152 FAIL("Could not terminate BIG sync: %d\n", err);
1153 return;
1154 }
1155 printk("success.\n");
1156
1157 printk("Waiting for ISO disconnected callback...\n");
1158 while (!is_iso_disconnected) {
1159 k_sleep(K_MSEC(100));
1160 }
1161 printk("disconnected.\n");
1162
1163 if (is_iso_disconnected != BT_HCI_ERR_LOCALHOST_TERM_CONN) {
1164 FAIL("Local Host Terminate Failed.\n");
1165 }
1166
1167 if (!is_iso_vs_emitted) {
1168 FAIL("Emitting of VS SDUs failed.\n");
1169 }
1170
1171 printk("success.\n");
1172
1173 printk("Deleting Periodic Advertising Sync... ");
1174 deleting_pa_sync = true;
1175 err = bt_le_per_adv_sync_delete(sync);
1176 if (err) {
1177 FAIL("Failed to delete periodic advertising sync (err %d)\n",
1178 err);
1179 return;
1180 }
1181 printk("success.\n");
1182
1183 PASS("ISO recv VS test Passed\n");
1184 }
1185 #endif /* CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH */
1186
test_iso_init(void)1187 static void test_iso_init(void)
1188 {
1189 bst_ticker_set_next_tick_absolute(60e6);
1190 bst_result = In_progress;
1191 }
1192
test_iso_tick(bs_time_t HW_device_time)1193 static void test_iso_tick(bs_time_t HW_device_time)
1194 {
1195 if (bst_result != Passed) {
1196 FAIL("test failed (not passed after seconds)\n");
1197 }
1198 }
1199
1200 static const struct bst_test_instance test_def[] = {
1201 {
1202 .test_id = "broadcast",
1203 .test_descr = "ISO broadcast",
1204 .test_pre_init_f = test_iso_init,
1205 .test_tick_f = test_iso_tick,
1206 .test_main_f = test_iso_main
1207 },
1208 {
1209 .test_id = "receive",
1210 .test_descr = "ISO receive",
1211 .test_pre_init_f = test_iso_init,
1212 .test_tick_f = test_iso_tick,
1213 .test_main_f = test_iso_recv_main
1214 },
1215 #if defined(CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH)
1216 {
1217 .test_id = "receive_vs_dp",
1218 .test_descr = "ISO receive VS",
1219 .test_pre_init_f = test_iso_init,
1220 .test_tick_f = test_iso_tick,
1221 .test_main_f = test_iso_recv_vs_dp_main
1222 },
1223 #endif /* CONFIG_BT_CTLR_ISO_VENDOR_DATA_PATH */
1224 BSTEST_END_MARKER
1225 };
1226
test_iso_install(struct bst_test_list * tests)1227 struct bst_test_list *test_iso_install(struct bst_test_list *tests)
1228 {
1229 return bst_add_tests(tests, test_def);
1230 }
1231