1 /*
2 * Copyright (c) 2022 Demant
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/types.h>
8 #include <zephyr/ztest.h>
9
10 #include <zephyr/fff.h>
11
12 DEFINE_FFF_GLOBALS;
13
14 #include <zephyr/bluetooth/hci.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/sys/slist.h>
17 #include <zephyr/sys/util.h>
18 #include "hal/ccm.h"
19
20 #include "util/util.h"
21 #include "util/mem.h"
22 #include "util/memq.h"
23 #include "util/dbuf.h"
24
25 #include "pdu_df.h"
26 #include "lll/pdu_vendor.h"
27 #include "pdu.h"
28 #include "ll.h"
29 #include "ll_settings.h"
30
31 #include "lll.h"
32 #include "lll/lll_df_types.h"
33 #include "lll_conn_iso.h"
34 #include "lll_conn.h"
35
36 #include "ull_tx_queue.h"
37
38 #include "isoal.h"
39 #include "ull_iso_types.h"
40 #include "ull_conn_types.h"
41 #include "ull_conn_iso_types.h"
42 #include "ull_conn_iso_internal.h"
43 #include "ull_llcp.h"
44 #include "ull_conn_internal.h"
45 #include "ull_llcp_internal.h"
46
47 #include "helper_pdu.h"
48 #include "helper_util.h"
49
50 static struct ll_conn conn;
51
52 static struct ll_conn_iso_group cig_mock = { 0 };
53 static struct ll_conn_iso_stream cis_mock = { .established = 1, .group = &cig_mock };
54
55 /* struct ll_conn_iso_stream *ll_conn_iso_stream_get(uint16_t handle); */
56 FAKE_VALUE_FUNC(struct ll_conn_iso_stream *, ll_conn_iso_stream_get, uint16_t);
57
cis_create_setup(void * data)58 static void cis_create_setup(void *data)
59 {
60 test_setup(&conn);
61
62 RESET_FAKE(ll_conn_iso_stream_get);
63 }
64
is_instant_reached(struct ll_conn * conn,uint16_t instant)65 static bool is_instant_reached(struct ll_conn *conn, uint16_t instant)
66 {
67 return ((event_counter(conn) - instant) & 0xFFFF) <= 0x7FFF;
68 }
69
70 #define MAX_xDU 160
71 static struct pdu_data_llctrl_cis_req remote_cis_req = {
72 .cig_id = 0x01,
73 .cis_id = 0x02,
74 .c_phy = 0x01,
75 .p_phy = 0x01,
76 .c_max_sdu_packed = { MAX_xDU, 0 },
77 .p_max_sdu = { MAX_xDU, 0 },
78 .c_max_pdu = MAX_xDU,
79 .p_max_pdu = MAX_xDU,
80 .nse = 2,
81 .p_bn = 1,
82 .c_bn = 1,
83 .c_ft = 1,
84 .p_ft = 1,
85 .iso_interval = 6,
86 .conn_event_count = 12,
87 .c_sdu_interval = { 0, 0, 0},
88 .p_sdu_interval = { 0, 0, 0},
89 .sub_interval = { 0, 0, 0},
90 .cis_offset_min = { 0, 0, 0},
91 .cis_offset_max = { 0, 0, 0}
92 };
93
94 static struct pdu_data_llctrl_cis_ind remote_cis_ind = {
95 .aa = { 0, 0, 0, 0},
96 .cig_sync_delay = { 0, 0, 0},
97 .cis_offset = { 0, 0, 0},
98 .cis_sync_delay = { 0, 0, 0},
99 .conn_event_count = 12
100 };
101
102 static struct pdu_data_llctrl_cis_req local_cis_req = {
103 .cig_id = 0x00,
104 .cis_id = 0x02,
105 .c_phy = 0x01,
106 .p_phy = 0x01,
107 .c_max_sdu_packed = { MAX_xDU, 0 },
108 .p_max_sdu = { MAX_xDU, 0 },
109 .c_max_pdu = MAX_xDU,
110 .p_max_pdu = MAX_xDU,
111 .nse = 2,
112 .p_bn = 1,
113 .c_bn = 1,
114 .c_ft = 1,
115 .p_ft = 1,
116 .iso_interval = 6,
117 .conn_event_count = 0,
118 .c_sdu_interval = { 0, 0, 0},
119 .p_sdu_interval = { 0, 0, 0},
120 .sub_interval = { 0, 0, 0},
121 .cis_offset_min = { 0, 0, 0},
122 .cis_offset_max = { 0, 0, 0}
123 };
124
125 static struct pdu_data_llctrl_cis_ind local_cis_ind = {
126 .aa = { 0, 0, 0, 0},
127 .cig_sync_delay = { 0, 0, 0},
128 .cis_offset = { 0, 0, 0},
129 .cis_sync_delay = { 0, 0, 0},
130 .conn_event_count = 13
131 };
132
133 #define ERROR_CODE 0x17
134 /*
135 * Central-initiated CIS Create procedure.
136 * Central requests CIS, peripheral Host rejects.
137 *
138 * +-----+ +-------+ +-----+
139 * | UT | | LL_S | | LT |
140 * +-----+ +-------+ +-----+
141 * | | |
142 * | | LL_CIS_REQ |
143 * | |<--------------------------|
144 * | | |
145 * | LE CIS Request | |
146 * |<--------------------------| |
147 * | LE CIS Request | |
148 * | Accept | |
149 * |-------------------------->| |
150 * | | |
151 * | | LL_CIS_RSP |
152 * | |-------------------------->|
153 * | | |
154 * | | LL_CIS_IND |
155 * | |<--------------------------|
156 * | | |
157 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158 * | | |
159 * | LE CIS ESTABLISHED | |
160 * |<--------------------------| |
161 */
ZTEST(cis_create,test_cc_create_periph_rem_host_accept)162 ZTEST(cis_create, test_cc_create_periph_rem_host_accept)
163 {
164 struct node_tx *tx;
165 struct node_rx_pdu *ntf;
166 struct node_rx_conn_iso_req cis_req = {
167 .cig_id = 0x01,
168 .cis_handle = 0x00,
169 .cis_id = 0x02
170 };
171 struct pdu_data_llctrl_cis_rsp local_cis_rsp = {
172 .cis_offset_max = { 0, 0, 0},
173 .cis_offset_min = { 0, 0, 0},
174 .conn_event_count = 12
175 };
176 struct node_rx_conn_iso_estab cis_estab = {
177 .cis_handle = 0x00,
178 .status = 0x00
179 };
180
181 /* Prepare mocked call to ll_conn_iso_stream_get() */
182 ll_conn_iso_stream_get_fake.return_val = &cis_mock;
183
184 /* Role */
185 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
186
187 /* Connect */
188 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
189
190 /* Prepare */
191 event_prepare(&conn);
192
193 /* Rx */
194 lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
195
196 /* Done */
197 event_done(&conn);
198
199 /* There should be excactly one host notification */
200 ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
201 ut_rx_q_is_empty();
202
203 /* Release Ntf */
204 release_ntf(ntf);
205
206 /* Accept request */
207 ull_cp_cc_accept(&conn, 0U);
208
209 /* Prepare */
210 event_prepare(&conn);
211
212 /* Tx Queue should have one LL Control PDU */
213 lt_rx(LL_CIS_RSP, &conn, &tx, &local_cis_rsp);
214 lt_rx_q_is_empty(&conn);
215
216 /* Done */
217 event_done(&conn);
218
219 /* Prepare */
220 event_prepare(&conn);
221
222 /* Release Tx */
223 ull_cp_release_tx(&conn, tx);
224
225 /* Rx */
226 lt_tx(LL_CIS_IND, &conn, &remote_cis_ind);
227
228 /* Done */
229 event_done(&conn);
230
231 /* */
232 while (!is_instant_reached(&conn, remote_cis_ind.conn_event_count)) {
233 /* Prepare */
234 event_prepare(&conn);
235
236 /* Tx Queue should NOT have a LL Control PDU */
237 lt_rx_q_is_empty(&conn);
238
239 /* Done */
240 event_done(&conn);
241
242 /* There should NOT be a host notification */
243 ut_rx_q_is_empty();
244 }
245
246 /* Prepare */
247 event_prepare(&conn);
248
249 /* Done */
250 event_done(&conn);
251
252 /* Emulate CIS becoming established */
253 ull_cp_cc_established(&conn, 0);
254
255 /* Prepare */
256 event_prepare(&conn);
257
258 /* Tx Queue should NOT have a LL Control PDU */
259 lt_rx_q_is_empty(&conn);
260
261 /* Done */
262 event_done(&conn);
263
264 /* Prepare */
265 event_prepare(&conn);
266
267 /* There should be excactly one host notification */
268 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
269 ut_rx_q_is_empty();
270
271 /* Done */
272 event_done(&conn);
273
274 /* NODE_CIS_ESTABLISHED carry extra information in header rx footer param field */
275 zassert_equal_ptr(ntf->rx_ftr.param, &cis_mock);
276
277 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
278 "Free CTX buffers %d", llcp_ctx_buffers_free());
279 }
280
281 /*
282 * Central-initiated CIS Create procedure.
283 * Central requests CIS, peripheral Host rejects.
284 *
285 * +-----+ +-------+ +-----+
286 * | UT | | LL_S | | LT |
287 * +-----+ +-------+ +-----+
288 * | | |
289 * | | LL_CIS_REQ |
290 * | |<--------------------------|
291 * | | |
292 * | LE CIS Request | |
293 * |<--------------------------| |
294 * | LE CIS Request | |
295 * | Decline | |
296 * |-------------------------->| |
297 * | | |
298 * | | LL_REJECT_EXT_IND |
299 * | |-------------------------->|
300 * | | |
301 */
ZTEST(cis_create,test_cc_create_periph_rem_host_reject)302 ZTEST(cis_create, test_cc_create_periph_rem_host_reject)
303 {
304 struct node_tx *tx;
305 struct node_rx_pdu *ntf;
306 struct node_rx_conn_iso_req cis_req = {
307 .cig_id = 0x01,
308 .cis_handle = 0x00,
309 .cis_id = 0x02
310 };
311 struct pdu_data_llctrl_reject_ext_ind local_reject = {
312 .error_code = ERROR_CODE,
313 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
314 };
315
316 /* Role */
317 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
318
319 /* Connect */
320 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
321
322 /* Prepare */
323 event_prepare(&conn);
324
325 /* Rx */
326 lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
327
328 /* Done */
329 event_done(&conn);
330
331 /* There should be excactly one host notification */
332 ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
333 ut_rx_q_is_empty();
334
335 /* Release Ntf */
336 release_ntf(ntf);
337
338 /* Decline request */
339 ull_cp_cc_reject(&conn, ERROR_CODE);
340
341 /* Prepare */
342 event_prepare(&conn);
343
344 /* Tx Queue should have one LL Control PDU */
345 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
346 lt_rx_q_is_empty(&conn);
347
348 /* Done */
349 event_done(&conn);
350
351 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
352 "Free CTX buffers %d", llcp_ctx_buffers_free());
353 }
354
355 /*
356 * Central-initiated CIS Create procedure.
357 * Central requests CIS, ask peripheral host peripheral Host fails to reply
358 *
359 * +-----+ +-------+ +-----+
360 * | UT | | LL_S | | LT |
361 * +-----+ +-------+ +-----+
362 * | | |
363 * | | LL_CIS_REQ |
364 * | |<--------------------------|
365 * | | |
366 * | LE CIS Request | |
367 * |<--------------------------| |
368 * | | |
369 *
370 *
371 * Let time pass ......
372 *
373 *
374 * | | |
375 * | | LL_REJECT_EXT_IND (to) |
376 * | |-------------------------->|
377 * | | |
378 */
ZTEST(cis_create,test_cc_create_periph_rem_host_accept_to)379 ZTEST(cis_create, test_cc_create_periph_rem_host_accept_to)
380 {
381 struct node_tx *tx;
382 struct node_rx_pdu *ntf;
383 struct node_rx_conn_iso_req cis_req = {
384 .cig_id = 0x01,
385 .cis_handle = 0x00,
386 .cis_id = 0x02
387 };
388 struct pdu_data_llctrl_reject_ext_ind local_reject = {
389 .error_code = BT_HCI_ERR_CONN_ACCEPT_TIMEOUT,
390 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
391 };
392 struct node_rx_conn_iso_estab cis_estab = {
393 .cis_handle = 0x00,
394 .status = BT_HCI_ERR_CONN_ACCEPT_TIMEOUT
395 };
396
397 /* Role */
398 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
399
400 /* Connect */
401 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
402
403 /* Prepare */
404 event_prepare(&conn);
405
406 /* Rx */
407 lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
408
409 /* Done */
410 event_done(&conn);
411
412 /* There should be excactly one host notification */
413 ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
414 ut_rx_q_is_empty();
415
416 /* Release Ntf */
417 release_ntf(ntf);
418
419 /* Emulate that time passes real fast re. timeout */
420 conn.connect_accept_to = 0;
421
422 /* Prepare */
423 event_prepare(&conn);
424
425 /* Done */
426 event_done(&conn);
427
428 /* Prepare */
429 event_prepare(&conn);
430
431 /* Tx Queue should now have one LL Control PDU */
432 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
433 lt_rx_q_is_empty(&conn);
434
435 /* Done */
436 event_done(&conn);
437
438 /* There should be excactly one host notification */
439 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
440 ut_rx_q_is_empty();
441
442 /* Release Ntf */
443 release_ntf(ntf);
444
445 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
446 "Free CTX buffers %d", llcp_ctx_buffers_free());
447 }
448
449 /*
450 * Central-initiated CIS Create procedure.
451 * Central requests CIS w. invalid PHY param, peripheral Host rejects.
452 *
453 * +-----+ +-------+ +-----+
454 * | UT | | LL_S | | LT |
455 * +-----+ +-------+ +-----+
456 * | | |
457 * | | LL_CIS_REQ (w. invald PHY) |
458 * | |<------------------------------|
459 * | | |
460 * | | |
461 * | | |
462 * | | |
463 * | | |
464 * | | |
465 * | | LL_REJECT_EXT_IND |
466 * | |------------------------------>|
467 * | | |
468 */
ZTEST(cis_create,test_cc_create_periph_rem_invalid_phy)469 ZTEST(cis_create, test_cc_create_periph_rem_invalid_phy)
470 {
471 static struct pdu_data_llctrl_cis_req remote_cis_req_invalid_phy = {
472 .cig_id = 0x01,
473 .cis_id = 0x02,
474 .c_phy = 0x03,
475 .p_phy = 0x01,
476 .c_max_sdu_packed = { MAX_xDU, 0 },
477 .p_max_sdu = { MAX_xDU, 0 },
478 .c_max_pdu = MAX_xDU,
479 .p_max_pdu = MAX_xDU,
480 .nse = 2,
481 .p_bn = 1,
482 .c_bn = 1,
483 .c_ft = 1,
484 .p_ft = 1,
485 .iso_interval = 6,
486 .conn_event_count = 12,
487 .c_sdu_interval = { 0, 0, 0},
488 .p_sdu_interval = { 0, 0, 0},
489 .sub_interval = { 0, 0, 0},
490 .cis_offset_min = { 0, 0, 0},
491 .cis_offset_max = { 0, 0, 0}
492 };
493 struct node_tx *tx;
494 struct pdu_data_llctrl_reject_ext_ind local_reject = {
495 .error_code = BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL,
496 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
497 };
498
499 /* Role */
500 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
501
502 /* Connect */
503 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
504
505 /* Prepare */
506 event_prepare(&conn);
507
508 /* Rx */
509 lt_tx(LL_CIS_REQ, &conn, &remote_cis_req_invalid_phy);
510
511 /* Done */
512 event_done(&conn);
513
514 /* Prepare */
515 event_prepare(&conn);
516
517 /* Tx Queue should have one LL Control PDU */
518 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
519 lt_rx_q_is_empty(&conn);
520
521 /* Done */
522 event_done(&conn);
523
524 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
525 "Free CTX buffers %d", llcp_ctx_buffers_free());
526 }
527
528 /*
529 * Central-initiated CIS Create procedure.
530 * Host requests CIS, LL replies with 'remote feature unsupported'
531 *
532 * +-----+ +-------+ +-----+
533 * | UT | | LL_C | | LT |
534 * +-----+ +-------+ +-----+
535 * | | |
536 * | LE CIS Create | |
537 * |-------------------------->| |
538 * | | |
539 * | | (FEAT unsupported) |
540 * | | |
541 * | | |
542 * | LE CIS ESTABLISHED | |
543 * | (rem feat unsupported) | |
544 * |<--------------------------| |
545 */
ZTEST(cis_create,test_cc_create_central_rem_unsupported)546 ZTEST(cis_create, test_cc_create_central_rem_unsupported)
547 {
548 struct ll_conn_iso_stream *cis;
549 struct node_rx_pdu *ntf;
550 uint8_t err;
551
552 struct node_rx_conn_iso_estab cis_estab = {
553 .cis_handle = 0x00,
554 .status = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE
555 };
556
557 /* Prepare mocked call to ll_conn_iso_stream_get() */
558 ll_conn_iso_stream_get_fake.return_val = &cis_mock;
559
560 /* Role */
561 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
562
563 /* Connect */
564 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
565 conn.llcp.fex.valid = 1;
566
567 cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE);
568 cis->lll.acl_handle = conn.lll.handle;
569
570 err = ull_cp_cis_create(&conn, cis);
571 zassert_equal(err, BT_HCI_ERR_SUCCESS);
572
573 /* Prepare */
574 event_prepare(&conn);
575
576 /* Done */
577 event_done(&conn);
578
579 /* Prepare */
580 event_prepare(&conn);
581
582 /* There should be excactly one host notification
583 * with status BT_HCI_ERR_UNSUPP_REMOTE_FEATURE
584 */
585 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
586 ut_rx_q_is_empty();
587
588 /* Done */
589 event_done(&conn);
590
591 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
592 "Free CTX buffers %d", llcp_ctx_buffers_free());
593 }
594
595 /*
596 * Central-initiated CIS Create procedure.
597 * Central requests CIS, peripheral accepts
598 *
599 * +-----+ +-------+ +-----+
600 * | UT | | LL_C | | LT |
601 * +-----+ +-------+ +-----+
602 * | | |
603 * | LE CIS Create | |
604 * |-------------------------->| |
605 * | | LL_CIS_REQ |
606 * | |-------------------------->|
607 * | | |
608 * | | LL_CIS_RSP |
609 * | |<--------------------------|
610 * | | |
611 * | | |
612 * | | LL_CIS_IND |
613 * | |-------------------------->|
614 * | | |
615 * | | |
616 * | | |
617 * | | |
618 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
619 * | | |
620 * | LE CIS ESTABLISHED | |
621 * |<--------------------------| |
622 */
ZTEST(cis_create,test_cc_create_central_rem_accept)623 ZTEST(cis_create, test_cc_create_central_rem_accept)
624 {
625 struct pdu_data_llctrl_cis_rsp remote_cis_rsp = {
626 .cis_offset_max = { 0, 0, 0},
627 .cis_offset_min = { 0, 0, 0},
628 .conn_event_count = 13
629 };
630 struct node_rx_conn_iso_estab cis_estab = {
631 .cis_handle = 0x00,
632 .status = BT_HCI_ERR_SUCCESS
633 };
634 struct ll_conn_iso_stream *cis;
635 struct node_rx_pdu *ntf;
636 struct node_tx *tx;
637 uint8_t err;
638
639 /* Prepare mocked call to ll_conn_iso_stream_get() */
640 ll_conn_iso_stream_get_fake.return_val = &cis_mock;
641
642 /* Role */
643 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
644
645 /* Connect */
646 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
647 conn.llcp.fex.valid = 1;
648 conn.llcp.fex.features_peer |= BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL);
649
650 /* Setup default CIS/CIG parameters */
651 cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE);
652 cis->lll.acl_handle = conn.lll.handle;
653 cis->group->cig_id = local_cis_req.cig_id;
654 cis->cis_id = local_cis_req.cis_id;
655 cis->lll.tx.phy = local_cis_req.c_phy;
656 cis->lll.rx.phy = local_cis_req.p_phy;
657 cis->group->c_sdu_interval = 0;
658 cis->group->p_sdu_interval = 0;
659 cis->lll.tx.max_pdu = MAX_xDU;
660 cis->lll.rx.max_pdu = MAX_xDU;
661 cis->c_max_sdu = MAX_xDU;
662 cis->p_max_sdu = MAX_xDU;
663 cis->group->iso_interval = local_cis_req.iso_interval;
664 cis->framed = 0;
665 cis->lll.nse = local_cis_req.nse;
666 cis->lll.sub_interval = 0;
667 cis->lll.tx.bn = local_cis_req.c_bn;
668 cis->lll.rx.bn = local_cis_req.p_bn;
669 cis->lll.tx.ft = local_cis_req.c_ft;
670 cis->lll.rx.ft = local_cis_req.p_ft;
671
672 err = ull_cp_cis_create(&conn, cis);
673 zassert_equal(err, BT_HCI_ERR_SUCCESS);
674
675 /* Prepare */
676 event_prepare(&conn);
677
678 /* Tx Queue should have one LL Control PDU */
679 lt_rx(LL_CIS_REQ, &conn, &tx, &local_cis_req);
680 lt_rx_q_is_empty(&conn);
681
682 /* Done */
683 event_done(&conn);
684
685 /* Prepare */
686 event_prepare(&conn);
687
688 /* Rx */
689 lt_tx(LL_CIS_RSP, &conn, &remote_cis_rsp);
690
691 /* Done */
692 event_done(&conn);
693
694 /* Prepare */
695 event_prepare(&conn);
696
697 /* Tx Queue should have one LL Control PDU */
698 lt_rx(LL_CIS_IND, &conn, &tx, &local_cis_ind);
699 lt_rx_q_is_empty(&conn);
700
701 /* Done */
702 event_done(&conn);
703
704 /* */
705 while (!is_instant_reached(&conn, remote_cis_rsp.conn_event_count)) {
706 /* Prepare */
707 event_prepare(&conn);
708
709 /* Tx Queue should NOT have a LL Control PDU */
710 lt_rx_q_is_empty(&conn);
711
712 /* Done */
713 event_done(&conn);
714
715 /* There should NOT be a host notification */
716 ut_rx_q_is_empty();
717 }
718
719 /* Prepare */
720 event_prepare(&conn);
721
722 /* Done */
723 event_done(&conn);
724
725 /* Emulate CIS becoming established */
726 ull_cp_cc_established(&conn, 0);
727
728 /* Prepare */
729 event_prepare(&conn);
730
731 /* Tx Queue should NOT have a LL Control PDU */
732 lt_rx_q_is_empty(&conn);
733
734 /* Done */
735 event_done(&conn);
736
737 /* Prepare */
738 event_prepare(&conn);
739
740 /* There should be excactly one host notification */
741 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
742 ut_rx_q_is_empty();
743
744 /* Done */
745 event_done(&conn);
746
747 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
748 "Free CTX buffers %d", llcp_ctx_buffers_free());
749 }
750
751 /*
752 * Central-initiated CIS Create procedure.
753 * Central requests CIS, peripheral rejects with 'unsupported remote feature'
754 *
755 * +-----+ +-------+ +-----+
756 * | UT | | LL_C | | LT |
757 * +-----+ +-------+ +-----+
758 * | | |
759 * | LE CIS Create | |
760 * |-------------------------->| |
761 * | | LL_CIS_REQ |
762 * | |-------------------------->|
763 * | | |
764 * | | LL_REJECT_EXT_IND |
765 * | | (unsupported remote feat) |
766 * | |<--------------------------|
767 * | | |
768 * | | |
769 * | | |
770 * | | |
771 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
772 * | | |
773 * | LE CIS ESTABLISHED | |
774 * |<--------------------------| |
775 */
ZTEST(cis_create,test_cc_create_central_rem_reject)776 ZTEST(cis_create, test_cc_create_central_rem_reject)
777 {
778 struct node_rx_conn_iso_estab cis_estab = {
779 .cis_handle = 0x00,
780 .status = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE
781 };
782 struct pdu_data_llctrl_reject_ext_ind remote_reject = {
783 .error_code = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE,
784 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
785 };
786 struct ll_conn_iso_stream *cis;
787 struct node_rx_pdu *ntf;
788 struct node_tx *tx;
789 uint8_t err;
790
791 /* Prepare mocked call to ll_conn_iso_stream_get() */
792 ll_conn_iso_stream_get_fake.return_val = &cis_mock;
793
794 /* Role */
795 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
796
797 /* Connect */
798 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
799 conn.llcp.fex.valid = 1;
800 conn.llcp.fex.features_peer |= BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL);
801
802 /* Setup default CIS/CIG parameters */
803 cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE);
804 cis->lll.acl_handle = conn.lll.handle;
805 cis->group->cig_id = local_cis_req.cig_id;
806 cis->cis_id = local_cis_req.cis_id;
807 cis->lll.tx.phy = local_cis_req.c_phy;
808 cis->lll.rx.phy = local_cis_req.p_phy;
809 cis->group->c_sdu_interval = 0;
810 cis->group->p_sdu_interval = 0;
811 cis->lll.tx.max_pdu = MAX_xDU;
812 cis->lll.rx.max_pdu = MAX_xDU;
813 cis->c_max_sdu = MAX_xDU;
814 cis->p_max_sdu = MAX_xDU;
815 cis->group->iso_interval = local_cis_req.iso_interval;
816 cis->framed = 0;
817 cis->lll.nse = local_cis_req.nse;
818 cis->lll.sub_interval = 0;
819 cis->lll.tx.bn = local_cis_req.c_bn;
820 cis->lll.rx.bn = local_cis_req.p_bn;
821 cis->lll.tx.ft = local_cis_req.c_ft;
822 cis->lll.rx.ft = local_cis_req.p_ft;
823
824 err = ull_cp_cis_create(&conn, cis);
825 zassert_equal(err, BT_HCI_ERR_SUCCESS);
826
827 /* Prepare */
828 event_prepare(&conn);
829
830 /* Tx Queue should have one LL Control PDU */
831 lt_rx(LL_CIS_REQ, &conn, &tx, &local_cis_req);
832 lt_rx_q_is_empty(&conn);
833
834 /* Done */
835 event_done(&conn);
836
837 /* Prepare */
838 event_prepare(&conn);
839
840 /* Rx */
841 lt_tx(LL_REJECT_EXT_IND, &conn, &remote_reject);
842
843 /* Done */
844 event_done(&conn);
845
846 /* Prepare */
847 event_prepare(&conn);
848
849 /* There should be excactly one host notification */
850 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
851 ut_rx_q_is_empty();
852
853 zassert_equal(conn.llcp.fex.features_peer & BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL), 0);
854
855 /* Done */
856 event_done(&conn);
857
858 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
859 "Free CTX buffers %d", llcp_ctx_buffers_free());
860 }
861
862
863 ZTEST_SUITE(cis_create, NULL, NULL, cis_create_setup, NULL, NULL);
864