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