1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/types.h>
8 #include <zephyr/sys/byteorder.h>
9 #include <zephyr/ztest.h>
10
11 #define ULL_LLCP_UNITTEST
12
13 #include <zephyr/bluetooth/hci.h>
14 #include <zephyr/sys/byteorder.h>
15 #include <zephyr/sys/slist.h>
16 #include <zephyr/sys/util.h>
17 #include "hal/ccm.h"
18
19 #include "util/util.h"
20 #include "util/mem.h"
21 #include "util/memq.h"
22 #include "util/dbuf.h"
23
24 #include "pdu_df.h"
25 #include "lll/pdu_vendor.h"
26 #include "pdu.h"
27 #include "ll.h"
28 #include "ll_settings.h"
29
30 #include "lll.h"
31 #include "lll/lll_df_types.h"
32 #include "lll_conn.h"
33 #include "lll_conn_iso.h"
34
35 #include "ull_tx_queue.h"
36
37 #include "isoal.h"
38 #include "ull_iso_types.h"
39 #include "ull_conn_iso_types.h"
40 #include "ull_conn_types.h"
41
42 #include "ull_internal.h"
43 #include "ull_llcp.h"
44 #include "ull_llcp_internal.h"
45 #include "ull_conn_internal.h"
46
47 #include "ll_feat.h"
48
49 #include "helper_pdu.h"
50 #include "helper_util.h"
51 #include "helper_features.h"
52
53 static struct ll_conn conn;
54
fex_setup(void * data)55 static void fex_setup(void *data)
56 {
57 test_setup(&conn);
58 }
59
60 /*
61 * +-----+ +-------+ +-----+
62 * | UT | | LL_A | | LT |
63 * +-----+ +-------+ +-----+
64 * | | |
65 * | Start | |
66 * | Feature Exchange Proc. | |
67 * |--------------------------->| |
68 * | | |
69 * | | LL_FEATURE_REQ |
70 * | |------------------>|
71 * | | |
72 * | | LL_FEATURE_RSP |
73 * | |<------------------|
74 * | | |
75 * | Feature Exchange Proc. | |
76 * | Complete | |
77 * |<---------------------------| |
78 * | | |
79 */
ZTEST(fex_central,test_feat_exchange_central_loc)80 ZTEST(fex_central, test_feat_exchange_central_loc)
81 {
82 uint64_t err;
83 uint64_t set_featureset[] = { DEFAULT_FEATURE, DEFAULT_FEATURE };
84 uint64_t rsp_featureset[] = {
85 (LL_FEAT_BIT_MASK_VALID & FEAT_FILTER_OCTET0) | DEFAULT_FEATURE, 0x0
86 };
87 uint64_t exp_rsp_featureset[] = { ((LL_FEAT_BIT_MASK_VALID & FEAT_FILTER_OCTET0) |
88 DEFAULT_FEATURE) &
89 LL_FEAT_BIT_MASK_VALID,
90 0x0 };
91 int feat_to_test = ARRAY_SIZE(set_featureset);
92
93 struct node_tx *tx;
94 struct node_rx_pdu *ntf;
95
96 struct pdu_data_llctrl_feature_req local_feature_req;
97 struct pdu_data_llctrl_feature_rsp remote_feature_rsp;
98 struct pdu_data_llctrl_feature_rsp exp_remote_feature_rsp;
99 int feat_counter;
100
101 for (feat_counter = 0; feat_counter < feat_to_test; feat_counter++) {
102 sys_put_le64(set_featureset[feat_counter], local_feature_req.features);
103
104 sys_put_le64(rsp_featureset[feat_counter], remote_feature_rsp.features);
105
106 sys_put_le64(exp_rsp_featureset[feat_counter], exp_remote_feature_rsp.features);
107
108 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
109 /* Connect */
110 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
111
112 /* Initiate a Feature Exchange Procedure */
113 err = ull_cp_feature_exchange(&conn, 1U);
114 zassert_equal(err, BT_HCI_ERR_SUCCESS);
115
116 event_prepare(&conn);
117 /* Tx Queue should have one LL Control PDU */
118 lt_rx(LL_FEATURE_REQ, &conn, &tx, &local_feature_req);
119 lt_rx_q_is_empty(&conn);
120
121 /* Rx */
122 lt_tx(LL_FEATURE_RSP, &conn, &remote_feature_rsp);
123
124 event_done(&conn);
125 /* There should be one host notification */
126
127 ut_rx_pdu(LL_FEATURE_RSP, &ntf, &exp_remote_feature_rsp);
128
129 ut_rx_q_is_empty();
130
131 ull_cp_release_tx(&conn, tx);
132 release_ntf(ntf);
133 }
134
135 /* Test that host enabled feature makes it into feature exchange */
136 ll_set_host_feature(BT_LE_FEAT_BIT_ISO_CHANNELS, 1);
137
138 /* Add host feature bit to expected features bit mask */
139 set_featureset[0] |= BIT64(BT_LE_FEAT_BIT_ISO_CHANNELS);
140
141 sys_put_le64(set_featureset[0], local_feature_req.features);
142 /* Initiate a Feature Exchange Procedure */
143 err = ull_cp_feature_exchange(&conn, 1U);
144 zassert_equal(err, BT_HCI_ERR_SUCCESS);
145
146 event_prepare(&conn);
147 /* Tx Queue should have one LL Control PDU */
148 lt_rx(LL_FEATURE_REQ, &conn, &tx, &local_feature_req);
149 lt_rx_q_is_empty(&conn);
150
151 /* Rx */
152 lt_tx(LL_FEATURE_RSP, &conn, &remote_feature_rsp);
153
154 event_done(&conn);
155 /* There should be one host notification */
156
157 ut_rx_pdu(LL_FEATURE_RSP, &ntf, &exp_remote_feature_rsp);
158
159 ut_rx_q_is_empty();
160
161 ull_cp_release_tx(&conn, tx);
162 release_ntf(ntf);
163
164 /* Remove host feature bit again */
165 ll_set_host_feature(BT_LE_FEAT_BIT_ISO_CHANNELS, 0);
166
167 zassert_equal(conn.lll.event_counter, feat_to_test + 1, "Wrong event-count %d\n",
168 conn.lll.event_counter);
169 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
170 "Free CTX buffers %d", llcp_ctx_buffers_free());
171 }
172
173 /*
174 * +-----+ +-------+ +-----+
175 * | UT | | LL_A | | LT |
176 * +-----+ +-------+ +-----+
177 * | | |
178 * | Start | |
179 * | Feature Exchange Proc. | |
180 * |--------------------------->| |
181 * | | |
182 * | | LL_FEATURE_REQ |
183 * | |------------------>|
184 * | | |
185 * | | LL_<INVALID>_RSP |
186 * | |<------------------|
187 * | | |
188 * ~~~~~~~~~~~~~~~~ TERMINATE CONNECTION ~~~~~~~~~~~~~~
189 * | | |
190 */
ZTEST(fex_central,test_feat_exchange_central_loc_invalid_rsp)191 ZTEST(fex_central, test_feat_exchange_central_loc_invalid_rsp)
192 {
193 uint64_t err;
194 struct pdu_data_llctrl_feature_req local_feature_req;
195 struct pdu_data_llctrl_reject_ind reject_ind = {
196 .error_code = BT_HCI_ERR_LL_PROC_COLLISION
197 };
198 struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = {
199 .reject_opcode = PDU_DATA_LLCTRL_TYPE_FEATURE_REQ,
200 .error_code = BT_HCI_ERR_LL_PROC_COLLISION
201 };
202 struct node_tx *tx;
203
204
205 sys_put_le64(DEFAULT_FEATURE, local_feature_req.features);
206
207 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
208 /* Connect */
209 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
210
211 /* Initiate a Feature Exchange Procedure */
212 err = ull_cp_feature_exchange(&conn, 1U);
213 zassert_equal(err, BT_HCI_ERR_SUCCESS);
214
215 event_prepare(&conn);
216 /* Tx Queue should have one LL Control PDU */
217 lt_rx(LL_FEATURE_REQ, &conn, &tx, &local_feature_req);
218 lt_rx_q_is_empty(&conn);
219
220 /* Rx */
221 lt_tx(LL_REJECT_IND, &conn, &reject_ind);
222
223 event_done(&conn);
224
225 /* Release tx node */
226 ull_cp_release_tx(&conn, tx);
227
228 /* Termination 'triggered' */
229 zassert_equal(conn.llcp_terminate.reason_final, BT_HCI_ERR_LMP_PDU_NOT_ALLOWED,
230 "Terminate reason %d", conn.llcp_terminate.reason_final);
231
232 /* Clear termination flag for subsequent test cycle */
233 conn.llcp_terminate.reason_final = 0;
234
235 /* There should not be a host notifications */
236 ut_rx_q_is_empty();
237
238 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
239 "Free CTX buffers %d", llcp_ctx_buffers_free());
240
241 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
242 /* Connect */
243 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
244
245 /* Initiate another Feature Exchange Procedure */
246 err = ull_cp_feature_exchange(&conn, 1U);
247 zassert_equal(err, BT_HCI_ERR_SUCCESS);
248
249 event_prepare(&conn);
250 /* Tx Queue should have one LL Control PDU */
251 lt_rx(LL_FEATURE_REQ, &conn, &tx, &local_feature_req);
252 lt_rx_q_is_empty(&conn);
253
254 /* Rx */
255 lt_tx(LL_REJECT_EXT_IND, &conn, &reject_ext_ind);
256
257 event_done(&conn);
258
259 /* Release tx node */
260 ull_cp_release_tx(&conn, tx);
261
262 /* Termination 'triggered' */
263 zassert_equal(conn.llcp_terminate.reason_final, BT_HCI_ERR_LMP_PDU_NOT_ALLOWED,
264 "Terminate reason %d", conn.llcp_terminate.reason_final);
265
266 /* There should not be a host notifications */
267 ut_rx_q_is_empty();
268
269 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
270 "Free CTX buffers %d", llcp_ctx_buffers_free());
271 }
272
ZTEST(fex_central,test_feat_exchange_central_loc_2)273 ZTEST(fex_central, test_feat_exchange_central_loc_2)
274 {
275 uint8_t err;
276
277 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
278 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
279
280 err = ull_cp_feature_exchange(&conn, 1U);
281 for (int i = 0U; i < CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM; i++) {
282 zassert_equal(err, BT_HCI_ERR_SUCCESS);
283 err = ull_cp_feature_exchange(&conn, 1U);
284 }
285
286 zassert_not_equal(err, BT_HCI_ERR_SUCCESS, NULL);
287 zassert_equal(llcp_ctx_buffers_free(),
288 test_ctx_buffers_cnt() - CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM,
289 "Free CTX buffers %d", llcp_ctx_buffers_free());
290 }
291
292 /*
293 * +-----+ +-------+ +-----+
294 * | UT | | LL_A | | LT |
295 * +-----+ +-------+ +-----+
296 * | | |
297 * | | LL_PERIPH_FEAT_XCHG |
298 * | |<------------------------|
299 * | | |
300 * | | LL_FEATURE_RSP |
301 * | |------------------------>|
302 * | | |
303 */
304 #define CENTRAL_NR_OF_EVENTS 2
ZTEST(fex_central,test_feat_exchange_central_rem)305 ZTEST(fex_central, test_feat_exchange_central_rem)
306 {
307 uint64_t set_featureset[] = {
308 DEFAULT_FEATURE,
309 LL_FEAT_BIT_MASK_VALID,
310 EXPECTED_FEAT_EXCH_VALID,
311 0xFFFFFFFFFFFFFFFF,
312 0x0 };
313 uint64_t exp_featureset[] = { DEFAULT_FEATURE & COMMON_FEAT_OCTET0(LL_FEAT_BIT_MASK_VALID),
314 DEFAULT_FEATURE & COMMON_FEAT_OCTET0(LL_FEAT_BIT_MASK_VALID),
315 DEFAULT_FEATURE &
316 COMMON_FEAT_OCTET0(EXPECTED_FEAT_EXCH_VALID),
317 DEFAULT_FEATURE & COMMON_FEAT_OCTET0(LL_FEAT_BIT_MASK_VALID),
318 DEFAULT_FEATURE & 0xFFFFFFFFFFFFFF00 };
319 int feat_to_test = ARRAY_SIZE(set_featureset);
320 struct node_tx *tx;
321
322 struct pdu_data_llctrl_feature_req remote_feature_req;
323 struct pdu_data_llctrl_feature_rsp local_feature_rsp;
324
325 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
326 /* Connect */
327 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
328
329 for (int feat_count = 0; feat_count < feat_to_test; feat_count++) {
330 sys_put_le64(set_featureset[feat_count], remote_feature_req.features);
331 sys_put_le64(exp_featureset[feat_count], local_feature_rsp.features);
332
333 event_prepare(&conn);
334
335 lt_tx(LL_PERIPH_FEAT_XCHG, &conn, &remote_feature_req);
336
337 event_done(&conn);
338
339 event_prepare(&conn);
340
341 lt_rx(LL_FEATURE_RSP, &conn, &tx, &local_feature_rsp);
342 lt_rx_q_is_empty(&conn);
343
344 event_done(&conn);
345
346 ut_rx_q_is_empty();
347
348 ull_cp_release_tx(&conn, tx);
349 }
350 zassert_equal(conn.lll.event_counter, CENTRAL_NR_OF_EVENTS * (feat_to_test),
351 "Wrong event-count %d\n", conn.lll.event_counter);
352 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
353 "Free CTX buffers %d", llcp_ctx_buffers_free());
354 }
355
356 #undef CENTRAL_NR_OF_EVENTS
357 #define CENTRAL_NR_OF_EVENTS 3
ZTEST(fex_central,test_feat_exchange_central_rem_2)358 ZTEST(fex_central, test_feat_exchange_central_rem_2)
359 {
360 /*
361 * we could combine some of the following,
362 * but in reality we should add some more
363 * test cases
364 */
365 uint64_t set_featureset[] = {
366 DEFAULT_FEATURE,
367 LL_FEAT_BIT_MASK_VALID,
368 EXPECTED_FEAT_EXCH_VALID,
369 0xFFFFFFFFFFFFFFFF,
370 0x0 };
371 uint64_t exp_featureset[] = { DEFAULT_FEATURE & COMMON_FEAT_OCTET0(LL_FEAT_BIT_MASK_VALID),
372 DEFAULT_FEATURE & COMMON_FEAT_OCTET0(LL_FEAT_BIT_MASK_VALID),
373 DEFAULT_FEATURE &
374 COMMON_FEAT_OCTET0(EXPECTED_FEAT_EXCH_VALID),
375 DEFAULT_FEATURE & COMMON_FEAT_OCTET0(LL_FEAT_BIT_MASK_VALID),
376 DEFAULT_FEATURE & 0xFFFFFFFFFFFFFF00 };
377 uint64_t ut_featureset[] = {
378 DEFAULT_FEATURE,
379 DEFAULT_FEATURE,
380 DEFAULT_FEATURE,
381 DEFAULT_FEATURE,
382 DEFAULT_FEATURE };
383 uint64_t ut_exp_featureset[] = {
384 DEFAULT_FEATURE & LL_FEAT_BIT_MASK_VALID, DEFAULT_FEATURE & LL_FEAT_BIT_MASK_VALID,
385 DEFAULT_FEATURE & LL_FEAT_BIT_MASK_VALID, DEFAULT_FEATURE & LL_FEAT_BIT_MASK_VALID,
386 (DEFAULT_FEATURE & LL_FEAT_BIT_MASK_VALID) & 0xFFFFFFFFFFFFFF00
387 };
388
389 int feat_to_test = ARRAY_SIZE(set_featureset);
390 uint64_t err;
391 struct node_tx *tx;
392 struct node_rx_pdu *ntf;
393
394 struct pdu_data_llctrl_feature_req remote_feature_req;
395 struct pdu_data_llctrl_feature_rsp local_feature_rsp;
396 struct pdu_data_llctrl_feature_req ut_feature_req;
397 struct pdu_data_llctrl_feature_req ut_feature_rsp;
398
399 test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
400 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
401
402 for (int feat_count = 0; feat_count < feat_to_test; feat_count++) {
403 sys_put_le64(set_featureset[feat_count], remote_feature_req.features);
404 sys_put_le64(exp_featureset[feat_count], local_feature_rsp.features);
405 sys_put_le64(ut_featureset[feat_count], ut_feature_req.features);
406 sys_put_le64(ut_exp_featureset[feat_count], ut_feature_rsp.features);
407
408 err = ull_cp_feature_exchange(&conn, 1U);
409 zassert_equal(err, BT_HCI_ERR_SUCCESS);
410
411 event_prepare(&conn);
412 lt_tx(LL_PERIPH_FEAT_XCHG, &conn, &remote_feature_req);
413 event_done(&conn);
414
415 event_prepare(&conn);
416 lt_rx(LL_FEATURE_REQ, &conn, &tx, &ut_feature_req);
417 lt_tx(LL_FEATURE_RSP, &conn, &local_feature_rsp);
418 event_done(&conn);
419
420 ull_cp_release_tx(&conn, tx);
421
422 event_prepare(&conn);
423 lt_rx(LL_FEATURE_RSP, &conn, &tx, &local_feature_rsp);
424 event_done(&conn);
425
426 ut_rx_pdu(LL_FEATURE_RSP, &ntf, &ut_feature_rsp);
427
428 /*
429 * at the end of a loop all queues should be empty
430 */
431 ut_rx_q_is_empty();
432 lt_rx_q_is_empty(&conn);
433
434 ull_cp_release_tx(&conn, tx);
435 release_ntf(ntf);
436 }
437
438 zassert_equal(conn.lll.event_counter, CENTRAL_NR_OF_EVENTS * (feat_to_test),
439 "Wrong event-count %d\n", conn.lll.event_counter);
440 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
441 "Free CTX buffers %d", llcp_ctx_buffers_free());
442 }
443
ZTEST(fex_periph,test_peripheral_feat_exchange_periph_loc)444 ZTEST(fex_periph, test_peripheral_feat_exchange_periph_loc)
445 {
446 uint64_t err;
447 uint64_t featureset;
448 struct node_tx *tx;
449 struct node_rx_pdu *ntf;
450
451 struct pdu_data_llctrl_feature_req local_feature_req;
452 struct pdu_data_llctrl_feature_rsp remote_feature_rsp;
453
454 featureset = DEFAULT_FEATURE;
455 sys_put_le64(featureset, local_feature_req.features);
456 featureset &= LL_FEAT_BIT_MASK_VALID;
457 sys_put_le64(featureset, remote_feature_rsp.features);
458
459 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
460 /* Connect */
461 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
462
463 /* Initiate a Feature Exchange Procedure */
464 err = ull_cp_feature_exchange(&conn, 1U);
465 zassert_equal(err, BT_HCI_ERR_SUCCESS);
466
467 event_prepare(&conn);
468 /* Tx Queue should have one LL Control PDU */
469 lt_rx(LL_PERIPH_FEAT_XCHG, &conn, &tx, &local_feature_req);
470 lt_rx_q_is_empty(&conn);
471
472 /* Rx */
473 lt_tx(LL_FEATURE_RSP, &conn, &remote_feature_rsp);
474
475 event_done(&conn);
476
477 /* There should be one host notification */
478 ut_rx_pdu(LL_FEATURE_RSP, &ntf, &remote_feature_rsp);
479 ut_rx_q_is_empty();
480
481 zassert_equal(conn.lll.event_counter, 1, "Wrong event-count %d\n",
482 conn.lll.event_counter);
483 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
484 "Free CTX buffers %d", llcp_ctx_buffers_free());
485 }
486
ZTEST(fex_periph,test_feat_exchange_periph_loc_unknown_rsp)487 ZTEST(fex_periph, test_feat_exchange_periph_loc_unknown_rsp)
488 {
489 uint64_t err;
490 uint64_t featureset;
491 struct node_tx *tx;
492
493 struct pdu_data_llctrl_feature_req local_feature_req;
494
495 struct node_rx_pdu *ntf;
496 struct pdu_data_llctrl_unknown_rsp unknown_rsp = {
497 .type = PDU_DATA_LLCTRL_TYPE_PER_INIT_FEAT_XCHG
498 };
499
500 featureset = DEFAULT_FEATURE;
501 sys_put_le64(featureset, local_feature_req.features);
502
503 test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL);
504
505 ull_cp_state_set(&conn, ULL_CP_CONNECTED);
506
507 /* Initiate a Feature Exchange Procedure */
508 event_prepare(&conn);
509 err = ull_cp_feature_exchange(&conn, 1U);
510 zassert_equal(err, BT_HCI_ERR_SUCCESS);
511 event_done(&conn);
512
513 event_prepare(&conn);
514
515 /* Tx Queue should have one LL Control PDU */
516 lt_rx(LL_PERIPH_FEAT_XCHG, &conn, &tx, &local_feature_req);
517 lt_rx_q_is_empty(&conn);
518
519 /* Rx Commented out for know, handling of UNKNOWN response will come in an update */
520
521 lt_tx(LL_UNKNOWN_RSP, &conn, &unknown_rsp);
522
523 event_done(&conn);
524
525 ut_rx_pdu(LL_UNKNOWN_RSP, &ntf, &unknown_rsp);
526 ut_rx_q_is_empty();
527 zassert_equal(conn.lll.event_counter, 2, "Wrong event-count %d\n",
528 conn.lll.event_counter);
529 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
530 "Free CTX buffers %d", llcp_ctx_buffers_free());
531 }
532
533 ZTEST_SUITE(fex_central, NULL, NULL, fex_setup, NULL, NULL);
534 ZTEST_SUITE(fex_periph, NULL, NULL, fex_setup, NULL, NULL);
535