1 /*
2 * Copyright (c) 2020 Demant
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/types.h>
8 #include <zephyr/ztest.h>
9
10 #define ULL_LLCP_UNITTEST
11
12 #include <zephyr/bluetooth/hci.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/sys/slist.h>
15 #include <zephyr/sys/util.h>
16 #include "hal/ccm.h"
17
18 #include "util/util.h"
19 #include "util/mem.h"
20 #include "util/memq.h"
21 #include "util/dbuf.h"
22
23 #include "pdu_df.h"
24 #include "lll/pdu_vendor.h"
25 #include "pdu.h"
26 #include "ll.h"
27 #include "ll_settings.h"
28
29 #include "lll.h"
30 #include "lll/lll_df_types.h"
31 #include "lll_conn.h"
32 #include "lll_conn_iso.h"
33
34 #include "ull_tx_queue.h"
35
36 #include "isoal.h"
37 #include "ull_iso_types.h"
38 #include "ull_conn_iso_types.h"
39 #include "ull_conn_types.h"
40 #include "ull_llcp.h"
41 #include "ull_conn_internal.h"
42 #include "ull_llcp_internal.h"
43
44 #include "helper_pdu.h"
45 #include "helper_util.h"
46
47 #define INTVL_MIN 6U /* multiple of 1.25 ms (min 6, max 3200) */
48 #define INTVL_MAX 6U /* multiple of 1.25 ms (min 6, max 3200) */
49 #define LATENCY 1U
50 #define TIMEOUT 10U /* multiple of 10 ms (min 10, max 3200) */
51
52 #define PREFER_S8_CODING 1
53 #define PREFER_S2_CODING 0
54
55 static struct ll_conn conn;
56
57 struct pdu_data_llctrl_conn_update_ind conn_update_ind = { .win_size = 1U,
58 .win_offset = 0U,
59 .interval = INTVL_MAX,
60 .latency = LATENCY,
61 .timeout = TIMEOUT,
62 .instant = 6U };
63
64 struct pdu_data_llctrl_conn_param_req conn_param_req_B = {
65 .interval_min = INTVL_MIN,
66 .interval_max = INTVL_MAX,
67 .latency = LATENCY + 1U, /* differentiate parameter */
68 .timeout = TIMEOUT + 1U, /* differentiate parameter */
69 .preferred_periodicity = 0U,
70 .reference_conn_event_count = 0u,
71 .offset0 = 0x0000U,
72 .offset1 = 0xffffU,
73 .offset2 = 0xffffU,
74 .offset3 = 0xffffU,
75 .offset4 = 0xffffU,
76 .offset5 = 0xffffU
77 };
78
79 struct pdu_data_llctrl_conn_param_rsp conn_param_rsp = { .interval_min = INTVL_MIN,
80 .interval_max = INTVL_MAX,
81 .latency = LATENCY,
82 .timeout = TIMEOUT,
83 .preferred_periodicity = 0U,
84 .reference_conn_event_count = 0u,
85 .offset0 = 0x0000U,
86 .offset1 = 0xffffU,
87 .offset2 = 0xffffU,
88 .offset3 = 0xffffU,
89 .offset4 = 0xffffU,
90 .offset5 = 0xffffU };
91
92 struct pdu_data_llctrl_conn_param_req *req_B = &conn_param_req_B;
93
collision_setup(void * data)94 static void collision_setup(void *data)
95 {
96 test_setup(&conn);
97
98 /* Emulate initial conn state */
99 conn.phy_pref_rx = PHY_1M | PHY_2M | PHY_CODED;
100 conn.phy_pref_tx = PHY_1M | PHY_2M | PHY_CODED;
101 conn.lll.phy_flags = PREFER_S2_CODING;
102 conn.lll.phy_tx_time = PHY_1M;
103 conn.lll.phy_rx = PHY_1M;
104 conn.lll.phy_tx = PHY_1M;
105
106 /* Init DLE data */
107 ull_conn_default_tx_octets_set(251);
108 ull_conn_default_tx_time_set(2120);
109 ull_dle_init(&conn, PHY_1M);
110 /* Emulate different remote numbers to trigger update of eff */
111 conn.lll.dle.remote.max_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN * 3;
112 conn.lll.dle.remote.max_rx_octets = PDU_DC_PAYLOAD_SIZE_MIN * 3;
113 conn.lll.dle.remote.max_tx_time = PDU_DC_MAX_US(conn.lll.dle.remote.max_tx_octets,
114 PHY_1M);
115 conn.lll.dle.remote.max_rx_time = PDU_DC_MAX_US(conn.lll.dle.remote.max_rx_octets,
116 PHY_1M);
117 ull_dle_update_eff(&conn);
118 }
119
120 #define CHECK_PREF_PHY_STATE(_conn, _tx, _rx) \
121 do { \
122 zassert_equal(_conn.phy_pref_rx, _rx, \
123 "Preferred RX PHY mismatch %d (actual) != %d (expected)", \
124 _conn.phy_pref_rx, _rx); \
125 zassert_equal(_conn.phy_pref_tx, _tx, \
126 "Preferred TX PHY mismatch %d (actual) != %d (expected)", \
127 _conn.phy_pref_tx, _tx); \
128 } while (0)
129
130 #define CHECK_CURRENT_PHY_STATE(_conn, _tx, _flags, _rx) \
131 do { \
132 zassert_equal(_conn.lll.phy_rx, _rx, \
133 "Current RX PHY mismatch %d (actual) != %d (expected)", \
134 _conn.lll.phy_rx, _rx); \
135 zassert_equal(_conn.lll.phy_tx, _tx, \
136 "Current TX PHY mismatch %d (actual) != %d (expected)", \
137 _conn.lll.phy_tx, _tx); \
138 zassert_equal(_conn.lll.phy_rx, _rx, \
139 "Current Flags mismatch %d (actual) != %d (expected)", \
140 _conn.lll.phy_flags, _flags); \
141 } while (0)
142
143
is_instant_reached(struct ll_conn * conn,uint16_t instant)144 static bool is_instant_reached(struct ll_conn *conn, uint16_t instant)
145 {
146 return ((event_counter(conn) - instant) & 0xFFFF) <= 0x7FFF;
147 }
148
ZTEST(collision,test_phy_update_central_loc_collision)149 ZTEST(collision, test_phy_update_central_loc_collision)
150 {
151 uint8_t err;
152 struct node_tx *tx;
153 struct node_rx_pdu *ntf;
154 struct pdu_data *pdu;
155 struct pdu_data_llctrl_phy_req req = { .rx_phys = PHY_2M, .tx_phys = PHY_2M };
156 struct pdu_data_llctrl_phy_req rsp = { .rx_phys = PHY_1M | PHY_2M,
157 .tx_phys = PHY_1M | PHY_2M };
158 struct pdu_data_llctrl_phy_upd_ind ind = { .instant = 9,
159 .c_to_p_phy = PHY_2M,
160 .p_to_c_phy = PHY_2M };
161 uint16_t instant;
162
163 struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = {
164 .reject_opcode = PDU_DATA_LLCTRL_TYPE_PHY_REQ,
165 .error_code = BT_HCI_ERR_LL_PROC_COLLISION
166 };
167
168 struct node_rx_pu pu = { .status = BT_HCI_ERR_SUCCESS };
169
170 /* Role */
171 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
172
173 /* Emulate valid feature exchange */
174 conn.llcp.fex.valid = 1;
175
176 /* Connect */
177 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
178
179 /* Initiate an PHY Update Procedure */
180 err = ull_cp_phy_update(&conn, PHY_2M, PREFER_S8_CODING, PHY_2M, 1);
181 zassert_equal(err, BT_HCI_ERR_SUCCESS);
182
183 /*** ***/
184
185 /* Prepare */
186 event_prepare(&conn);
187
188 /* Tx Queue should have one LL Control PDU */
189 lt_rx(LL_PHY_REQ, &conn, &tx, &req);
190 lt_rx_q_is_empty(&conn);
191
192 /* Rx - emulate colliding PHY_REQ from peer */
193 lt_tx(LL_PHY_REQ, &conn, &req);
194
195 /* Check that data tx is paused */
196 zassert_equal(conn.tx_q.pause_data, 1U, "Data tx is not paused");
197
198 /* TX Ack */
199 event_tx_ack(&conn, tx);
200
201 /* Check that data tx is paused */
202 zassert_equal(conn.tx_q.pause_data, 1U, "Data tx is paused");
203
204 /* Done */
205 event_done(&conn);
206
207 /* Check that data tx is not paused */
208 zassert_equal(conn.tx_q.pause_data, 1U, "Data tx is not paused");
209
210 /* Release Tx */
211 ull_cp_release_tx(&conn, tx);
212
213 /*** ***/
214
215 /* Prepare */
216 event_prepare(&conn);
217 test_print_conn(&conn);
218 /* Tx Queue should have one LL Control PDU */
219 printf("Tx REJECT\n");
220 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &reject_ext_ind);
221 lt_rx_q_is_empty(&conn);
222
223 /* TX Ack */
224 event_tx_ack(&conn, tx);
225
226 /* Done */
227 printf("Done again\n");
228 event_done(&conn);
229
230 /* Release Tx */
231 ull_cp_release_tx(&conn, tx);
232
233 /*** ***/
234
235 /* Prepare */
236 event_prepare(&conn);
237
238 /* Tx Queue should NOT have a LL Control PDU */
239 printf("Empty\n");
240 lt_rx_q_is_empty(&conn);
241
242 /* Rx */
243 printf("Tx again\n");
244 lt_tx(LL_PHY_RSP, &conn, &rsp);
245
246 /* TX Ack */
247 event_tx_ack(&conn, tx);
248
249 /* Done */
250 event_done(&conn);
251
252 /* Check that data tx is paused */
253 zassert_equal(conn.tx_q.pause_data, 1U, "Data tx is not paused");
254
255 /*** ***/
256
257 /* Prepare */
258 event_prepare(&conn);
259
260 /* Tx Queue should have one LL Control PDU */
261 printf("And again\n");
262 lt_rx(LL_PHY_UPDATE_IND, &conn, &tx, &ind);
263 lt_rx_q_is_empty(&conn);
264
265 /* TX Ack */
266 event_tx_ack(&conn, tx);
267
268 /* Done */
269 event_done(&conn);
270
271 /* Check that data tx is not paused */
272 zassert_equal(conn.tx_q.pause_data, 0U, "Data tx is paused");
273
274 /* Save Instant */
275 pdu = (struct pdu_data *)tx->pdu;
276 instant = sys_le16_to_cpu(pdu->llctrl.phy_upd_ind.instant);
277
278 /* Release Tx */
279 ull_cp_release_tx(&conn, tx);
280
281 /* */
282 while (!is_instant_reached(&conn, instant)) {
283 /* Prepare */
284 event_prepare(&conn);
285
286 /* Tx Queue should NOT have a LL Control PDU */
287 lt_rx_q_is_empty(&conn);
288
289 /* Done */
290 event_done(&conn);
291
292 /* There should NOT be a host notification */
293 ut_rx_q_is_empty();
294 }
295
296 /*** ***/
297
298 /* Prepare */
299 event_prepare(&conn);
300
301 /* Tx Queue should NOT have a LL Control PDU */
302 lt_rx_q_is_empty(&conn);
303
304 /* Done */
305 event_done(&conn);
306
307 /* There should be one host notification */
308 ut_rx_node(NODE_PHY_UPDATE, &ntf, &pu);
309 ut_rx_q_is_empty();
310
311 /* Release Ntf */
312 release_ntf(ntf);
313
314 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
315 "Free CTX buffers %d", llcp_ctx_buffers_free());
316 }
317
ZTEST(collision,test_phy_update_central_rem_collision)318 ZTEST(collision, test_phy_update_central_rem_collision)
319 {
320 uint8_t err;
321 struct node_tx *tx;
322 struct node_rx_pdu *ntf;
323 struct pdu_data *pdu;
324 struct pdu_data_llctrl_phy_req req_peripheral = { .rx_phys = PHY_1M, .tx_phys = PHY_2M };
325 struct pdu_data_llctrl_phy_req req_central = { .rx_phys = PHY_2M, .tx_phys = PHY_2M };
326 struct pdu_data_llctrl_phy_req rsp = { .rx_phys = PHY_1M | PHY_2M,
327 .tx_phys = PHY_1M | PHY_2M };
328 struct pdu_data_llctrl_phy_upd_ind ind_1 = { .instant = 7,
329 .c_to_p_phy = 0,
330 .p_to_c_phy = PHY_2M };
331 struct pdu_data_llctrl_phy_upd_ind ind_2 = { .instant = 15,
332 .c_to_p_phy = PHY_2M,
333 .p_to_c_phy = 0 };
334 uint16_t instant;
335
336 struct node_rx_pu pu = { .status = BT_HCI_ERR_SUCCESS };
337
338 /* Role */
339 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
340
341 /* Connect */
342 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
343
344 /*** ***/
345
346 /* Prepare */
347 event_prepare(&conn);
348
349 /* Rx */
350 lt_tx(LL_PHY_REQ, &conn, &req_peripheral);
351
352 /* Done */
353 event_done(&conn);
354
355 /*** ***/
356
357 /* Initiate an PHY Update Procedure */
358 err = ull_cp_phy_update(&conn, PHY_2M, PREFER_S8_CODING, PHY_2M, 1);
359 zassert_equal(err, BT_HCI_ERR_SUCCESS);
360
361 /*** ***/
362
363 /* Prepare */
364 event_prepare(&conn);
365
366 /* Tx Queue should have one LL Control PDU */
367 lt_rx(LL_PHY_UPDATE_IND, &conn, &tx, &ind_1);
368 lt_rx_q_is_empty(&conn);
369
370 /* TX Ack */
371 event_tx_ack(&conn, tx);
372
373 /* Done */
374 event_done(&conn);
375
376 /* Save Instant */
377 pdu = (struct pdu_data *)tx->pdu;
378 instant = sys_le16_to_cpu(pdu->llctrl.phy_upd_ind.instant);
379
380 /* Release Tx */
381 ull_cp_release_tx(&conn, tx);
382
383 /* */
384 while (!is_instant_reached(&conn, instant)) {
385 /* Prepare */
386 event_prepare(&conn);
387
388 /* Tx Queue should NOT have a LL Control PDU */
389 lt_rx_q_is_empty(&conn);
390
391 /* Done */
392 event_done(&conn);
393
394 /* There should NOT be a host notification */
395 ut_rx_q_is_empty();
396 }
397
398 /*** ***/
399
400 /* Prepare */
401 event_prepare(&conn);
402
403 /* Tx Queue should NOT have a LL Control PDU */
404 lt_rx_q_is_empty(&conn);
405
406 /* Done */
407 event_done(&conn);
408
409 /* Prepare */
410 event_prepare(&conn);
411
412 /* Tx Queue should have one LL Control PDU */
413 lt_rx(LL_PHY_REQ, &conn, &tx, &req_central);
414 lt_rx_q_is_empty(&conn);
415
416 /* Rx */
417 lt_tx(LL_PHY_RSP, &conn, &rsp);
418
419 /* TX Ack */
420 event_tx_ack(&conn, tx);
421
422 /* Done */
423 event_done(&conn);
424
425 /* Release Tx */
426 ull_cp_release_tx(&conn, tx);
427
428 /* There should be one host notification */
429 ut_rx_node(NODE_PHY_UPDATE, &ntf, &pu);
430 ut_rx_q_is_empty();
431
432 /* Release Ntf */
433 release_ntf(ntf);
434
435 /* Prepare */
436 event_prepare(&conn);
437
438 /* Tx Queue should have one LL Control PDU */
439 lt_rx(LL_PHY_UPDATE_IND, &conn, &tx, &ind_2);
440 lt_rx_q_is_empty(&conn);
441
442 /* TX Ack */
443 event_tx_ack(&conn, tx);
444
445 /* Done */
446 event_done(&conn);
447
448 /* Save Instant */
449 pdu = (struct pdu_data *)tx->pdu;
450 instant = sys_le16_to_cpu(pdu->llctrl.phy_upd_ind.instant);
451
452 /* Release Tx */
453 ull_cp_release_tx(&conn, tx);
454
455 /* */
456 while (!is_instant_reached(&conn, instant)) {
457 /* Prepare */
458 event_prepare(&conn);
459
460 /* Tx Queue should NOT have a LL Control PDU */
461 lt_rx_q_is_empty(&conn);
462
463 /* Done */
464 event_done(&conn);
465
466 /* There should NOT be a host notification */
467 ut_rx_q_is_empty();
468 }
469
470 /* Prepare */
471 event_prepare(&conn);
472
473 /* Tx Queue should NOT have a LL Control PDU */
474 lt_rx_q_is_empty(&conn);
475
476 /* Done */
477 event_done(&conn);
478
479 /* There should be one host notification */
480 ut_rx_node(NODE_PHY_UPDATE, &ntf, &pu);
481 ut_rx_q_is_empty();
482
483 /* Release Ntf */
484 release_ntf(ntf);
485
486 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
487 "Free CTX buffers %d", llcp_ctx_buffers_free());
488 }
489
ZTEST(collision,test_phy_update_periph_loc_collision)490 ZTEST(collision, test_phy_update_periph_loc_collision)
491 {
492 uint8_t err;
493 struct node_tx *tx;
494 struct node_rx_pdu *ntf;
495 struct pdu_data_llctrl_phy_req req_central = { .rx_phys = PHY_1M, .tx_phys = PHY_2M };
496 struct pdu_data_llctrl_phy_req req_peripheral = { .rx_phys = PHY_2M, .tx_phys = PHY_2M };
497 struct pdu_data_llctrl_phy_req rsp = { .rx_phys = PHY_2M, .tx_phys = PHY_2M };
498 struct pdu_data_llctrl_phy_upd_ind ind = { .instant = 7,
499 .c_to_p_phy = PHY_2M,
500 .p_to_c_phy = PHY_1M };
501 uint16_t instant;
502
503 struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = {
504 .reject_opcode = PDU_DATA_LLCTRL_TYPE_PHY_REQ,
505 .error_code = BT_HCI_ERR_LL_PROC_COLLISION
506 };
507
508 struct node_rx_pu pu = { 0 };
509
510 /* Role */
511 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
512
513 /* Connect */
514 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
515
516 /*** ***/
517
518 /* Initiate an PHY Update Procedure */
519 err = ull_cp_phy_update(&conn, PHY_2M, PREFER_S8_CODING, PHY_2M, 1);
520 zassert_equal(err, BT_HCI_ERR_SUCCESS);
521
522 /* Prepare */
523 event_prepare(&conn);
524
525 /* Tx Queue should have one LL Control PDU */
526 lt_rx(LL_PHY_REQ, &conn, &tx, &req_peripheral);
527 lt_rx_q_is_empty(&conn);
528
529 /* Rx */
530 lt_tx(LL_PHY_REQ, &conn, &req_central);
531
532 /* TX Ack */
533 event_tx_ack(&conn, tx);
534
535 /* Done */
536 event_done(&conn);
537
538 /* Release Tx */
539 ull_cp_release_tx(&conn, tx);
540
541 /* Prepare */
542 event_prepare(&conn);
543
544 /* Tx Queue should have one LL Control PDU */
545 lt_rx(LL_PHY_RSP, &conn, &tx, &rsp);
546 lt_rx_q_is_empty(&conn);
547
548 /* Rx */
549 lt_tx(LL_REJECT_EXT_IND, &conn, &reject_ext_ind);
550
551 /* Done */
552 event_done(&conn);
553
554 /* Prepare */
555 event_prepare(&conn);
556
557 /* Done */
558 event_done(&conn);
559
560 /* There should be one host notification */
561 pu.status = BT_HCI_ERR_LL_PROC_COLLISION;
562 ut_rx_node(NODE_PHY_UPDATE, &ntf, &pu);
563 ut_rx_q_is_empty();
564
565 /* Release Ntf */
566 release_ntf(ntf);
567
568 /* Prepare */
569 event_prepare(&conn);
570
571 /* Rx */
572 ind.instant = instant = event_counter(&conn) + 6;
573 lt_tx(LL_PHY_UPDATE_IND, &conn, &ind);
574
575 /* TX Ack */
576 event_tx_ack(&conn, tx);
577
578 /* Done */
579 event_done(&conn);
580
581 /* Release Tx */
582 ull_cp_release_tx(&conn, tx);
583
584 /* */
585 while (!is_instant_reached(&conn, instant)) {
586 /* Prepare */
587 event_prepare(&conn);
588
589 /* Tx Queue should NOT have a LL Control PDU */
590 lt_rx_q_is_empty(&conn);
591
592 /* Done */
593 event_done(&conn);
594
595 /* There should NOT be a host notification */
596 ut_rx_q_is_empty();
597 }
598
599 /* Prepare */
600 event_prepare(&conn);
601
602 /* Tx Queue should NOT have a LL Control PDU */
603 lt_rx_q_is_empty(&conn);
604
605 /* Done */
606 event_done(&conn);
607
608 /* There should be one host notification */
609 pu.status = BT_HCI_ERR_SUCCESS;
610 ut_rx_node(NODE_PHY_UPDATE, &ntf, &pu);
611 ut_rx_q_is_empty();
612
613 /* Release Ntf */
614 release_ntf(ntf);
615
616 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
617 "Free CTX buffers %d", llcp_ctx_buffers_free());
618 }
619
ZTEST(collision,test_phy_conn_update_central_loc_collision)620 ZTEST(collision, test_phy_conn_update_central_loc_collision)
621 {
622 uint8_t err;
623 struct node_tx *tx;
624 struct node_rx_pdu *ntf;
625 struct pdu_data *pdu;
626 uint16_t instant;
627
628 struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = {
629 .reject_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ,
630 .error_code = BT_HCI_ERR_DIFF_TRANS_COLLISION
631 };
632 struct pdu_data_llctrl_phy_req req = { .rx_phys = PHY_2M, .tx_phys = PHY_2M };
633 struct pdu_data_llctrl_phy_req rsp = { .rx_phys = PHY_1M | PHY_2M,
634 .tx_phys = PHY_1M | PHY_2M };
635 struct pdu_data_llctrl_phy_upd_ind ind = { .instant = 9,
636 .c_to_p_phy = PHY_2M,
637 .p_to_c_phy = PHY_2M };
638
639 struct node_rx_pu pu = { .status = BT_HCI_ERR_SUCCESS };
640
641 /* Role */
642 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
643
644 /* Emulate valid feature exchange */
645 conn.llcp.fex.valid = 1;
646
647 /* Connect */
648 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
649
650 /* (A) Initiate a PHY update procedure */
651
652 err = ull_cp_phy_update(&conn, PHY_2M, PREFER_S8_CODING, PHY_2M, 1);
653 zassert_equal(err, BT_HCI_ERR_SUCCESS);
654
655 /* Prepare */
656 event_prepare(&conn);
657
658 /* (A) Tx Queue should have one LL Control PDU */
659 lt_rx(LL_PHY_REQ, &conn, &tx, &req);
660 lt_rx_q_is_empty(&conn);
661
662 /* (B) Rx */
663 lt_tx(LL_CONNECTION_PARAM_REQ, &conn, req_B);
664
665 event_tx_ack(&conn, tx);
666
667 /* Done */
668 event_done(&conn);
669
670 /* Release Tx */
671 ull_cp_release_tx(&conn, tx);
672
673 /* Prepare */
674 event_prepare(&conn);
675
676 /* (B) Rx Queue should have a REJECT_EXT_IND PDU */
677 lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &reject_ext_ind);
678 lt_rx_q_is_empty(&conn);
679
680 event_tx_ack(&conn, tx);
681
682 /* Done */
683 event_done(&conn);
684
685 /* Release Tx */
686 ull_cp_release_tx(&conn, tx);
687
688 /**/
689
690 /* Prepare */
691 event_prepare(&conn);
692
693 /* (B) Tx Queue should NOT have a LL Control PDU */
694 lt_rx_q_is_empty(&conn);
695
696 /* (A) Rx */
697 lt_tx(LL_PHY_RSP, &conn, &rsp);
698
699 /* Done */
700 event_done(&conn);
701
702 zassert_equal(conn.tx_q.pause_data, 1U, "Data tx is not paused");
703
704
705 /* Prepare */
706 event_prepare(&conn);
707
708 /* (A) Tx Queue should have one LL Control PDU */
709 lt_rx(LL_PHY_UPDATE_IND, &conn, &tx, &ind);
710 lt_rx_q_is_empty(&conn);
711 event_tx_ack(&conn, tx);
712
713 /* Done */
714 event_done(&conn);
715
716 /* Save Instant */
717 pdu = (struct pdu_data *)tx->pdu;
718 instant = sys_le16_to_cpu(pdu->llctrl.phy_upd_ind.instant);
719
720 /* Release Tx */
721 ull_cp_release_tx(&conn, tx);
722
723 /* */
724 while (!is_instant_reached(&conn, instant)) {
725 /* Prepare */
726 event_prepare(&conn);
727
728 /* (A) Tx Queue should NOT have a LL Control PDU */
729 lt_rx_q_is_empty(&conn);
730
731 /* Done */
732 event_done(&conn);
733
734 /* (A) There should NOT be a host notification */
735 ut_rx_q_is_empty();
736 }
737
738 /* Prepare */
739 event_prepare(&conn);
740
741 /* (A) Tx Queue should NOT have a LL Control PDU */
742 lt_rx_q_is_empty(&conn);
743
744 /* Done */
745 event_done(&conn);
746
747 /* (A) There should be one host notification */
748 ut_rx_node(NODE_PHY_UPDATE, &ntf, &pu);
749
750 ut_rx_q_is_empty();
751
752 /* Release Ntf */
753 release_ntf(ntf);
754 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
755 "Free CTX buffers %d", llcp_ctx_buffers_free());
756 }
757
758 ZTEST_SUITE(collision, NULL, NULL, collision_setup, NULL, NULL);
759