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