1 /*
2 * Copyright (c) 2020 Demant
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <zephyr/types.h>
9 #include <zephyr/ztest.h>
10
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #include "util/util.h"
15 #include "util/memq.h"
16 #include "util/dbuf.h"
17
18 #include "pdu_df.h"
19 #include "lll/pdu_vendor.h"
20 #include "hal/ccm.h"
21
22 #include "pdu.h"
23 #include "lll.h"
24 #include "lll/lll_df_types.h"
25 #include "lll_conn.h"
26
27 #include "ull_tx_queue.h"
28
29 #define SIZE 10U
30
ZTEST(tx_q,test_init)31 ZTEST(tx_q, test_init)
32 {
33 struct ull_tx_q tx_q;
34 struct node_tx *node;
35
36 ull_tx_q_init(&tx_q);
37 zassert_equal(0U, tx_q.pause_data, "pause_data must be zero on init");
38
39 /* Tx Queue shall be empty */
40 node = ull_tx_q_dequeue(&tx_q);
41 zassert_equal_ptr(node, NULL, "");
42 }
43
44 /*
45 * (1) Enqueue ctrl nodes.
46 * Dequeue and verify order of the ctrl nodes from (1).
47 * Verify Tx Queue is empty.
48 */
ZTEST(tx_q,test_ctrl)49 ZTEST(tx_q, test_ctrl)
50 {
51 struct ull_tx_q tx_q;
52 struct node_tx *node;
53 struct node_tx ctrl_nodes1[SIZE] = { 0 };
54
55 ull_tx_q_init(&tx_q);
56
57 /* Enqueue ctrl nodes */
58 for (int i = 0U; i < SIZE; i++) {
59 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes1[i]);
60 }
61
62 /* Dequeue ctrl nodes */
63 for (int i = 0U; i < SIZE; i++) {
64 node = ull_tx_q_dequeue(&tx_q);
65 zassert_equal_ptr(node, &ctrl_nodes1[i], NULL);
66 }
67
68 /* Tx Queue shall be empty */
69 node = ull_tx_q_dequeue(&tx_q);
70 zassert_equal_ptr(node, NULL, "");
71 }
72
73 /*
74 * (1) Enqueue data nodes.
75 * Dequeue and verify order of the data nodes from (1).
76 * Verify Tx Queue is empty.
77 */
ZTEST(tx_q,test_data)78 ZTEST(tx_q, test_data)
79 {
80 struct ull_tx_q tx_q;
81 struct node_tx *node;
82 struct node_tx nodes[SIZE] = { 0 };
83
84 ull_tx_q_init(&tx_q);
85
86 /* Enqueue data nodes */
87 for (int i = 0U; i < SIZE; i++) {
88 ull_tx_q_enqueue_data(&tx_q, &nodes[i]);
89 }
90
91 /* Dequeue data nodes */
92 for (int i = 0U; i < SIZE; i++) {
93 node = ull_tx_q_dequeue(&tx_q);
94 zassert_equal_ptr(node, &nodes[i], NULL);
95 }
96
97 /* Tx Queue shall be empty */
98 node = ull_tx_q_dequeue(&tx_q);
99 zassert_equal_ptr(node, NULL, "");
100 }
101
102 /*
103 * (1) Enqueue ctrl and data nodes interleaved.
104 * Dequeue and verify order of the data and ctrl nodes from (1).
105 * Verify Tx Queue is empty.
106 */
ZTEST(tx_q,test_ctrl_and_data_1)107 ZTEST(tx_q, test_ctrl_and_data_1)
108 {
109 struct ull_tx_q tx_q;
110 struct node_tx *node;
111 struct node_tx ctrl_nodes1[SIZE] = { 0 };
112 struct node_tx data_nodes1[SIZE] = { 0 };
113
114 ull_tx_q_init(&tx_q);
115
116 /* Enqueue ctrl and data nodes */
117 for (int i = 0U; i < SIZE; i++) {
118 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes1[i]);
119 ull_tx_q_enqueue_data(&tx_q, &data_nodes1[i]);
120 }
121
122 /* Dequeue ctrl and data nodes */
123 for (int i = 0U; i < SIZE; i++) {
124 node = ull_tx_q_dequeue(&tx_q);
125 zassert_equal_ptr(node, &ctrl_nodes1[i], NULL);
126
127 node = ull_tx_q_dequeue(&tx_q);
128 zassert_equal_ptr(node, &data_nodes1[i], NULL);
129 }
130
131 /* Tx Queue shall be empty */
132 node = ull_tx_q_dequeue(&tx_q);
133 zassert_equal_ptr(node, NULL, "");
134 }
135
136 /*
137 * (1) Enqueue ctrl and data nodes interleaved.
138 * Pause Tx Queue.
139 * (2) Enqueue data nodes.
140 * Dequeue and verify order of the data and ctrl nodes from (1).
141 * Verify Tx Queue is empty.
142 */
ZTEST(tx_q,test_ctrl_and_data_2)143 ZTEST(tx_q, test_ctrl_and_data_2)
144 {
145 struct ull_tx_q tx_q;
146 struct node_tx *node;
147 struct node_tx ctrl_nodes1[SIZE] = { 0 };
148 struct node_tx data_nodes1[SIZE] = { 0 };
149 struct node_tx data_nodes2[SIZE] = { 0 };
150
151 ull_tx_q_init(&tx_q);
152
153 /* Enqueue ctrl and data nodes */
154 for (int i = 0U; i < SIZE; i++) {
155 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes1[i]);
156 ull_tx_q_enqueue_data(&tx_q, &data_nodes1[i]);
157 }
158
159 /* Pause Tx Queue */
160 ull_tx_q_pause_data(&tx_q);
161
162 /* Enqueue data nodes */
163 for (int i = 0U; i < SIZE; i++) {
164 ull_tx_q_enqueue_data(&tx_q, &data_nodes2[i]);
165 }
166
167 /* Dequeue ctrl and data nodes */
168 for (int i = 0U; i < SIZE; i++) {
169 node = ull_tx_q_dequeue(&tx_q);
170 zassert_equal_ptr(node, &ctrl_nodes1[i], NULL);
171
172 node = ull_tx_q_dequeue(&tx_q);
173 zassert_equal_ptr(node, &data_nodes1[i], NULL);
174 }
175
176 /* Tx Queue shall be empty */
177 node = ull_tx_q_dequeue(&tx_q);
178 zassert_equal_ptr(node, NULL, "");
179 }
180
181 /*
182 * (1) Enqueue ctrl and data nodes interleaved.
183 * Pause Tx Queue.
184 * (2) Enqueue ctrl and data nodes interleaved.
185 * Dequeue and verify order of ctrl and data nodes from (1).
186 * Dequeue and verify order of ctrl nodes from (2).
187 * Verify Tx Queue is empty.
188 */
ZTEST(tx_q,test_ctrl_and_data_3)189 ZTEST(tx_q, test_ctrl_and_data_3)
190 {
191 struct ull_tx_q tx_q;
192 struct node_tx *node;
193 struct node_tx ctrl_nodes1[SIZE] = { 0 };
194 struct node_tx ctrl_nodes2[SIZE] = { 0 };
195 struct node_tx data_nodes1[SIZE] = { 0 };
196 struct node_tx data_nodes2[SIZE] = { 0 };
197
198 ull_tx_q_init(&tx_q);
199
200 /* Enqueue ctrl and data nodes */
201 for (int i = 0U; i < SIZE; i++) {
202 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes1[i]);
203 ull_tx_q_enqueue_data(&tx_q, &data_nodes1[i]);
204 }
205
206 /* Pause Tx Queue */
207 ull_tx_q_pause_data(&tx_q);
208
209 /* Enqueue ctrl and data nodes */
210 for (int i = 0U; i < SIZE; i++) {
211 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes2[i]);
212 ull_tx_q_enqueue_data(&tx_q, &data_nodes2[i]);
213 }
214
215 /* Dequeue ctrl and data nodes */
216 for (int i = 0U; i < SIZE; i++) {
217 node = ull_tx_q_dequeue(&tx_q);
218 zassert_equal_ptr(node, &ctrl_nodes1[i], NULL);
219
220 node = ull_tx_q_dequeue(&tx_q);
221 zassert_equal_ptr(node, &data_nodes1[i], NULL);
222 }
223
224 /* Dequeue ctrl nodes */
225 for (int i = 0U; i < SIZE; i++) {
226 node = ull_tx_q_dequeue(&tx_q);
227 zassert_equal_ptr(node, &ctrl_nodes2[i], NULL);
228 }
229
230 /* Tx Queue shall be empty */
231 node = ull_tx_q_dequeue(&tx_q);
232 zassert_equal_ptr(node, NULL, "");
233 }
234
235 /*
236 * (1) Enqueue ctrl and data nodes interleaved.
237 * Pause Tx Queue.
238 * (2) Enqueue ctrl and data nodes interleaved.
239 * Resume Tx Queue.
240 * Dequeue and verify order of ctrl and data nodes from (1).
241 * Dequeue and verify order of ctrl nodes from (2).
242 * Dequeue and verify order of data nodes from (2).
243 * Verify Tx Queue is empty.
244 */
ZTEST(tx_q,test_ctrl_and_data_4)245 ZTEST(tx_q, test_ctrl_and_data_4)
246 {
247 struct ull_tx_q tx_q;
248 struct node_tx *node;
249 struct node_tx ctrl_nodes1[SIZE] = { 0 };
250 struct node_tx ctrl_nodes2[SIZE] = { 0 };
251 struct node_tx data_nodes1[SIZE] = { 0 };
252 struct node_tx data_nodes2[SIZE] = { 0 };
253
254 ull_tx_q_init(&tx_q);
255
256 /* Enqueue ctrl and data nodes */
257 for (int i = 0U; i < SIZE; i++) {
258 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes1[i]);
259 ull_tx_q_enqueue_data(&tx_q, &data_nodes1[i]);
260 }
261
262 /* Pause Tx Queue */
263 ull_tx_q_pause_data(&tx_q);
264
265 /* Enqueue ctrl and data nodes */
266 for (int i = 0U; i < SIZE; i++) {
267 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes2[i]);
268 ull_tx_q_enqueue_data(&tx_q, &data_nodes2[i]);
269 }
270
271 /* Resume Tx Queue */
272 ull_tx_q_resume_data(&tx_q);
273
274 /* Dequeue ctrl and data nodes */
275 for (int i = 0U; i < SIZE; i++) {
276 node = ull_tx_q_dequeue(&tx_q);
277 zassert_equal_ptr(node, &ctrl_nodes1[i], NULL);
278
279 node = ull_tx_q_dequeue(&tx_q);
280 zassert_equal_ptr(node, &data_nodes1[i], NULL);
281 }
282
283 /* Dequeue ctrl nodes */
284 for (int i = 0U; i < SIZE; i++) {
285 node = ull_tx_q_dequeue(&tx_q);
286 zassert_equal_ptr(node, &ctrl_nodes2[i], NULL);
287 }
288
289 /* Dequeue data nodes */
290 for (int i = 0U; i < SIZE; i++) {
291 node = ull_tx_q_dequeue(&tx_q);
292 zassert_equal_ptr(node, &data_nodes2[i], NULL);
293 }
294
295 /* Tx Queue shall be empty */
296 node = ull_tx_q_dequeue(&tx_q);
297 zassert_equal_ptr(node, NULL, "");
298 }
299
300 /*
301 * (1) Enqueue ctrl and data nodes interleaved.
302 * Pause Tx Queue.
303 * (2) Enqueue ctrl and data nodes interleaved.
304 * Resume Tx Queue.
305 * (3) Enqueue ctrl and data nodes interleaved.
306 * Dequeue and verify order of ctrl and data nodes from (1).
307 * Dequeue and verify order of ctrl nodes from (2).
308 * Dequeue and verify order of data nodes from (2).
309 * Dequeue and verify order of ctrl and data nodes from (3).
310 * Verify Tx Queue is empty.
311 */
ZTEST(tx_q,test_ctrl_and_data_5)312 ZTEST(tx_q, test_ctrl_and_data_5)
313 {
314 struct ull_tx_q tx_q;
315 struct node_tx *node;
316 struct node_tx ctrl_nodes1[SIZE] = { 0 };
317 struct node_tx ctrl_nodes2[SIZE] = { 0 };
318 struct node_tx ctrl_nodes3[SIZE] = { 0 };
319 struct node_tx data_nodes1[SIZE] = { 0 };
320 struct node_tx data_nodes2[SIZE] = { 0 };
321 struct node_tx data_nodes3[SIZE] = { 0 };
322
323 ull_tx_q_init(&tx_q);
324
325 /* Enqueue ctrl and data nodes */
326 for (int i = 0U; i < SIZE; i++) {
327 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes1[i]);
328 ull_tx_q_enqueue_data(&tx_q, &data_nodes1[i]);
329 }
330
331 /* Pause Tx Queue */
332 ull_tx_q_pause_data(&tx_q);
333
334 /* Enqueue ctrl and data nodes */
335 for (int i = 0U; i < SIZE; i++) {
336 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes2[i]);
337 ull_tx_q_enqueue_data(&tx_q, &data_nodes2[i]);
338 }
339
340 /* Resume Tx Queue */
341 ull_tx_q_resume_data(&tx_q);
342
343 /* Enqueue ctrl and data nodes */
344 for (int i = 0U; i < SIZE; i++) {
345 ull_tx_q_enqueue_ctrl(&tx_q, &ctrl_nodes3[i]);
346 ull_tx_q_enqueue_data(&tx_q, &data_nodes3[i]);
347 }
348
349 /* Dequeue ctrl and data nodes */
350 for (int i = 0U; i < SIZE; i++) {
351 struct node_tx *node;
352
353 node = ull_tx_q_dequeue(&tx_q);
354 zassert_equal_ptr(node, &ctrl_nodes1[i], NULL);
355
356 node = ull_tx_q_dequeue(&tx_q);
357 zassert_equal_ptr(node, &data_nodes1[i], NULL);
358 }
359
360 /* Dequeue ctrl nodes */
361 for (int i = 0U; i < SIZE; i++) {
362 struct node_tx *node = ull_tx_q_dequeue(&tx_q);
363
364 zassert_equal_ptr(node, &ctrl_nodes2[i], NULL);
365 }
366
367 /* Dequeue data nodes */
368 for (int i = 0U; i < SIZE; i++) {
369 struct node_tx *node = ull_tx_q_dequeue(&tx_q);
370
371 zassert_equal_ptr(node, &data_nodes2[i], NULL);
372 }
373
374 /* Dequeue ctrl and data nodes */
375 for (int i = 0U; i < SIZE; i++) {
376 node = ull_tx_q_dequeue(&tx_q);
377 zassert_equal_ptr(node, &ctrl_nodes3[i], NULL);
378
379 node = ull_tx_q_dequeue(&tx_q);
380 zassert_equal_ptr(node, &data_nodes3[i], NULL);
381 }
382
383 /* Tx Queue shall be empty */
384 node = ull_tx_q_dequeue(&tx_q);
385 zassert_equal_ptr(node, NULL, "");
386 }
387
388 /*
389 * (1) Enqueue data nodes.
390 * Pause Tx Queue TWICE.
391 * (2) Enqueue data nodes.
392 * Dequeue and verify order of data nodes from (1).
393 * Verify Tx Queue is empty.
394 * Resume Tx Queue.
395 * Verify Tx Queue is empty.
396 * Resume Tx Queue.
397 * Dequeue and verify order of data nodes from (2).
398 */
ZTEST(tx_q,test_multiple_pause_resume)399 ZTEST(tx_q, test_multiple_pause_resume)
400 {
401 struct ull_tx_q tx_q;
402 struct node_tx *node;
403 struct node_tx data_nodes1[SIZE] = { 0 };
404 struct node_tx data_nodes2[SIZE] = { 0 };
405
406 ull_tx_q_init(&tx_q);
407
408 /* Enqueue data 1 nodes */
409 for (int i = 0U; i < SIZE; i++) {
410 ull_tx_q_enqueue_data(&tx_q, &data_nodes1[i]);
411 }
412
413 /* Pause Tx Queue Twice */
414 ull_tx_q_pause_data(&tx_q);
415 ull_tx_q_pause_data(&tx_q);
416
417 /* Enqueue data 2 nodes */
418 for (int i = 0U; i < SIZE; i++) {
419 ull_tx_q_enqueue_data(&tx_q, &data_nodes2[i]);
420 }
421
422 /* Dequeue data 1 nodes */
423 for (int i = 0U; i < SIZE; i++) {
424 node = ull_tx_q_dequeue(&tx_q);
425 zassert_equal_ptr(node, &data_nodes1[i], NULL);
426 }
427
428 /* Tx Queue shall be empty */
429 node = ull_tx_q_dequeue(&tx_q);
430 zassert_equal_ptr(node, NULL, "");
431
432 /* Resume Tx Queue */
433 ull_tx_q_resume_data(&tx_q);
434
435 /* Tx Queue shall be empty */
436 node = ull_tx_q_dequeue(&tx_q);
437 zassert_equal_ptr(node, NULL, "");
438
439 /* Resume Tx Queue */
440 ull_tx_q_resume_data(&tx_q);
441
442 /* Dequeue data 2 nodes */
443 for (int i = 0U; i < SIZE; i++) {
444 node = ull_tx_q_dequeue(&tx_q);
445 zassert_equal_ptr(node, &data_nodes2[i], NULL);
446 }
447
448 /* Tx Queue shall be empty */
449 node = ull_tx_q_dequeue(&tx_q);
450 zassert_equal_ptr(node, NULL, "");
451 }
452
453 ZTEST_SUITE(tx_q, NULL, NULL, NULL, NULL, NULL);
454