1 /* main.c - Application main entry point */
2
3 /*
4 * Copyright (c) 2023 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/sys/printk.h>
11 #include <zephyr/sys/byteorder.h>
12
13 #include <zephyr/bluetooth/bluetooth.h>
14 #include <zephyr/bluetooth/conn.h>
15 #include <zephyr/bluetooth/iso.h>
16 #include <zephyr/bluetooth/hci.h>
17
18 #include "bs_types.h"
19 #include "bs_tracing.h"
20 #include "time_machine.h"
21 #include "bstests.h"
22
23 #define FAIL(...) \
24 do { \
25 bst_result = Failed; \
26 bs_trace_error_time_line(__VA_ARGS__); \
27 } while (0)
28
29 #define PASS(...) \
30 do { \
31 bst_result = Passed; \
32 bs_trace_info_time(1, __VA_ARGS__); \
33 } while (0)
34
35 extern enum bst_result_t bst_result;
36
37 static struct bt_iso_chan iso_chan[CONFIG_BT_ISO_MAX_CHAN];
38
39 static K_SEM_DEFINE(sem_peer_addr, 0, 1);
40 static K_SEM_DEFINE(sem_peer_conn, 0, 1);
41 static K_SEM_DEFINE(sem_peer_disc, 0, CONFIG_BT_MAX_CONN);
42 static K_SEM_DEFINE(sem_iso_conn, 0, 1);
43 static K_SEM_DEFINE(sem_iso_disc, 0, 1);
44 static K_SEM_DEFINE(sem_iso_data, CONFIG_BT_ISO_TX_BUF_COUNT,
45 CONFIG_BT_ISO_TX_BUF_COUNT);
46 static bt_addr_le_t peer_addr;
47
48 #define CREATE_CONN_INTERVAL 0x0010
49 #define CREATE_CONN_WINDOW 0x0010
50
51 #define ISO_INTERVAL_US 10000U
52 #define ISO_LATENCY_MS DIV_ROUND_UP(ISO_INTERVAL_US, USEC_PER_MSEC)
53 #define ISO_LATENCY_FT_MS 20U
54
55 #define BT_CONN_US_TO_INTERVAL(t) ((uint16_t)((t) * 4U / 5U / USEC_PER_MSEC))
56
57 #if (CONFIG_BT_CTLR_CENTRAL_SPACING == 0)
58 #define CONN_INTERVAL_MIN BT_CONN_US_TO_INTERVAL(ISO_INTERVAL_US)
59 #else /* CONFIG_BT_CTLR_CENTRAL_SPACING > 0 */
60 #define CONN_INTERVAL_MIN BT_CONN_US_TO_INTERVAL(ISO_INTERVAL_US * CONFIG_BT_MAX_CONN)
61 #endif /* CONFIG_BT_CTLR_CENTRAL_SPACING > 0 */
62
63 #define CONN_INTERVAL_MAX CONN_INTERVAL_MIN
64 #define CONN_TIMEOUT MAX((BT_CONN_INTERVAL_TO_MS(CONN_INTERVAL_MAX) * 6U / 10U), 10U)
65
66 #define ADV_INTERVAL_MIN 0x0020
67 #define ADV_INTERVAL_MAX 0x0020
68
69 #define BT_CONN_LE_CREATE_CONN_CUSTOM \
70 BT_CONN_LE_CREATE_PARAM(BT_CONN_LE_OPT_NONE, \
71 CREATE_CONN_INTERVAL, \
72 CREATE_CONN_WINDOW)
73
74 #define BT_LE_CONN_PARAM_CUSTOM \
75 BT_LE_CONN_PARAM(CONN_INTERVAL_MIN, CONN_INTERVAL_MAX, 0U, CONN_TIMEOUT)
76
77 #if defined(CONFIG_TEST_USE_LEGACY_ADVERTISING)
78 #define BT_LE_ADV_CONN_CUSTOM BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \
79 BT_LE_ADV_OPT_ONE_TIME, \
80 ADV_INTERVAL_MIN, \
81 ADV_INTERVAL_MAX, \
82 NULL)
83 #else /* !CONFIG_TEST_USE_LEGACY_ADVERTISING */
84 #define BT_LE_ADV_CONN_CUSTOM BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \
85 BT_LE_ADV_OPT_EXT_ADV | \
86 BT_LE_ADV_OPT_ONE_TIME, \
87 ADV_INTERVAL_MIN, \
88 ADV_INTERVAL_MAX, \
89 NULL)
90 #endif /* !CONFIG_TEST_USE_LEGACY_ADVERTISING */
91
92 #define SEQ_NUM_MAX 1000U
93
94 #define NAME_LEN 30
95
96 #define BUF_ALLOC_TIMEOUT (50) /* milliseconds */
97 NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT,
98 BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
99 CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
100
data_cb(struct bt_data * data,void * user_data)101 static bool data_cb(struct bt_data *data, void *user_data)
102 {
103 char *name = user_data;
104
105 switch (data->type) {
106 case BT_DATA_NAME_SHORTENED:
107 case BT_DATA_NAME_COMPLETE:
108 memcpy(name, data->data, MIN(data->data_len, NAME_LEN - 1));
109 return false;
110 default:
111 return true;
112 }
113 }
114
phy2str(uint8_t phy)115 static const char *phy2str(uint8_t phy)
116 {
117 switch (phy) {
118 case 0: return "No packets";
119 case BT_GAP_LE_PHY_1M: return "LE 1M";
120 case BT_GAP_LE_PHY_2M: return "LE 2M";
121 case BT_GAP_LE_PHY_CODED: return "LE Coded";
122 default: return "Unknown";
123 }
124 }
125
scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * buf)126 static void scan_recv(const struct bt_le_scan_recv_info *info,
127 struct net_buf_simple *buf)
128 {
129 char le_addr[BT_ADDR_LE_STR_LEN];
130 char name[NAME_LEN];
131
132 (void)memset(name, 0, sizeof(name));
133
134 bt_data_parse(buf, data_cb, name);
135
136 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
137 printk("[DEVICE]: %s, AD evt type %u, Tx Pwr: %i, RSSI %i %s "
138 "C:%u S:%u D:%u SR:%u E:%u Prim: %s, Secn: %s, "
139 "Interval: 0x%04x (%u ms), SID: %u\n",
140 le_addr, info->adv_type, info->tx_power, info->rssi, name,
141 (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0,
142 (info->adv_props & BT_GAP_ADV_PROP_SCANNABLE) != 0,
143 (info->adv_props & BT_GAP_ADV_PROP_DIRECTED) != 0,
144 (info->adv_props & BT_GAP_ADV_PROP_SCAN_RESPONSE) != 0,
145 (info->adv_props & BT_GAP_ADV_PROP_EXT_ADV) != 0,
146 phy2str(info->primary_phy), phy2str(info->secondary_phy),
147 info->interval, info->interval * 5 / 4, info->sid);
148
149 bt_addr_le_copy(&peer_addr, info->addr);
150 k_sem_give(&sem_peer_addr);
151 }
152
153 static struct bt_le_scan_cb scan_callbacks = {
154 .recv = scan_recv,
155 };
156
connected(struct bt_conn * conn,uint8_t err)157 static void connected(struct bt_conn *conn, uint8_t err)
158 {
159 char addr[BT_ADDR_LE_STR_LEN];
160
161 bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
162
163 if (err) {
164 struct bt_conn_info conn_info;
165
166 printk("Failed to connect to %s (%u)\n", addr, err);
167
168 err = bt_conn_get_info(conn, &conn_info);
169 if (err) {
170 FAIL("Failed to get connection info (%d).\n", err);
171 return;
172 }
173
174 printk("%s: %s role %u\n", __func__, addr, conn_info.role);
175
176 if (conn_info.role == BT_CONN_ROLE_CENTRAL) {
177 bt_conn_unref(conn);
178 }
179
180 return;
181 }
182
183 printk("Connected: %s\n", addr);
184
185 k_sem_give(&sem_peer_conn);
186 }
187
disconnected(struct bt_conn * conn,uint8_t reason)188 static void disconnected(struct bt_conn *conn, uint8_t reason)
189 {
190 struct bt_conn_info conn_info;
191 char addr[BT_ADDR_LE_STR_LEN];
192 int err;
193
194 bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
195
196 printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
197
198 err = bt_conn_get_info(conn, &conn_info);
199 if (err) {
200 FAIL("Failed to get connection info (%d).\n", err);
201 return;
202 }
203
204 printk("%s: %s role %u\n", __func__, addr, conn_info.role);
205
206 if (conn_info.role == BT_CONN_ROLE_CENTRAL) {
207 bt_conn_unref(conn);
208 }
209
210 k_sem_give(&sem_peer_disc);
211 }
212
213 BT_CONN_CB_DEFINE(conn_callbacks) = {
214 .connected = connected,
215 .disconnected = disconnected,
216 };
217
disconnect(struct bt_conn * conn,void * data)218 static void disconnect(struct bt_conn *conn, void *data)
219 {
220 char addr[BT_ADDR_LE_STR_LEN];
221 int err;
222
223 bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
224
225 printk("Disconnecting %s...\n", addr);
226 err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
227 if (err) {
228 FAIL("Failed disconnection %s.\n", addr);
229 return;
230 }
231 printk("success.\n");
232 }
233
234 /** 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
235 *
236 * Examples:
237 * 01
238 * 0102
239 * 010203
240 * 01020304
241 * 0102030405
242 * 010203040506
243 * 010203...050607
244 * 010203...060708
245 * etc.
246 */
iso_print_data(uint8_t * data,size_t data_len)247 static void iso_print_data(uint8_t *data, size_t data_len)
248 {
249 /* Maximum number of octets from each end of the data */
250 const uint8_t max_octets = 3;
251 char data_str[35];
252 size_t str_len;
253
254 str_len = bin2hex(data, MIN(max_octets, data_len), data_str, sizeof(data_str));
255 if (data_len > max_octets) {
256 if (data_len > (max_octets * 2)) {
257 static const char dots[] = "...";
258
259 strcat(&data_str[str_len], dots);
260 str_len += strlen(dots);
261 }
262
263 str_len += bin2hex(data + (data_len - MIN(max_octets, data_len - max_octets)),
264 MIN(max_octets, data_len - max_octets),
265 data_str + str_len,
266 sizeof(data_str) - str_len);
267 }
268
269 printk("\t %s\n", data_str);
270 }
271
272 static uint16_t expected_seq_num[CONFIG_BT_ISO_MAX_CHAN];
273
iso_recv(struct bt_iso_chan * chan,const struct bt_iso_recv_info * info,struct net_buf * buf)274 static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info,
275 struct net_buf *buf)
276 {
277 uint16_t seq_num;
278 uint8_t index;
279
280 index = bt_conn_index(chan->iso);
281
282 printk("Incoming data channel %p (%u) flags 0x%x seq_num %u ts %u len %u:\n",
283 chan, index, info->flags, info->seq_num, info->ts, buf->len);
284 iso_print_data(buf->data, buf->len);
285
286 seq_num = sys_get_le32(buf->data);
287 if (info->flags & BT_ISO_FLAGS_VALID) {
288 if (seq_num != expected_seq_num[index]) {
289 if (expected_seq_num[index]) {
290 FAIL("ISO data miss match, expected %u actual %u\n",
291 expected_seq_num[index], seq_num);
292 }
293 expected_seq_num[index] = seq_num;
294 }
295
296 expected_seq_num[index] += 1U;
297
298 #if defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)
299 expected_seq_num[index] += ((CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT - 1U) * 2U);
300 #elif defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)
301 expected_seq_num[index] += ((CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U);
302 #endif
303 } else if (expected_seq_num[index] &&
304 expected_seq_num[index] < SEQ_NUM_MAX) {
305 FAIL("%s: Invalid ISO data after valid ISO data reception.\n"
306 "Expected %u\n", __func__, expected_seq_num[index]);
307 }
308 }
309
iso_sent(struct bt_iso_chan * chan)310 void iso_sent(struct bt_iso_chan *chan)
311 {
312 k_sem_give(&sem_iso_data);
313 }
314
iso_connected(struct bt_iso_chan * chan)315 static void iso_connected(struct bt_iso_chan *chan)
316 {
317 printk("ISO Channel %p connected\n", chan);
318
319 k_sem_give(&sem_iso_conn);
320 }
321
iso_disconnected(struct bt_iso_chan * chan,uint8_t reason)322 static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
323 {
324 printk("ISO Channel %p disconnected (reason 0x%02x)\n", chan, reason);
325
326 k_sem_give(&sem_iso_disc);
327 }
328
329 static struct bt_iso_chan_ops iso_ops = {
330 .connected = iso_connected,
331 .disconnected = iso_disconnected,
332 .recv = iso_recv,
333 .sent = iso_sent,
334 };
335
test_cis_central(void)336 static void test_cis_central(void)
337 {
338 struct bt_iso_chan_io_qos iso_tx[CONFIG_BT_ISO_MAX_CHAN];
339 struct bt_iso_chan_io_qos iso_rx[CONFIG_BT_ISO_MAX_CHAN];
340 struct bt_iso_chan_qos iso_qos[CONFIG_BT_ISO_MAX_CHAN];
341 struct bt_iso_chan *channels[CONFIG_BT_ISO_MAX_CHAN];
342 struct bt_conn *conn_list[CONFIG_BT_MAX_CONN];
343 struct bt_iso_cig_param cig_param;
344 struct bt_iso_cig *cig;
345 int conn_count;
346 int err;
347
348 printk("Bluetooth initializing...");
349 err = bt_enable(NULL);
350 if (err) {
351 FAIL("Could not init BT: %d\n", err);
352 return;
353 }
354 printk("success.\n");
355
356 printk("Scan callbacks register...");
357 bt_le_scan_cb_register(&scan_callbacks);
358 printk("success.\n");
359
360 for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) {
361 iso_tx[i].sdu = CONFIG_BT_ISO_TX_MTU;
362 iso_tx[i].phy = BT_GAP_LE_PHY_2M;
363 iso_tx[i].path = NULL;
364 if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) {
365 iso_tx[i].rtn = 2U;
366 } else {
367 iso_tx[i].rtn = 0U;
368 }
369
370 if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) ||
371 IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) {
372 iso_qos[i].tx = &iso_tx[i];
373 } else {
374 iso_qos[i].tx = NULL;
375 }
376
377 iso_rx[i].sdu = CONFIG_BT_ISO_RX_MTU;
378 iso_rx[i].phy = BT_GAP_LE_PHY_2M;
379 iso_rx[i].path = NULL;
380 if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) {
381 iso_rx[i].rtn = 2U;
382 } else {
383 iso_rx[i].rtn = 0U;
384 }
385
386 if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) {
387 iso_qos[i].rx = &iso_rx[i];
388 } else {
389 iso_qos[i].rx = NULL;
390 }
391
392 iso_chan[i].ops = &iso_ops;
393 iso_chan[i].qos = &iso_qos[i];
394 #if defined(CONFIG_BT_SMP)
395 iso_chan[i].required_sec_level = BT_SECURITY_L2,
396 #endif /* CONFIG_BT_SMP */
397
398 channels[i] = &iso_chan[i];
399 }
400
401 cig_param.cis_channels = channels;
402 cig_param.num_cis = ARRAY_SIZE(channels);
403 cig_param.sca = BT_GAP_SCA_UNKNOWN;
404 cig_param.packing = 0U;
405 cig_param.framing = 0U;
406 cig_param.c_to_p_interval = ISO_INTERVAL_US;
407 cig_param.p_to_c_interval = ISO_INTERVAL_US;
408 if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) {
409 cig_param.c_to_p_latency = ISO_LATENCY_FT_MS;
410 cig_param.p_to_c_latency = ISO_LATENCY_FT_MS;
411 } else {
412 cig_param.c_to_p_latency = ISO_LATENCY_MS;
413 cig_param.p_to_c_latency = ISO_LATENCY_MS;
414 }
415
416 printk("Create CIG...");
417 err = bt_iso_cig_create(&cig_param, &cig);
418 if (err) {
419 FAIL("Failed to create CIG (%d)\n", err);
420 return;
421 }
422 printk("success.\n");
423
424 conn_count = 0;
425
426 #if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)
427 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
428 expected_seq_num[chan] = (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U;
429 }
430 #endif
431
432 #if !defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
433 for (int i = 0; i < CONFIG_BT_MAX_CONN; i++) {
434 #else
435 int i = 0;
436 #endif
437
438 struct bt_conn *conn;
439 int conn_index;
440 int chan;
441
442 printk("Start scanning (%d)...", i);
443 err = bt_le_scan_start(BT_LE_SCAN_PASSIVE_CONTINUOUS, NULL);
444 if (err) {
445 FAIL("Could not start scan: %d\n", err);
446 return;
447 }
448 printk("success.\n");
449
450 printk("Waiting for advertising report...\n");
451 err = k_sem_take(&sem_peer_addr, K_FOREVER);
452 if (err) {
453 FAIL("failed (err %d)\n", err);
454 return;
455 }
456 printk("Found peer advertising.\n");
457
458 printk("Stop scanning... ");
459 err = bt_le_scan_stop();
460 if (err) {
461 FAIL("Could not stop scan: %d\n", err);
462 return;
463 }
464 printk("success.\n");
465
466 printk("Create connection...");
467 err = bt_conn_le_create(&peer_addr, BT_CONN_LE_CREATE_CONN_CUSTOM,
468 BT_LE_CONN_PARAM_CUSTOM, &conn);
469 if (err) {
470 FAIL("Create connection failed (0x%x)\n", err);
471 return;
472 }
473 printk("success.\n");
474
475 printk("Waiting for connection %d...", i);
476 err = k_sem_take(&sem_peer_conn, K_FOREVER);
477 if (err) {
478 FAIL("failed (err %d)\n", err);
479 return;
480 }
481 printk("connected to peer device %d.\n", i);
482
483 conn_list[conn_count] = conn;
484 conn_index = chan = conn_count;
485 conn_count++;
486
487 #if defined(CONFIG_TEST_CONNECT_ACL_FIRST)
488 }
489
490 for (int chan = 0, conn_index = 0;
491 (conn_index < conn_count) && (chan < CONFIG_BT_ISO_MAX_CHAN);
492 conn_index++, chan++) {
493
494 #elif defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
495 for (int chan = 0, conn_index = 0;
496 (chan < CONFIG_BT_ISO_MAX_CHAN); chan++) {
497 #endif
498
499 struct bt_iso_connect_param iso_connect_param;
500
501 printk("Connect ISO Channel %d...", chan);
502 iso_connect_param.acl = conn_list[conn_index];
503 iso_connect_param.iso_chan = &iso_chan[chan];
504 err = bt_iso_chan_connect(&iso_connect_param, 1);
505 if (err) {
506 FAIL("Failed to connect iso (%d)\n", err);
507 return;
508 }
509
510 printk("Waiting for ISO channel connection %d...", chan);
511 err = k_sem_take(&sem_iso_conn, K_FOREVER);
512 if (err) {
513 FAIL("failed (err %d)\n", err);
514 return;
515 }
516 printk("connected to peer %d ISO channel.\n", chan);
517 }
518
519 if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) ||
520 IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) {
521 for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) {
522
523 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
524 uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, };
525 struct net_buf *buf;
526 int ret;
527
528 buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT));
529 if (!buf) {
530 FAIL("Data buffer allocate timeout on channel %d\n", chan);
531 return;
532 }
533
534 net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
535 sys_put_le16(seq_num, iso_data);
536 net_buf_add_mem(buf, iso_data, sizeof(iso_data));
537
538 ret = k_sem_take(&sem_iso_data, K_MSEC(BUF_ALLOC_TIMEOUT));
539 if (ret) {
540 FAIL("k_sem_take for ISO data sent failed.\n");
541 return;
542 }
543
544 printk("ISO send: seq_num %u, chan %d\n", seq_num, chan);
545 ret = bt_iso_chan_send(&iso_chan[chan], buf, seq_num);
546 if (ret < 0) {
547 FAIL("Unable to send data on channel %d : %d\n", chan, ret);
548 net_buf_unref(buf);
549 return;
550 }
551 }
552
553 if ((seq_num % 100) == 0) {
554 printk("Sending value %u\n", seq_num);
555 }
556 }
557
558 k_sleep(K_MSEC(1000));
559 } else {
560 k_sleep(K_SECONDS(11));
561 }
562
563 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
564 printk("ISO disconnect channel %d...", chan);
565 err = bt_iso_chan_disconnect(&iso_chan[chan]);
566 if (err) {
567 FAIL("Failed to disconnect channel %d (%d)\n", chan, err);
568 return;
569 }
570 printk("success\n");
571
572 printk("Waiting for ISO channel disconnect %d...", chan);
573 err = k_sem_take(&sem_iso_disc, K_FOREVER);
574 if (err) {
575 FAIL("failed (err %d)\n", err);
576 return;
577 }
578 printk("disconnected to peer %d ISO channel.\n", chan);
579 }
580
581 bt_conn_foreach(BT_CONN_TYPE_LE, disconnect, NULL);
582
583 #if !defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
584 for (int i = 0; i < CONFIG_BT_MAX_CONN; i++) {
585 #endif
586
587 printk("Waiting for disconnection %d...", i);
588 err = k_sem_take(&sem_peer_disc, K_FOREVER);
589 if (err) {
590 FAIL("failed (err %d)\n", err);
591 return;
592 }
593 printk("Disconnected from peer device %d.\n", i);
594
595 #if !defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
596 }
597 #endif
598
599 if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) {
600 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
601 if (expected_seq_num[chan] < SEQ_NUM_MAX) {
602 FAIL("ISO Data reception incomplete %u (%u).\n",
603 expected_seq_num[chan], SEQ_NUM_MAX);
604 return;
605 }
606 }
607 }
608
609 PASS("Central ISO tests Passed\n");
610 }
611
612 static const struct bt_data ad[] = {
613 BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
614 };
615
616 static struct bt_iso_chan_io_qos iso_rx_p[CONFIG_BT_ISO_MAX_CHAN];
617 static struct bt_iso_chan_qos iso_qos_p[CONFIG_BT_ISO_MAX_CHAN];
618 static struct bt_iso_chan iso_chan_p[CONFIG_BT_ISO_MAX_CHAN];
619 static uint8_t chan_count;
620
621 static int iso_accept(const struct bt_iso_accept_info *info,
622 struct bt_iso_chan **chan)
623 {
624 printk("Incoming request from %p\n", (void *)info->acl);
625
626 if ((chan_count >= CONFIG_BT_ISO_MAX_CHAN) ||
627 iso_chan_p[chan_count].iso) {
628 FAIL("No channels available\n");
629 return -ENOMEM;
630 }
631
632 *chan = &iso_chan_p[chan_count];
633 chan_count++;
634
635 printk("Accepted on channel %p\n", *chan);
636
637 return 0;
638 }
639
640 static struct bt_iso_server iso_server = {
641 #if defined(CONFIG_BT_SMP)
642 .sec_level = BT_SECURITY_L1,
643 #endif /* CONFIG_BT_SMP */
644 .accept = iso_accept,
645 };
646
647 static void test_cis_peripheral(void)
648 {
649 struct bt_iso_chan_io_qos iso_tx_p[CONFIG_BT_ISO_MAX_CHAN];
650 int err;
651
652 printk("Bluetooth initializing...");
653 err = bt_enable(NULL);
654 if (err) {
655 FAIL("Bluetooth init failed (err %d)\n", err);
656 return;
657 }
658 printk("success.\n");
659
660 for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) {
661 iso_tx_p[i].sdu = CONFIG_BT_ISO_TX_MTU;
662 iso_tx_p[i].phy = BT_GAP_LE_PHY_2M;
663 iso_tx_p[i].path = NULL;
664 if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) {
665 iso_tx_p[i].rtn = 2U;
666 } else {
667 iso_tx_p[i].rtn = 0U;
668 }
669
670 iso_qos_p[i].tx = &iso_tx_p[i];
671
672 iso_rx_p[i].sdu = CONFIG_BT_ISO_RX_MTU;
673
674 iso_qos_p[i].rx = &iso_rx_p[i];
675
676 iso_chan_p[i].ops = &iso_ops;
677 iso_chan_p[i].qos = &iso_qos_p[i];
678 }
679
680 printk("ISO Server Register...");
681 err = bt_iso_server_register(&iso_server);
682 if (err) {
683 FAIL("Unable to register ISO server (err %d)\n", err);
684 return;
685 }
686 printk("success.\n");
687
688 #if defined(CONFIG_TEST_USE_LEGACY_ADVERTISING)
689 printk("Start Advertising...");
690 err = bt_le_adv_start(BT_LE_ADV_CONN_CUSTOM, ad, ARRAY_SIZE(ad), NULL, 0);
691 if (err) {
692 FAIL("Advertising failed to start (err %d)\n", err);
693 return;
694 }
695 printk("success.\n");
696
697 #else /* !CONFIG_TEST_USE_LEGACY_ADVERTISING */
698 struct bt_le_ext_adv *adv;
699
700 printk("Creating connectable extended advertising set...\n");
701 err = bt_le_ext_adv_create(BT_LE_ADV_CONN_CUSTOM, NULL, &adv);
702 if (err) {
703 FAIL("Failed to create advertising set (err %d)\n", err);
704 return;
705 }
706 printk("success.\n");
707
708 /* Set extended advertising data */
709 err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
710 if (err) {
711 FAIL("Failed to set advertising data (err %d)\n", err);
712 return;
713 }
714
715 printk("Start Advertising...");
716 err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
717 if (err) {
718 FAIL("Failed to start extended advertising (err %d)\n", err);
719 return;
720 }
721 printk("success.\n");
722 #endif /* !CONFIG_TEST_USE_LEGACY_ADVERTISING */
723
724 printk("Waiting for connection from central...\n");
725 err = k_sem_take(&sem_peer_conn, K_FOREVER);
726 if (err) {
727 FAIL("failed (err %d)\n", err);
728 return;
729 }
730 printk("connected to peer central.\n");
731
732 #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
733 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
734 #endif
735
736 printk("Waiting for ISO channel connection...");
737 err = k_sem_take(&sem_iso_conn, K_FOREVER);
738 if (err) {
739 FAIL("failed (err %d)\n", err);
740 return;
741 }
742 printk("connected to peer ISO channel.\n");
743
744 #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
745 }
746 #endif
747
748 if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) {
749 for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) {
750 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
751 uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, };
752 struct net_buf *buf;
753 int ret;
754
755 buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT));
756 if (!buf) {
757 FAIL("Data buffer allocate timeout on channel %d\n", chan);
758 return;
759 }
760
761 net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
762 sys_put_le16(seq_num, iso_data);
763 net_buf_add_mem(buf, iso_data, sizeof(iso_data));
764
765 ret = k_sem_take(&sem_iso_data, K_MSEC(BUF_ALLOC_TIMEOUT));
766 if (ret) {
767 FAIL("k_sem_take for ISO data sent failed.\n");
768 return;
769 }
770
771 printk("ISO send: seq_num %u, chan %d\n", seq_num, chan);
772 ret = bt_iso_chan_send(&iso_chan_p[chan], buf, seq_num);
773 if (ret < 0) {
774 FAIL("Unable to send data on channel %d : %d\n", chan, ret);
775 net_buf_unref(buf);
776 return;
777 }
778 }
779
780 if ((seq_num % 100) == 0) {
781 printk("Sending value %u\n", seq_num);
782 }
783 }
784 }
785
786 #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
787 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
788 #endif
789
790 printk("Waiting for ISO channel disconnect...");
791 err = k_sem_take(&sem_iso_disc, K_FOREVER);
792 if (err) {
793 FAIL("failed (err %d)\n", err);
794 return;
795 }
796 printk("disconnected to peer ISO channel.\n");
797
798 #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
799 }
800 #endif
801
802 printk("Waiting for disconnection...");
803 err = k_sem_take(&sem_peer_disc, K_FOREVER);
804 if (err) {
805 FAIL("failed (err %d)\n", err);
806 return;
807 }
808 printk("disconnected from peer device.\n");
809
810 #if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)
811 #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
812 for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
813 #else
814 int chan = 0;
815 #endif
816 if (expected_seq_num[chan] < SEQ_NUM_MAX) {
817 FAIL("ISO Data reception incomplete %u (%u).\n", expected_seq_num[chan],
818 SEQ_NUM_MAX);
819 return;
820 }
821 #if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
822 }
823 #endif
824 #endif
825
826 PASS("Peripheral ISO tests Passed\n");
827 }
828
829 static void test_cis_init(void)
830 {
831 bst_ticker_set_next_tick_absolute(60e6);
832 bst_result = In_progress;
833 }
834
835 static void test_cis_tick(bs_time_t HW_device_time)
836 {
837 if (bst_result != Passed) {
838 FAIL("test failed (not passed after seconds)\n");
839 }
840 }
841
842 static const struct bst_test_instance test_def[] = {
843 {
844 .test_id = "central",
845 .test_descr = "Central ISO",
846 .test_pre_init_f = test_cis_init,
847 .test_tick_f = test_cis_tick,
848 .test_main_f = test_cis_central,
849 },
850 {
851 .test_id = "peripheral",
852 .test_descr = "Peripheral ISO",
853 .test_pre_init_f = test_cis_init,
854 .test_tick_f = test_cis_tick,
855 .test_main_f = test_cis_peripheral,
856 },
857 BSTEST_END_MARKER
858 };
859
860 struct bst_test_list *test_cis_install(struct bst_test_list *tests)
861 {
862 return bst_add_tests(tests, test_def);
863 }
864
865 bst_test_install_t test_installers[] = {
866 test_cis_install,
867 NULL
868 };
869
870 int main(void)
871 {
872 bst_main();
873 return 0;
874 }
875