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 #include <zephyr/bluetooth/iso.h>
51
52 #define SUB_INTERVAL_MIN 400
53
54 static struct ll_conn conn;
55
56 static struct ll_conn_iso_group cig_mock = { 0 };
57 static struct ll_conn_iso_stream cis_mock = { .established = 1, .group = &cig_mock };
58
59 /* struct ll_conn_iso_stream *ll_conn_iso_stream_get(uint16_t handle); */
60 FAKE_VALUE_FUNC(struct ll_conn_iso_stream *, ll_conn_iso_stream_get, uint16_t);
61
cis_create_setup(void * data)62 static void cis_create_setup(void *data)
63 {
64 test_setup(&conn);
65
66 RESET_FAKE(ll_conn_iso_stream_get);
67 }
68
is_instant_reached(struct ll_conn * llconn,uint16_t instant)69 static bool is_instant_reached(struct ll_conn *llconn, uint16_t instant)
70 {
71 return ((event_counter(llconn) - instant) & 0xFFFF) <= 0x7FFF;
72 }
73
74 #define MAX_xDU 160
75 static struct pdu_data_llctrl_cis_req remote_cis_req = {
76 .cig_id = 0x01,
77 .cis_id = 0x02,
78 .c_phy = 0x01,
79 .p_phy = 0x01,
80 .c_max_sdu_packed = { MAX_xDU, 0 },
81 .p_max_sdu = { MAX_xDU, 0 },
82 .c_max_pdu = MAX_xDU,
83 .p_max_pdu = MAX_xDU,
84 .nse = 2,
85 .p_bn = 1,
86 .c_bn = 1,
87 .c_ft = 1,
88 .p_ft = 1,
89 .iso_interval = 6,
90 .conn_event_count = 12,
91 .c_sdu_interval = { 0, 0x02, 0}, /* 512 us */
92 .p_sdu_interval = { 0, 0x02, 0}, /* 512 us */
93 .sub_interval = { 0x90, 0x01, 0x00}, /* 400 us */
94 .cis_offset_min = { 0, 0x02, 0}, /* 512 us */
95 .cis_offset_max = { 0, 0x02, 0} /* 512 us */
96 };
97
98 static struct pdu_data_llctrl_cis_ind remote_cis_ind = {
99 .aa = { 0, 0, 0, 0},
100 .cig_sync_delay = { 0, 0, 0},
101 .cis_offset = { 0, 0, 0},
102 .cis_sync_delay = { 0, 0, 0},
103 .conn_event_count = 12
104 };
105
106 static struct pdu_data_llctrl_cis_req local_cis_req = {
107 .cig_id = 0x00,
108 .cis_id = 0x02,
109 .c_phy = 0x01,
110 .p_phy = 0x01,
111 .c_max_sdu_packed = { MAX_xDU, 0 },
112 .p_max_sdu = { MAX_xDU, 0 },
113 .c_max_pdu = MAX_xDU,
114 .p_max_pdu = MAX_xDU,
115 .nse = 2,
116 .p_bn = 1,
117 .c_bn = 1,
118 .c_ft = 1,
119 .p_ft = 1,
120 .iso_interval = 6,
121 .conn_event_count = 0,
122 .c_sdu_interval = { 0, 0, 0},
123 .p_sdu_interval = { 0, 0, 0},
124 .sub_interval = { 0, 0, 0},
125 .cis_offset_min = { 0, 0, 0},
126 .cis_offset_max = { 0, 0, 0}
127 };
128
129 static struct pdu_data_llctrl_cis_ind local_cis_ind = {
130 .aa = { 0, 0, 0, 0},
131 .cig_sync_delay = { 0, 0, 0},
132 .cis_offset = { 0, 0, 0},
133 .cis_sync_delay = { 0, 0, 0},
134 .conn_event_count = 0
135 };
136
137 #define ERROR_CODE 0x17
138 /*
139 * Central-initiated CIS Create procedure.
140 * Central requests CIS, peripheral Host rejects.
141 *
142 * +-----+ +-------+ +-----+
143 * | UT | | LL_S | | LT |
144 * +-----+ +-------+ +-----+
145 * | | |
146 * | | LL_CIS_REQ |
147 * | |<--------------------------|
148 * | | |
149 * | LE CIS Request | |
150 * |<--------------------------| |
151 * | LE CIS Request | |
152 * | Accept | |
153 * |-------------------------->| |
154 * | | |
155 * | | LL_CIS_RSP |
156 * | |-------------------------->|
157 * | | |
158 * | | LL_CIS_IND |
159 * | |<--------------------------|
160 * | | |
161 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
162 * | | |
163 * | LE CIS ESTABLISHED | |
164 * |<--------------------------| |
165 */
ZTEST(cis_create,test_cc_create_periph_rem_host_accept)166 ZTEST(cis_create, test_cc_create_periph_rem_host_accept)
167 {
168 struct node_tx *tx;
169 struct node_rx_pdu *ntf;
170 struct node_rx_conn_iso_req cis_req = {
171 .cig_id = 0x01,
172 .cis_handle = 0x00,
173 .cis_id = 0x02
174 };
175 struct pdu_data_llctrl_cis_rsp local_cis_rsp = {
176 .cis_offset_max = { 0, 0x02, 0},
177 .cis_offset_min = { 0, 0x02, 0},
178 .conn_event_count = 12
179 };
180 struct node_rx_conn_iso_estab cis_estab = {
181 .cis_handle = 0x00,
182 .status = 0x00
183 };
184
185 /* Prepare mocked call to ll_conn_iso_stream_get() */
186 ll_conn_iso_stream_get_fake.return_val = &cis_mock;
187
188 /* Role */
189 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
190
191 /* Connect */
192 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
193
194 /* Prepare */
195 event_prepare(&conn);
196
197 /* Rx */
198 lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
199
200 /* Done */
201 event_done(&conn);
202
203 /* There should be exactly one host notification */
204 ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
205 ut_rx_q_is_empty();
206
207 /* Release Ntf */
208 release_ntf(ntf);
209
210 /* Accept request */
211 ull_cp_cc_accept(&conn, 0U);
212
213 /* Prepare */
214 event_prepare(&conn);
215
216 /* Tx Queue should have one LL Control PDU */
217 lt_rx(LL_CIS_RSP, &conn, &tx, &local_cis_rsp);
218 lt_rx_q_is_empty(&conn);
219
220 /* Done */
221 event_done(&conn);
222
223 /* Prepare */
224 event_prepare(&conn);
225
226 /* Release Tx */
227 ull_cp_release_tx(&conn, tx);
228
229 /* Rx */
230 lt_tx(LL_CIS_IND, &conn, &remote_cis_ind);
231
232 /* Done */
233 event_done(&conn);
234
235 /* */
236 while (!is_instant_reached(&conn, remote_cis_ind.conn_event_count)) {
237 /* Prepare */
238 event_prepare(&conn);
239
240 /* Tx Queue should NOT have a LL Control PDU */
241 lt_rx_q_is_empty(&conn);
242
243 /* Done */
244 event_done(&conn);
245
246 /* There should NOT be a host notification */
247 ut_rx_q_is_empty();
248 }
249
250 /* Prepare */
251 event_prepare(&conn);
252
253 /* Done */
254 event_done(&conn);
255
256 /* Emulate CIS becoming established */
257 ull_cp_cc_established(&conn, 0);
258
259 /* Prepare */
260 event_prepare(&conn);
261
262 /* Tx Queue should NOT have a LL Control PDU */
263 lt_rx_q_is_empty(&conn);
264
265 /* Done */
266 event_done(&conn);
267
268 /* Prepare */
269 event_prepare(&conn);
270
271 /* There should be exactly one host notification */
272 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
273 ut_rx_q_is_empty();
274
275 /* Done */
276 event_done(&conn);
277
278 /* NODE_CIS_ESTABLISHED carry extra information in header rx footer param field */
279 zassert_equal_ptr(ntf->rx_ftr.param, &cis_mock);
280
281 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
282 "Free CTX buffers %d", llcp_ctx_buffers_free());
283 }
284
285 /*
286 * Central-initiated CIS Create procedure.
287 * Central requests CIS, peripheral Host rejects.
288 *
289 * +-----+ +-------+ +-----+
290 * | UT | | LL_S | | LT |
291 * +-----+ +-------+ +-----+
292 * | | |
293 * | | LL_CIS_REQ |
294 * | |<--------------------------|
295 * | | |
296 * | LE CIS Request | |
297 * |<--------------------------| |
298 * | LE CIS Request | |
299 * | Decline | |
300 * |-------------------------->| |
301 * | | |
302 * | | LL_REJECT_EXT_IND |
303 * | |-------------------------->|
304 * | | |
305 */
ZTEST(cis_create,test_cc_create_periph_rem_host_reject)306 ZTEST(cis_create, test_cc_create_periph_rem_host_reject)
307 {
308 struct node_tx *tx;
309 struct node_rx_pdu *ntf;
310 struct node_rx_conn_iso_req cis_req = {
311 .cig_id = 0x01,
312 .cis_handle = 0x00,
313 .cis_id = 0x02
314 };
315 struct pdu_data_llctrl_reject_ext_ind local_reject = {
316 .error_code = ERROR_CODE,
317 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
318 };
319
320 /* Role */
321 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
322
323 /* Connect */
324 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
325
326 /* Prepare */
327 event_prepare(&conn);
328
329 /* Rx */
330 lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
331
332 /* Done */
333 event_done(&conn);
334
335 /* There should be exactly one host notification */
336 ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
337 ut_rx_q_is_empty();
338
339 /* Release Ntf */
340 release_ntf(ntf);
341
342 /* Decline request */
343 ull_cp_cc_reject(&conn, ERROR_CODE);
344
345 /* Prepare */
346 event_prepare(&conn);
347
348 /* Tx Queue should have one LL Control PDU */
349 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
350 lt_rx_q_is_empty(&conn);
351
352 /* Done */
353 event_done(&conn);
354
355 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
356 "Free CTX buffers %d", llcp_ctx_buffers_free());
357 }
358
359 /*
360 * Central-initiated CIS Create procedure.
361 * Central requests CIS, ask peripheral host peripheral Host fails to reply
362 *
363 * +-----+ +-------+ +-----+
364 * | UT | | LL_S | | LT |
365 * +-----+ +-------+ +-----+
366 * | | |
367 * | | LL_CIS_REQ |
368 * | |<--------------------------|
369 * | | |
370 * | LE CIS Request | |
371 * |<--------------------------| |
372 * | | |
373 *
374 *
375 * Let time pass ......
376 *
377 *
378 * | | |
379 * | | LL_REJECT_EXT_IND (to) |
380 * | |-------------------------->|
381 * | | |
382 */
ZTEST(cis_create,test_cc_create_periph_rem_host_accept_to)383 ZTEST(cis_create, test_cc_create_periph_rem_host_accept_to)
384 {
385 struct node_tx *tx;
386 struct node_rx_pdu *ntf;
387 struct node_rx_conn_iso_req cis_req = {
388 .cig_id = 0x01,
389 .cis_handle = 0x00,
390 .cis_id = 0x02
391 };
392 struct pdu_data_llctrl_reject_ext_ind local_reject = {
393 .error_code = BT_HCI_ERR_CONN_ACCEPT_TIMEOUT,
394 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
395 };
396 struct node_rx_conn_iso_estab cis_estab = {
397 .cis_handle = 0x00,
398 .status = BT_HCI_ERR_CONN_ACCEPT_TIMEOUT
399 };
400
401 /* Role */
402 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
403
404 /* Connect */
405 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
406
407 /* Prepare */
408 event_prepare(&conn);
409
410 /* Rx */
411 lt_tx(LL_CIS_REQ, &conn, &remote_cis_req);
412
413 /* Done */
414 event_done(&conn);
415
416 /* There should be exactly one host notification */
417 ut_rx_node(NODE_CIS_REQUEST, &ntf, &cis_req);
418 ut_rx_q_is_empty();
419
420 /* Release Ntf */
421 release_ntf(ntf);
422
423 /* Emulate that time passes real fast re. timeout */
424 conn.connect_accept_to = 0;
425
426 /* Prepare */
427 event_prepare(&conn);
428
429 /* Done */
430 event_done(&conn);
431
432 /* Prepare */
433 event_prepare(&conn);
434
435 /* Tx Queue should now have one LL Control PDU */
436 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
437 lt_rx_q_is_empty(&conn);
438
439 /* Done */
440 event_done(&conn);
441
442 /* There should be exactly one host notification */
443 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
444 ut_rx_q_is_empty();
445
446 /* Release Ntf */
447 release_ntf(ntf);
448
449 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
450 "Free CTX buffers %d", llcp_ctx_buffers_free());
451 }
452
453 /*
454 * Central-initiated CIS Create procedure.
455 * Central requests CIS w. invalid PHY param, peripheral Host rejects.
456 *
457 * +-----+ +-------+ +-----+
458 * | UT | | LL_S | | LT |
459 * +-----+ +-------+ +-----+
460 * | | |
461 * | | LL_CIS_REQ (w. invald PHY) |
462 * | |<------------------------------|
463 * | | |
464 * | | |
465 * | | |
466 * | | |
467 * | | |
468 * | | |
469 * | | LL_REJECT_EXT_IND |
470 * | |------------------------------>|
471 * | | |
472 */
ZTEST(cis_create,test_cc_create_periph_rem_invalid_phy)473 ZTEST(cis_create, test_cc_create_periph_rem_invalid_phy)
474 {
475 static struct pdu_data_llctrl_cis_req remote_cis_req_invalid_phy = {
476 .cig_id = 0x01,
477 .cis_id = 0x02,
478 .c_phy = 0x03,
479 .p_phy = 0x01,
480 .c_max_sdu_packed = { MAX_xDU, 0 },
481 .p_max_sdu = { MAX_xDU, 0 },
482 .c_max_pdu = MAX_xDU,
483 .p_max_pdu = MAX_xDU,
484 .nse = 2,
485 .p_bn = 1,
486 .c_bn = 1,
487 .c_ft = 1,
488 .p_ft = 1,
489 .iso_interval = 6,
490 .conn_event_count = 12,
491 .c_sdu_interval = { 0, 0, 0},
492 .p_sdu_interval = { 0, 0, 0},
493 .sub_interval = { 0, 0, 0},
494 .cis_offset_min = { 0, 0, 0},
495 .cis_offset_max = { 0, 0, 0}
496 };
497 struct node_tx *tx;
498 struct pdu_data_llctrl_reject_ext_ind local_reject = {
499 .error_code = BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL,
500 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
501 };
502
503 /* Role */
504 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
505
506 /* Connect */
507 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
508
509 /* Prepare */
510 event_prepare(&conn);
511
512 /* Rx */
513 lt_tx(LL_CIS_REQ, &conn, &remote_cis_req_invalid_phy);
514
515 /* Done */
516 event_done(&conn);
517
518 /* Prepare */
519 event_prepare(&conn);
520
521 /* Tx Queue should have one LL Control PDU */
522 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
523 lt_rx_q_is_empty(&conn);
524
525 /* Done */
526 event_done(&conn);
527
528 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
529 "Free CTX buffers %d", llcp_ctx_buffers_free());
530 }
531
rx_remote_cis_req_invalid_param(struct pdu_data_llctrl_cis_req * req)532 static void rx_remote_cis_req_invalid_param(struct pdu_data_llctrl_cis_req *req)
533 {
534 struct node_tx *tx;
535 struct pdu_data_llctrl_reject_ext_ind local_reject = {
536 .error_code = BT_HCI_ERR_INVALID_LL_PARAM,
537 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
538 };
539
540 test_setup(&conn);
541
542 /* Role */
543 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
544
545 /* Connect */
546 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
547
548 /* Prepare */
549 event_prepare(&conn);
550
551 /* Rx */
552 lt_tx(LL_CIS_REQ, &conn, req);
553
554 /* Done */
555 event_done(&conn);
556
557 /* Prepare */
558 event_prepare(&conn);
559
560 /* Tx Queue should have one LL Control PDU */
561 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &local_reject);
562 lt_rx_q_is_empty(&conn);
563
564 /* Done */
565 event_done(&conn);
566
567 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
568 "Free CTX buffers %d", llcp_ctx_buffers_free());
569 }
570
571 /*
572 * Central-initiated CIS Create procedure.
573 * Central requests CIS w. invalid param, peripheral Host rejects.
574 *
575 * +-----+ +-------+ +-----+
576 * | UT | | LL_S | | LT |
577 * +-----+ +-------+ +-----+
578 * | | |
579 * | | LL_CIS_REQ (invalid param) |
580 * | |<------------------------------|
581 * | | |
582 * | | |
583 * | | |
584 * | | |
585 * | | |
586 * | | |
587 * | | LL_REJECT_EXT_IND |
588 * | |------------------------------>|
589 * | | |
590 */
ZTEST(cis_create,test_cc_create_periph_rem_invalid_param)591 ZTEST(cis_create, test_cc_create_periph_rem_invalid_param)
592 {
593 struct pdu_data_llctrl_cis_req remote_cis_req_invalid_param = remote_cis_req;
594
595 /* Rx with c_sdu_interval < 255 */
596 sys_put_le24(BT_HCI_ISO_SDU_INTERVAL_MIN-1, remote_cis_req_invalid_param.c_sdu_interval);
597 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
598
599 /* Restore to valid params */
600 remote_cis_req_invalid_param = remote_cis_req;
601
602 /* Rx with p_sdu_interval < 255 */
603 sys_put_le24(BT_HCI_ISO_SDU_INTERVAL_MIN-1, remote_cis_req_invalid_param.p_sdu_interval);
604 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
605
606 /* Restore to valid params */
607 remote_cis_req_invalid_param = remote_cis_req;
608
609 /* Rx with c_max_pdu > 251 */
610 remote_cis_req_invalid_param.c_max_pdu = sys_cpu_to_le16(BT_ISO_PDU_MAX + 1);
611 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
612
613 /* Restore to valid params */
614 remote_cis_req_invalid_param = remote_cis_req;
615
616 /* Rx with p_max_pdu > 251 */
617 remote_cis_req_invalid_param.p_max_pdu = sys_cpu_to_le16(BT_ISO_PDU_MAX + 1);
618 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
619
620 /* Restore to valid params */
621 remote_cis_req_invalid_param = remote_cis_req;
622
623 /* Rx with nse == 0 */
624 remote_cis_req_invalid_param.nse = 0;
625 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
626
627 /* Restore to valid params */
628 remote_cis_req_invalid_param = remote_cis_req;
629
630 /* Rx with nse > 31 */
631 remote_cis_req_invalid_param.nse = BT_ISO_NSE_MAX + 1;
632 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
633
634 /* Restore to valid params */
635 remote_cis_req_invalid_param = remote_cis_req;
636
637 /* Rx with sub_interval > 0 && nse == 1 */
638 remote_cis_req_invalid_param.nse = 1;
639 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
640
641 /* Restore to valid params */
642 remote_cis_req_invalid_param = remote_cis_req;
643
644 /* Rx with sub_interval < 400 && nse > 1 */
645 sys_put_le24(SUB_INTERVAL_MIN - 1, remote_cis_req_invalid_param.sub_interval);
646 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
647
648 /* Restore to valid params */
649 remote_cis_req_invalid_param = remote_cis_req;
650
651 /* Rx with sub_interval >= iso_interval */
652 sys_put_le24(sys_le16_to_cpu(remote_cis_req_invalid_param.iso_interval) * CONN_INT_UNIT_US,
653 remote_cis_req_invalid_param.sub_interval);
654 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
655
656 /* Restore to valid params */
657 remote_cis_req_invalid_param = remote_cis_req;
658
659
660 /* Rx with c_bn == 0 && c_max_pdu > 0 */
661 remote_cis_req_invalid_param.c_bn = 0;
662 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
663
664 /* Restore to valid params */
665 remote_cis_req_invalid_param = remote_cis_req;
666
667 /* Rx with p_bn == 0 && p_max_pdu > 0 */
668 remote_cis_req_invalid_param.p_bn = 0;
669 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
670
671 /* Restore to valid params */
672 remote_cis_req_invalid_param = remote_cis_req;
673
674 /* Rx with c_ft == 0 */
675 remote_cis_req_invalid_param.c_ft = 0;
676 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
677
678 /* Restore to valid params */
679 remote_cis_req_invalid_param = remote_cis_req;
680
681 /* Rx with p_ft == 0 */
682 remote_cis_req_invalid_param.p_ft = 0;
683 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
684
685 /* Restore to valid params */
686 remote_cis_req_invalid_param = remote_cis_req;
687
688 /* Rx with iso_interval < 4 */
689 remote_cis_req_invalid_param.iso_interval = sys_cpu_to_le16(BT_HCI_ISO_INTERVAL_MIN - 1);
690 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
691
692 /* Restore to valid params */
693 remote_cis_req_invalid_param = remote_cis_req;
694
695 /* Rx with iso_interval > 3200 */
696 remote_cis_req_invalid_param.iso_interval = sys_cpu_to_le16(BT_HCI_ISO_INTERVAL_MAX + 1);
697 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
698
699 /* Restore to valid params */
700 remote_cis_req_invalid_param = remote_cis_req;
701
702 /* Rx with cis_offset_min < 500 */
703 sys_put_le24(PDU_CIS_OFFSET_MIN_US - 1, remote_cis_req_invalid_param.cis_offset_min);
704 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
705
706 /* Restore to valid params */
707 remote_cis_req_invalid_param = remote_cis_req;
708
709 /* Rx with cis_offset_max < cis_offset_min */
710 sys_put_le24(0x01FF, remote_cis_req_invalid_param.cis_offset_max);
711 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
712
713 /* Restore to valid params */
714 remote_cis_req_invalid_param = remote_cis_req;
715
716 /* Rx with cis_offset_max >= conn_interval */
717 sys_put_le24(conn.lll.interval * CONN_INT_UNIT_US,
718 remote_cis_req_invalid_param.cis_offset_max);
719 rx_remote_cis_req_invalid_param(&remote_cis_req_invalid_param);
720 }
721
722 /*
723 * Central-initiated CIS Create procedure.
724 * Host requests CIS, LL replies with 'remote feature unsupported'
725 *
726 * +-----+ +-------+ +-----+
727 * | UT | | LL_C | | LT |
728 * +-----+ +-------+ +-----+
729 * | | |
730 * | LE CIS Create | |
731 * |-------------------------->| |
732 * | | |
733 * | | (FEAT unsupported) |
734 * | | |
735 * | | |
736 * | LE CIS ESTABLISHED | |
737 * | (rem feat unsupported) | |
738 * |<--------------------------| |
739 */
ZTEST(cis_create,test_cc_create_central_rem_unsupported)740 ZTEST(cis_create, test_cc_create_central_rem_unsupported)
741 {
742 struct ll_conn_iso_stream *cis;
743 struct node_rx_pdu *ntf;
744 uint8_t err;
745
746 struct node_rx_conn_iso_estab cis_estab = {
747 .cis_handle = 0x00,
748 .status = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE
749 };
750
751 /* Prepare mocked call to ll_conn_iso_stream_get() */
752 ll_conn_iso_stream_get_fake.return_val = &cis_mock;
753
754 /* Role */
755 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
756
757 /* Connect */
758 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
759 conn.llcp.fex.valid = 1;
760
761 cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE);
762 cis->lll.acl_handle = conn.lll.handle;
763
764 err = ull_cp_cis_create(&conn, cis);
765 zassert_equal(err, BT_HCI_ERR_SUCCESS);
766
767 /* Prepare */
768 event_prepare(&conn);
769
770 /* Done */
771 event_done(&conn);
772
773 /* Prepare */
774 event_prepare(&conn);
775
776 /* There should be exactly one host notification
777 * with status BT_HCI_ERR_UNSUPP_REMOTE_FEATURE
778 */
779 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
780 ut_rx_q_is_empty();
781
782 /* Done */
783 event_done(&conn);
784
785 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
786 "Free CTX buffers %d", llcp_ctx_buffers_free());
787 }
788
789 /*
790 * Central-initiated CIS Create procedure.
791 * Central requests CIS, peripheral accepts
792 *
793 * +-----+ +-------+ +-----+
794 * | UT | | LL_C | | LT |
795 * +-----+ +-------+ +-----+
796 * | | |
797 * | LE CIS Create | |
798 * |-------------------------->| |
799 * | | LL_CIS_REQ |
800 * | |-------------------------->|
801 * | | |
802 * | | LL_CIS_RSP |
803 * | |<--------------------------|
804 * | | |
805 * | | |
806 * | | LL_CIS_IND |
807 * | |-------------------------->|
808 * | | |
809 * | | |
810 * | | |
811 * | | |
812 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
813 * | | |
814 * | LE CIS ESTABLISHED | |
815 * |<--------------------------| |
816 */
ZTEST(cis_create,test_cc_create_central_rem_accept)817 ZTEST(cis_create, test_cc_create_central_rem_accept)
818 {
819 struct pdu_data_llctrl_cis_rsp remote_cis_rsp = {
820 .cis_offset_max = { 0, 0, 0},
821 .cis_offset_min = { 0, 0, 0},
822 .conn_event_count = 13
823 };
824 struct node_rx_conn_iso_estab cis_estab = {
825 .cis_handle = 0x00,
826 .status = BT_HCI_ERR_SUCCESS
827 };
828 struct ll_conn_iso_stream *cis;
829 struct node_rx_pdu *ntf;
830 struct node_tx *tx;
831 uint8_t err;
832
833 /* Prepare mocked call to ll_conn_iso_stream_get() */
834 ll_conn_iso_stream_get_fake.return_val = &cis_mock;
835
836 /* Role */
837 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
838
839 /* Connect */
840 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
841 conn.llcp.fex.valid = 1;
842 conn.llcp.fex.features_peer |= BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL);
843
844 /* Setup default CIS/CIG parameters */
845 cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE);
846 cis->lll.acl_handle = conn.lll.handle;
847 cis->group->cig_id = local_cis_req.cig_id;
848 cis->cis_id = local_cis_req.cis_id;
849 cis->lll.tx.phy = local_cis_req.c_phy;
850 cis->lll.rx.phy = local_cis_req.p_phy;
851 cis->group->c_sdu_interval = 0;
852 cis->group->p_sdu_interval = 0;
853 cis->lll.tx.max_pdu = MAX_xDU;
854 cis->lll.rx.max_pdu = MAX_xDU;
855 cis->c_max_sdu = MAX_xDU;
856 cis->p_max_sdu = MAX_xDU;
857 cis->group->iso_interval = local_cis_req.iso_interval;
858 cis->framed = 0;
859 cis->lll.nse = local_cis_req.nse;
860 cis->lll.sub_interval = 0;
861 cis->lll.tx.bn = local_cis_req.c_bn;
862 cis->lll.rx.bn = local_cis_req.p_bn;
863 cis->lll.tx.ft = local_cis_req.c_ft;
864 cis->lll.rx.ft = local_cis_req.p_ft;
865
866 err = ull_cp_cis_create(&conn, cis);
867 zassert_equal(err, BT_HCI_ERR_SUCCESS);
868
869 /* Prepare */
870 event_prepare(&conn);
871
872 /* Tx Queue should have one LL Control PDU */
873 lt_rx(LL_CIS_REQ, &conn, &tx, &local_cis_req);
874 lt_rx_q_is_empty(&conn);
875
876 /* Done */
877 event_done(&conn);
878
879 /* Prepare */
880 event_prepare(&conn);
881
882 /* Rx */
883 lt_tx(LL_CIS_RSP, &conn, &remote_cis_rsp);
884
885 /* Done */
886 event_done(&conn);
887
888 /* Prepare */
889 event_prepare(&conn);
890
891 /* Tx Queue should have one LL Control PDU */
892 lt_rx(LL_CIS_IND, &conn, &tx, &local_cis_ind);
893 lt_rx_q_is_empty(&conn);
894
895 /* Done */
896 event_done(&conn);
897
898 /* */
899 while (!is_instant_reached(&conn, remote_cis_rsp.conn_event_count)) {
900 /* Prepare */
901 event_prepare(&conn);
902
903 /* Tx Queue should NOT have a LL Control PDU */
904 lt_rx_q_is_empty(&conn);
905
906 /* Done */
907 event_done(&conn);
908
909 /* There should NOT be a host notification */
910 ut_rx_q_is_empty();
911 }
912
913 /* Prepare */
914 event_prepare(&conn);
915
916 /* Done */
917 event_done(&conn);
918
919 /* Emulate CIS becoming established */
920 ull_cp_cc_established(&conn, 0);
921
922 /* Prepare */
923 event_prepare(&conn);
924
925 /* Tx Queue should NOT have a LL Control PDU */
926 lt_rx_q_is_empty(&conn);
927
928 /* Done */
929 event_done(&conn);
930
931 /* Prepare */
932 event_prepare(&conn);
933
934 /* There should be exactly one host notification */
935 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
936 ut_rx_q_is_empty();
937
938 /* Done */
939 event_done(&conn);
940
941 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
942 "Free CTX buffers %d", llcp_ctx_buffers_free());
943 }
944
945 /*
946 * Central-initiated CIS Create procedure.
947 * Central requests CIS, peripheral rejects with 'unsupported remote feature'
948 *
949 * +-----+ +-------+ +-----+
950 * | UT | | LL_C | | LT |
951 * +-----+ +-------+ +-----+
952 * | | |
953 * | LE CIS Create | |
954 * |-------------------------->| |
955 * | | LL_CIS_REQ |
956 * | |-------------------------->|
957 * | | |
958 * | | LL_REJECT_EXT_IND |
959 * | | (unsupported remote feat) |
960 * | |<--------------------------|
961 * | | |
962 * | | |
963 * | | |
964 * | | |
965 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
966 * | | |
967 * | LE CIS ESTABLISHED | |
968 * |<--------------------------| |
969 */
ZTEST(cis_create,test_cc_create_central_rem_reject)970 ZTEST(cis_create, test_cc_create_central_rem_reject)
971 {
972 struct node_rx_conn_iso_estab cis_estab = {
973 .cis_handle = 0x00,
974 .status = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE
975 };
976 struct pdu_data_llctrl_reject_ext_ind remote_reject = {
977 .error_code = BT_HCI_ERR_UNSUPP_REMOTE_FEATURE,
978 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CIS_REQ
979 };
980 struct ll_conn_iso_stream *cis;
981 struct node_rx_pdu *ntf;
982 struct node_tx *tx;
983 uint8_t err;
984
985 /* Prepare mocked call to ll_conn_iso_stream_get() */
986 ll_conn_iso_stream_get_fake.return_val = &cis_mock;
987
988 /* Role */
989 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
990
991 /* Connect */
992 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
993 conn.llcp.fex.valid = 1;
994 conn.llcp.fex.features_peer |= BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL);
995
996 /* Setup default CIS/CIG parameters */
997 cis = ll_conn_iso_stream_get(LL_CIS_HANDLE_BASE);
998 cis->lll.acl_handle = conn.lll.handle;
999 cis->group->cig_id = local_cis_req.cig_id;
1000 cis->cis_id = local_cis_req.cis_id;
1001 cis->lll.tx.phy = local_cis_req.c_phy;
1002 cis->lll.rx.phy = local_cis_req.p_phy;
1003 cis->group->c_sdu_interval = 0;
1004 cis->group->p_sdu_interval = 0;
1005 cis->lll.tx.max_pdu = MAX_xDU;
1006 cis->lll.rx.max_pdu = MAX_xDU;
1007 cis->c_max_sdu = MAX_xDU;
1008 cis->p_max_sdu = MAX_xDU;
1009 cis->group->iso_interval = local_cis_req.iso_interval;
1010 cis->framed = 0;
1011 cis->lll.nse = local_cis_req.nse;
1012 cis->lll.sub_interval = 0;
1013 cis->lll.tx.bn = local_cis_req.c_bn;
1014 cis->lll.rx.bn = local_cis_req.p_bn;
1015 cis->lll.tx.ft = local_cis_req.c_ft;
1016 cis->lll.rx.ft = local_cis_req.p_ft;
1017
1018 err = ull_cp_cis_create(&conn, cis);
1019 zassert_equal(err, BT_HCI_ERR_SUCCESS);
1020
1021 /* Prepare */
1022 event_prepare(&conn);
1023
1024 /* Tx Queue should have one LL Control PDU */
1025 lt_rx(LL_CIS_REQ, &conn, &tx, &local_cis_req);
1026 lt_rx_q_is_empty(&conn);
1027
1028 /* Done */
1029 event_done(&conn);
1030
1031 /* Prepare */
1032 event_prepare(&conn);
1033
1034 /* Rx */
1035 lt_tx(LL_REJECT_EXT_IND, &conn, &remote_reject);
1036
1037 /* Done */
1038 event_done(&conn);
1039
1040 /* Prepare */
1041 event_prepare(&conn);
1042
1043 /* There should be exactly one host notification */
1044 ut_rx_node(NODE_CIS_ESTABLISHED, &ntf, &cis_estab);
1045 ut_rx_q_is_empty();
1046
1047 zassert_equal(conn.llcp.fex.features_peer & BIT64(BT_LE_FEAT_BIT_CIS_PERIPHERAL), 0);
1048
1049 /* Done */
1050 event_done(&conn);
1051
1052 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
1053 "Free CTX buffers %d", llcp_ctx_buffers_free());
1054 }
1055
1056
1057 ZTEST_SUITE(cis_create, NULL, NULL, cis_create_setup, NULL, NULL);
1058