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/bluetooth/hci.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/slist.h>
13 #include <zephyr/sys/util.h>
14 #include "hal/ccm.h"
15 
16 #include "util/util.h"
17 #include "util/mem.h"
18 #include "util/memq.h"
19 #include "util/dbuf.h"
20 
21 #include "pdu_df.h"
22 #include "lll/pdu_vendor.h"
23 #include "pdu.h"
24 #include "ll.h"
25 #include "ll_feat.h"
26 #include "ll_settings.h"
27 
28 #include "lll.h"
29 #include "lll/lll_df_types.h"
30 #include "lll_conn.h"
31 #include "lll_conn_iso.h"
32 
33 #include "ull_tx_queue.h"
34 
35 #include "isoal.h"
36 #include "ull_iso_types.h"
37 #include "ull_conn_iso_types.h"
38 #include "ull_conn_types.h"
39 #include "ull_llcp.h"
40 #include "ull_conn_internal.h"
41 #include "ull_llcp_internal.h"
42 #include "ull_llcp_features.h"
43 
44 #include "helper_pdu.h"
45 #include "helper_util.h"
46 
47 static struct ll_conn conn;
48 
sca_setup(void * data)49 static void sca_setup(void *data)
50 {
51 	test_setup(&conn);
52 }
53 
54 /* +-----+                     +-------+            +-----+
55  * | UT  |                     | LL_A  |            | LT  |
56  * +-----+                     +-------+            +-----+
57  *    |                            |                                |
58  *    | Start                      |                                |
59  *    | SCA Update Proc.           |                                |
60  *    |--------------------------->|                                |
61  *    |                            |                                |
62  *    |                            | LL_CLOCK_ACCURACY_REQ          |
63  *    |                            |------------------------------->|
64  *    |                            |                                |
65  *    |                            |    LL_CLOCK_ACCURACY_RSP       |
66  *    |                            |<-------------------------------|
67  *    |                            |                                |
68  *    | Start                      |                                |
69  *    | SCA UPdate Proc.           |                                |
70  *    |--------------------------->|                                |
71  *    |                            |                                |
72  *    |                            | LL_CLOCK_ACCURACY_REQ          |
73  *    |                            |------------------------------->|
74  *    |                            |                                |
75  *    |                            |    LL_UNKNOWN_RSP              |
76  *    |                            |<-------------------------------|
77  *    |                            |                                |
78  */
ZTEST(sca_central,test_sca_central_loc)79 ZTEST(sca_central, test_sca_central_loc)
80 {
81 	uint8_t err;
82 	struct node_tx *tx;
83 	struct node_rx_pdu *ntf;
84 	struct node_rx_sca scau = { .status = BT_HCI_ERR_SUCCESS, .sca = 2 };
85 	struct pdu_data_llctrl_clock_accuracy_req local_sca_req = { };
86 	struct pdu_data_llctrl_clock_accuracy_rsp remote_sca_rsp = { .sca = 2 };
87 	struct pdu_data_llctrl_unknown_rsp unknown_rsp = {
88 		.type = PDU_DATA_LLCTRL_TYPE_CLOCK_ACCURACY_REQ
89 	};
90 
91 	/* Role */
92 	test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
93 
94 	/* Connect */
95 	ull_cp_state_set(&conn, ULL_CP_CONNECTED);
96 
97 	/* Initiate an SCA Procedure */
98 	err = ull_cp_req_peer_sca(&conn);
99 	zassert_equal(err, BT_HCI_ERR_SUCCESS);
100 
101 	/* Confirm SCA Update is indicated as supported */
102 	zassert_equal(feature_sca(&conn), true, "SCA Update Feature masked out");
103 
104 	/* Prepare */
105 	event_prepare(&conn);
106 
107 	/* Tx Queue should have one LL Control PDU */
108 	lt_rx(LL_CLOCK_ACCURACY_REQ, &conn, &tx, &local_sca_req);
109 	lt_rx_q_is_empty(&conn);
110 
111 	/* Rx */
112 	lt_tx(LL_CLOCK_ACCURACY_RSP, &conn, &remote_sca_rsp);
113 
114 	/* Done */
115 	event_done(&conn);
116 
117 	/* Release tx node */
118 	ull_cp_release_tx(&conn, tx);
119 
120 	/* Termination not 'triggered' */
121 	zassert_equal(conn.llcp_terminate.reason_final, 0,
122 		      "Terminate reason %d", conn.llcp_terminate.reason_final);
123 
124 	/* There should be one notification due to Peer SCA Request */
125 	ut_rx_node(NODE_PEER_SCA_UPDATE, &ntf, &scau);
126 	ut_rx_q_is_empty();
127 
128 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
129 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
130 
131 	/* Initiate another SCA Procedure */
132 	err = ull_cp_req_peer_sca(&conn);
133 	zassert_equal(err, BT_HCI_ERR_SUCCESS);
134 
135 	/* Prepare */
136 	event_prepare(&conn);
137 
138 	/* Tx Queue should have one LL Control PDU */
139 	lt_rx(LL_CLOCK_ACCURACY_REQ, &conn, &tx, &local_sca_req);
140 	lt_rx_q_is_empty(&conn);
141 
142 	/* Rx */
143 	lt_tx(LL_UNKNOWN_RSP, &conn, &unknown_rsp);
144 
145 	/* Done */
146 	event_done(&conn);
147 
148 	/* Release tx node */
149 	ull_cp_release_tx(&conn, tx);
150 
151 	/* Confirm SCA Update is now indicated as NOT supported */
152 	zassert_equal(feature_sca(&conn), false, "SCA Update Feature masked in");
153 
154 	/* Termination not 'triggered' */
155 	zassert_equal(conn.llcp_terminate.reason_final, 0,
156 		      "Terminate reason %d", conn.llcp_terminate.reason_final);
157 
158 	scau.status = BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
159 	scau.sca = 0;
160 
161 	/* There should be one notification due to Peer SCA Request */
162 	ut_rx_node(NODE_PEER_SCA_UPDATE, &ntf, &scau);
163 	ut_rx_q_is_empty();
164 
165 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
166 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
167 
168 }
169 
170 /* +-----+                     +-------+                   +-----+
171  * | UT  |                     | LL_A  |                   | LT  |
172  * +-----+                     +-------+                   +-----+
173  *    |                            |                          |
174  *    | Start                      |                          |
175  *    | SCA Update Proc.           |                          |
176  *    |--------------------------->|                          |
177  *    |                            |                          |
178  *    |                            | LL_CLOCK_ACCURACY_REQ    |
179  *    |                            |------------------------->|
180  *    |                            |                          |
181  *    |                            | LL_<INVALID>_RSP         |
182  *    |                            |<-------------------------|
183  *    |                            |                          |
184  *       ~~~~~~~~~~~~~~~~~ TERMINATE CONNECTION ~~~~~~~~~~~~~~
185  *    |                            |                          |
186  */
ZTEST(sca_central,test_sca_central_loc_invalid_rsp)187 ZTEST(sca_central, test_sca_central_loc_invalid_rsp)
188 {
189 	uint8_t err;
190 	struct node_tx *tx;
191 
192 	struct pdu_data_llctrl_reject_ind reject_ind = {
193 		.error_code = BT_HCI_ERR_LL_PROC_COLLISION
194 	};
195 	struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = {
196 		.reject_opcode = PDU_DATA_LLCTRL_TYPE_CLOCK_ACCURACY_REQ,
197 		.error_code = BT_HCI_ERR_LL_PROC_COLLISION
198 	};
199 	struct pdu_data_llctrl_clock_accuracy_req local_sca_req = {};
200 
201 	/* Role */
202 	test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
203 
204 	/* Connect */
205 	ull_cp_state_set(&conn, ULL_CP_CONNECTED);
206 
207 	/* Initiate an SCA Procedure */
208 	err = ull_cp_req_peer_sca(&conn);
209 	zassert_equal(err, BT_HCI_ERR_SUCCESS);
210 
211 	/* Prepare */
212 	event_prepare(&conn);
213 
214 	/* Tx Queue should have one LL Control PDU */
215 	lt_rx(LL_CLOCK_ACCURACY_REQ, &conn, &tx, &local_sca_req);
216 	lt_rx_q_is_empty(&conn);
217 
218 	/* Rx */
219 	lt_tx(LL_REJECT_EXT_IND, &conn, &reject_ext_ind);
220 
221 	/* Done */
222 	event_done(&conn);
223 
224 	/* Release tx node */
225 	ull_cp_release_tx(&conn, tx);
226 
227 	/* Termination 'triggered' */
228 	zassert_equal(conn.llcp_terminate.reason_final, BT_HCI_ERR_LMP_PDU_NOT_ALLOWED,
229 		      "Terminate reason %d", conn.llcp_terminate.reason_final);
230 
231 	/* Clear termination flag for subsequent test cycle */
232 	conn.llcp_terminate.reason_final = 0;
233 
234 	/* There should not be a host notifications */
235 	ut_rx_q_is_empty();
236 
237 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
238 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
239 
240 	/* Initiate another SCA Procedure */
241 	err = ull_cp_req_peer_sca(&conn);
242 	zassert_equal(err, BT_HCI_ERR_SUCCESS);
243 
244 	/* Prepare */
245 	event_prepare(&conn);
246 
247 	/* Tx Queue should have one LL Control PDU */
248 	lt_rx(LL_CLOCK_ACCURACY_REQ, &conn, &tx, &local_sca_req);
249 	lt_rx_q_is_empty(&conn);
250 
251 	/* Rx */
252 	lt_tx(LL_REJECT_IND, &conn, &reject_ind);
253 
254 	/* Done */
255 	event_done(&conn);
256 
257 	/* Release tx node */
258 	ull_cp_release_tx(&conn, tx);
259 
260 	/* Termination 'triggered' */
261 	zassert_equal(conn.llcp_terminate.reason_final, BT_HCI_ERR_LMP_PDU_NOT_ALLOWED,
262 		      "Terminate reason %d", conn.llcp_terminate.reason_final);
263 
264 	/* There should not be a host notifications */
265 	ut_rx_q_is_empty();
266 
267 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
268 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
269 
270 }
271 
272 /* +-----+                     +-------+                   +-----+
273  * | UT  |                     | LL_A  |                   | LT  |
274  * +-----+                     +-------+                   +-----+
275  *    |                            |                          |
276  *    | Start                      |                          |
277  *    | SCA Update Proc.           |                          |
278  *    |--------------------------->|                          |
279  *    |                            |                          |
280  *    |                            | LL_CLOCK_ACCURACY_REQ    |
281  *    |                            |------------------------->|
282  *    |                            |                          |
283  *    |                            | LL_<INVALID>_RSP         |
284  *    |                            |<-------------------------|
285  *    |                            |                          |
286  *       ~~~~~~~~~~~~~~~~~ TERMINATE CONNECTION ~~~~~~~~~~~~~~
287  *    |                            |                          |
288  */
ZTEST(sca_periph,test_sca_peripheral_loc_invalid_rsp)289 ZTEST(sca_periph, test_sca_peripheral_loc_invalid_rsp)
290 {
291 	uint8_t err;
292 	struct node_tx *tx;
293 
294 	struct pdu_data_llctrl_reject_ind reject_ind = {
295 		.error_code = BT_HCI_ERR_LL_PROC_COLLISION
296 	};
297 	struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = {
298 		.reject_opcode = PDU_DATA_LLCTRL_TYPE_CLOCK_ACCURACY_REQ,
299 		.error_code = BT_HCI_ERR_LL_PROC_COLLISION
300 	};
301 	struct pdu_data_llctrl_clock_accuracy_req local_sca_req = {};
302 
303 	/* Role */
304 	test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
305 
306 	/* Connect */
307 	ull_cp_state_set(&conn, ULL_CP_CONNECTED);
308 
309 	/* Initiate an SCA Procedure */
310 	err = ull_cp_req_peer_sca(&conn);
311 	zassert_equal(err, BT_HCI_ERR_SUCCESS);
312 
313 	/* Prepare */
314 	event_prepare(&conn);
315 
316 	/* Tx Queue should have one LL Control PDU */
317 	lt_rx(LL_CLOCK_ACCURACY_REQ, &conn, &tx, &local_sca_req);
318 	lt_rx_q_is_empty(&conn);
319 
320 	/* Rx */
321 	lt_tx(LL_REJECT_EXT_IND, &conn, &reject_ext_ind);
322 
323 	/* Done */
324 	event_done(&conn);
325 
326 	/* Release tx node */
327 	ull_cp_release_tx(&conn, tx);
328 
329 	/* Termination 'triggered' */
330 	zassert_equal(conn.llcp_terminate.reason_final, BT_HCI_ERR_LMP_PDU_NOT_ALLOWED,
331 		      "Terminate reason %d", conn.llcp_terminate.reason_final);
332 
333 	/* Clear termination flag for subsequent test cycle */
334 	conn.llcp_terminate.reason_final = 0;
335 
336 	/* There should not be a host notifications */
337 	ut_rx_q_is_empty();
338 
339 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
340 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
341 
342 	/* Initiate another SCA Procedure */
343 	err = ull_cp_req_peer_sca(&conn);
344 	zassert_equal(err, BT_HCI_ERR_SUCCESS);
345 
346 	/* Prepare */
347 	event_prepare(&conn);
348 
349 	/* Tx Queue should have one LL Control PDU */
350 	lt_rx(LL_CLOCK_ACCURACY_REQ, &conn, &tx, &local_sca_req);
351 	lt_rx_q_is_empty(&conn);
352 
353 	/* Rx */
354 	lt_tx(LL_REJECT_IND, &conn, &reject_ind);
355 
356 	/* Done */
357 	event_done(&conn);
358 
359 	/* Release tx node */
360 	ull_cp_release_tx(&conn, tx);
361 
362 	/* Termination 'triggered' */
363 	zassert_equal(conn.llcp_terminate.reason_final, BT_HCI_ERR_LMP_PDU_NOT_ALLOWED,
364 		      "Terminate reason %d", conn.llcp_terminate.reason_final);
365 
366 	/* There should not be a host notifications */
367 	ut_rx_q_is_empty();
368 
369 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
370 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
371 
372 }
373 
374 /* +-----+                     +-------+            +-----+
375  * | UT  |                     | LL_A  |            | LT  |
376  * +-----+                     +-------+            +-----+
377  *    |                            |                          |
378  *    | Start                      |                          |
379  *    | SCA Update Proc.           |                          |
380  *    |--------------------------->|                          |
381  *    |                            |                          |
382  *    |                            | LL_CLOCK_ACCURACY_REQ    |
383  *    |                            |------------------------->|
384  *    |                            |                          |
385  *    |                            |    LL_CLOCK_ACCURACY_RSP |
386  *    |                            |<-------------------------|
387  *    |                            |                          |
388  *    |                            |                          |
389  */
ZTEST(sca_periph,test_ping_periph_loc)390 ZTEST(sca_periph, test_ping_periph_loc)
391 {
392 	uint8_t err;
393 	struct node_tx *tx;
394 	struct node_rx_pdu *ntf;
395 	struct node_rx_sca scau = { .status = BT_HCI_ERR_SUCCESS, .sca = 2 };
396 	struct pdu_data_llctrl_clock_accuracy_req local_sca_req = { };
397 	struct pdu_data_llctrl_clock_accuracy_rsp remote_sca_rsp = { .sca = 2 };
398 
399 	/* Role */
400 	test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
401 
402 	/* Connect */
403 	ull_cp_state_set(&conn, ULL_CP_CONNECTED);
404 
405 	/* Initiate an SCA Procedure */
406 	err = ull_cp_req_peer_sca(&conn);
407 	zassert_equal(err, BT_HCI_ERR_SUCCESS);
408 
409 	/* Prepare */
410 	event_prepare(&conn);
411 
412 	/* Tx Queue should have one LL Control PDU */
413 	lt_rx(LL_CLOCK_ACCURACY_REQ, &conn, &tx, &local_sca_req);
414 	lt_rx_q_is_empty(&conn);
415 
416 	/* Rx */
417 	lt_tx(LL_CLOCK_ACCURACY_RSP, &conn, &remote_sca_rsp);
418 
419 	/* Done */
420 	event_done(&conn);
421 
422 	/* Release tx node */
423 	ull_cp_release_tx(&conn, tx);
424 
425 	/* Termination not 'triggered' */
426 	zassert_equal(conn.llcp_terminate.reason_final, 0,
427 		      "Terminate reason %d", conn.llcp_terminate.reason_final);
428 
429 	/* There should be one notification due to Peer SCA Request */
430 	ut_rx_node(NODE_PEER_SCA_UPDATE, &ntf, &scau);
431 	ut_rx_q_is_empty();
432 
433 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
434 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
435 }
436 
437 /* +-----+                     +-------+                   +-----+
438  * | UT  |                     | LL_A  |                   | LT  |
439  * +-----+                     +-------+                   +-----+
440  *    |                            |                          |
441  *    |                            | LL_CLOCK_ACCURACY_REQ    |
442  *    |                            |------------------------->|
443  *    |                            |                          |
444  *    |                            |    LL_CLOCK_ACCURACY_RSP |
445  *    |                            |<-------------------------|
446  *    |                            |                          |
447  *    |                            |                          |
448  */
ZTEST(sca_central,test_ping_central_rem)449 ZTEST(sca_central, test_ping_central_rem)
450 {
451 	struct node_tx *tx;
452 
453 	struct pdu_data_llctrl_clock_accuracy_req local_sca_req = { };
454 
455 	struct pdu_data_llctrl_clock_accuracy_rsp remote_sca_rsp = { };
456 
457 	/* Role */
458 	test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
459 
460 	/* Connect */
461 	ull_cp_state_set(&conn, ULL_CP_CONNECTED);
462 
463 	/* Prepare */
464 	event_prepare(&conn);
465 
466 	/* Tx */
467 	lt_tx(LL_CLOCK_ACCURACY_REQ, &conn, &local_sca_req);
468 
469 	/* Done */
470 	event_done(&conn);
471 
472 	/* Prepare */
473 	event_prepare(&conn);
474 
475 	/* Tx Queue should have one LL Control PDU */
476 	lt_rx(LL_CLOCK_ACCURACY_RSP, &conn, &tx, &remote_sca_rsp);
477 	lt_rx_q_is_empty(&conn);
478 
479 	event_tx_ack(&conn, tx);
480 
481 	/* Done */
482 	event_done(&conn);
483 
484 	/* Release tx node */
485 	ull_cp_release_tx(&conn, tx);
486 
487 	/* There should not be a host notifications */
488 	ut_rx_q_is_empty();
489 
490 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
491 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
492 }
493 
494 /* +-----+                     +-------+                   +-----+
495  * | UT  |                     | LL_A  |                   | LT  |
496  * +-----+                     +-------+                   +-----+
497  *    |                            |                          |
498  *    |                            | LL_CLOCK_ACCURACY_REQ    |
499  *    |                            |------------------------->|
500  *    |                            |                          |
501  *    |                            |    LL_CLOCK_ACCURACY_RSP |
502  *    |                            |<-------------------------|
503  *    |                            |                          |
504  *    |                            |                          |
505  */
ZTEST(sca_periph,test_ping_periph_rem)506 ZTEST(sca_periph, test_ping_periph_rem)
507 {
508 	struct node_tx *tx;
509 
510 	struct pdu_data_llctrl_clock_accuracy_req local_sca_req = { };
511 
512 	struct pdu_data_llctrl_clock_accuracy_rsp remote_sca_rsp = { };
513 
514 	/* Role */
515 	test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
516 
517 	/* Connect */
518 	ull_cp_state_set(&conn, ULL_CP_CONNECTED);
519 
520 	/* Prepare */
521 	event_prepare(&conn);
522 
523 	/* Tx */
524 	lt_tx(LL_CLOCK_ACCURACY_REQ, &conn, &local_sca_req);
525 
526 	/* Done */
527 	event_done(&conn);
528 
529 	/* Prepare */
530 	event_prepare(&conn);
531 
532 	/* Tx Queue should have one LL Control PDU */
533 	lt_rx(LL_CLOCK_ACCURACY_RSP, &conn, &tx, &remote_sca_rsp);
534 	lt_rx_q_is_empty(&conn);
535 
536 	event_tx_ack(&conn, tx);
537 
538 	/* Done */
539 	event_done(&conn);
540 
541 	/* Release tx node */
542 	ull_cp_release_tx(&conn, tx);
543 
544 	/* There should not be a host notifications */
545 	ut_rx_q_is_empty();
546 
547 	zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
548 		      "Free CTX buffers %d", llcp_ctx_buffers_free());
549 }
550 
551 ZTEST_SUITE(sca_central, NULL, NULL, sca_setup, NULL, NULL);
552 ZTEST_SUITE(sca_periph, NULL, NULL, sca_setup, NULL, NULL);
553