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_settings.h"
26 #include "ll_feat.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
43 #include "helper_pdu.h"
44 #include "helper_util.h"
45
46 static struct ll_conn test_conn;
47
unsupported_setup(void * data)48 static void unsupported_setup(void *data)
49 {
50 test_setup(&test_conn);
51 }
52
53 #define LLCTRL_PDU_SIZE (offsetof(struct pdu_data, llctrl) + sizeof(struct pdu_data_llctrl))
54
55 /* +-----+ +-------+ +-----+
56 * | UT | | LL_A | | LT |
57 * +-----+ +-------+ +-----+
58 * | | |
59 * | | <PDU> |
60 * | |<------------------|
61 * | | |
62 * | | LL_UNKNOWN_RSP |
63 * | |------------------>|
64 * | | |
65 */
lt_tx_pdu_and_rx_unknown_rsp(enum helper_pdu_opcode opcode)66 static void lt_tx_pdu_and_rx_unknown_rsp(enum helper_pdu_opcode opcode)
67 {
68 struct node_tx *tx;
69 struct pdu_data pdu;
70 /* PDU contents does not matter when testing for invalid PDU opcodes */
71 uint8_t data[LLCTRL_PDU_SIZE] = { 0 };
72
73 /* Encode a PDU for the opcode */
74 encode_pdu(opcode, &pdu, &data);
75
76 /* Setup the LL_UNKNOWN_RSP expected for the PDU */
77 struct pdu_data_llctrl_unknown_rsp unknown_rsp = {
78 .type = pdu.llctrl.opcode
79 };
80
81 /* Connect */
82 ull_cp_state_set(&test_conn, ULL_CP_CONNECTED);
83
84 /* Prepare */
85 event_prepare(&test_conn);
86
87 /* Rx */
88 lt_tx(opcode, &test_conn, &pdu.llctrl.unknown_rsp);
89
90 /* Done */
91 event_done(&test_conn);
92
93 /* Prepare */
94 event_prepare(&test_conn);
95
96 /* Tx Queue should have one LL Control PDU */
97 lt_rx(LL_UNKNOWN_RSP, &test_conn, &tx, &unknown_rsp);
98 lt_rx_q_is_empty(&test_conn);
99
100 /* Done */
101 event_done(&test_conn);
102
103 /* Release Tx */
104 ull_cp_release_tx(&test_conn, tx);
105
106 /* There should not be a host notifications */
107 ut_rx_q_is_empty();
108
109 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
110 "Free CTX buffers %d", llcp_ctx_buffers_free());
111 }
112
lt_tx_undef_opcode_and_rx_unknown_rsp(uint8_t opcode)113 static void lt_tx_undef_opcode_and_rx_unknown_rsp(uint8_t opcode)
114 {
115 struct node_tx *tx;
116 struct pdu_data pdu;
117 /* PDU contents does not matter when testing for invalid PDU opcodes */
118 uint8_t data[LLCTRL_PDU_SIZE] = { 0 };
119
120 /* Undefined opcodes cannot be encoded, so encode a LL_UNKNOWN_RSP as
121 * a placeholder and override the opcode
122 */
123 encode_pdu(LL_UNKNOWN_RSP, &pdu, &data);
124 pdu.llctrl.opcode = opcode;
125
126 /* Setup the LL_UNKNOWN_RSP expected for the PDU */
127 struct pdu_data_llctrl_unknown_rsp unknown_rsp = {
128 .type = pdu.llctrl.opcode
129 };
130
131 /* Connect */
132 ull_cp_state_set(&test_conn, ULL_CP_CONNECTED);
133
134 /* Prepare */
135 event_prepare(&test_conn);
136
137 /* Rx */
138 lt_tx_no_encode(&pdu, &test_conn, &pdu.llctrl.unknown_rsp);
139
140 /* Done */
141 event_done(&test_conn);
142
143 /* Prepare */
144 event_prepare(&test_conn);
145
146 /* Tx Queue should have one LL Control PDU */
147 lt_rx(LL_UNKNOWN_RSP, &test_conn, &tx, &unknown_rsp);
148 lt_rx_q_is_empty(&test_conn);
149
150 /* Done */
151 event_done(&test_conn);
152
153 /* Release Tx */
154 ull_cp_release_tx(&test_conn, tx);
155
156 /* There should not be a host notifications */
157 ut_rx_q_is_empty();
158
159 zassert_equal(llcp_ctx_buffers_free(), test_ctx_buffers_cnt(),
160 "Free CTX buffers %d", llcp_ctx_buffers_free());
161 }
162
ZTEST(invalid,test_invalid_per_rem)163 ZTEST(invalid, test_invalid_per_rem)
164 {
165 /* Role */
166 test_set_role(&test_conn, BT_HCI_ROLE_PERIPHERAL);
167
168 /* Test opcodes that cannot initiate a remote procedure */
169 lt_tx_pdu_and_rx_unknown_rsp(LL_ENC_RSP);
170 lt_tx_pdu_and_rx_unknown_rsp(LL_START_ENC_REQ);
171 lt_tx_pdu_and_rx_unknown_rsp(LL_START_ENC_RSP);
172 lt_tx_pdu_and_rx_unknown_rsp(LL_UNKNOWN_RSP);
173 lt_tx_pdu_and_rx_unknown_rsp(LL_FEATURE_RSP);
174 lt_tx_pdu_and_rx_unknown_rsp(LL_PAUSE_ENC_RSP);
175 lt_tx_pdu_and_rx_unknown_rsp(LL_REJECT_IND);
176 lt_tx_pdu_and_rx_unknown_rsp(LL_CONNECTION_PARAM_RSP);
177 lt_tx_pdu_and_rx_unknown_rsp(LL_REJECT_EXT_IND);
178 lt_tx_pdu_and_rx_unknown_rsp(LL_LE_PING_RSP);
179 lt_tx_pdu_and_rx_unknown_rsp(LL_LENGTH_RSP);
180 lt_tx_pdu_and_rx_unknown_rsp(LL_PHY_RSP);
181 lt_tx_pdu_and_rx_unknown_rsp(LL_PHY_UPDATE_IND);
182 lt_tx_pdu_and_rx_unknown_rsp(LL_CTE_RSP);
183
184 /* Test opcodes that can initiate a remote procedure but use the wrong
185 * role
186 */
187 lt_tx_pdu_and_rx_unknown_rsp(LL_PERIPH_FEAT_XCHG);
188 lt_tx_pdu_and_rx_unknown_rsp(LL_MIN_USED_CHANS_IND);
189 }
190
ZTEST(invalid,test_invalid_cen_rem)191 ZTEST(invalid, test_invalid_cen_rem)
192 {
193 /* Role */
194 test_set_role(&test_conn, BT_HCI_ROLE_CENTRAL);
195
196 /* Test opcodes that cannot initiate a remote procedure */
197 lt_tx_pdu_and_rx_unknown_rsp(LL_ENC_RSP);
198 lt_tx_pdu_and_rx_unknown_rsp(LL_START_ENC_REQ);
199 lt_tx_pdu_and_rx_unknown_rsp(LL_START_ENC_RSP);
200 lt_tx_pdu_and_rx_unknown_rsp(LL_UNKNOWN_RSP);
201 lt_tx_pdu_and_rx_unknown_rsp(LL_FEATURE_RSP);
202 lt_tx_pdu_and_rx_unknown_rsp(LL_PAUSE_ENC_RSP);
203 lt_tx_pdu_and_rx_unknown_rsp(LL_REJECT_IND);
204 lt_tx_pdu_and_rx_unknown_rsp(LL_CONNECTION_PARAM_RSP);
205 lt_tx_pdu_and_rx_unknown_rsp(LL_REJECT_EXT_IND);
206 lt_tx_pdu_and_rx_unknown_rsp(LL_LE_PING_RSP);
207 lt_tx_pdu_and_rx_unknown_rsp(LL_LENGTH_RSP);
208 lt_tx_pdu_and_rx_unknown_rsp(LL_PHY_RSP);
209 lt_tx_pdu_and_rx_unknown_rsp(LL_PHY_UPDATE_IND);
210 lt_tx_pdu_and_rx_unknown_rsp(LL_CTE_RSP);
211
212 /* Test opcodes that can initiate a remote procedure but use the wrong
213 * role
214 */
215 lt_tx_pdu_and_rx_unknown_rsp(LL_CONNECTION_UPDATE_IND);
216 lt_tx_pdu_and_rx_unknown_rsp(LL_CHAN_MAP_UPDATE_IND);
217 lt_tx_pdu_and_rx_unknown_rsp(LL_ENC_REQ);
218 lt_tx_pdu_and_rx_unknown_rsp(LL_FEATURE_REQ);
219 lt_tx_pdu_and_rx_unknown_rsp(LL_PAUSE_ENC_REQ);
220 }
221
ZTEST(undefined,test_undefined_per_rem)222 ZTEST(undefined, test_undefined_per_rem)
223 {
224 /* Role */
225 test_set_role(&test_conn, BT_HCI_ROLE_PERIPHERAL);
226
227 /* Test undefined opcodes that cannot initiate a remote procedure */
228
229 /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 6, Part B, Table 2.18:
230 * LL Control PDU opcodes
231 */
232 for (uint16_t opcode = 0x30; opcode < 0x100; opcode++) {
233 lt_tx_undef_opcode_and_rx_unknown_rsp(opcode);
234 }
235 }
236
ZTEST(undefined,test_undefined_cen_rem)237 ZTEST(undefined, test_undefined_cen_rem)
238 {
239 /* Role */
240 test_set_role(&test_conn, BT_HCI_ROLE_CENTRAL);
241
242 /* Test undefined opcodes that cannot initiate a remote procedure */
243
244 /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 6, Part B, Table 2.18:
245 * LL Control PDU opcodes
246 */
247 for (uint16_t opcode = 0x30; opcode < 0x100; opcode++) {
248 lt_tx_undef_opcode_and_rx_unknown_rsp(opcode);
249 }
250 }
251
252 #if !defined(CONFIG_BT_CTLR_LE_ENC)
ZTEST(unsupported,test_no_enc_per_rem)253 ZTEST(unsupported, test_no_enc_per_rem)
254 {
255 /* Role */
256 test_set_role(&test_conn, BT_HCI_ROLE_PERIPHERAL);
257
258 lt_tx_pdu_and_rx_unknown_rsp(LL_ENC_REQ);
259 }
260 #endif /* CONFIG_BT_CTLR_LE_ENC */
261
ZTEST(unsupported,test_no_enc_cen_rem)262 ZTEST(unsupported, test_no_enc_cen_rem)
263 {
264 /* Role */
265 test_set_role(&test_conn, BT_HCI_ROLE_CENTRAL);
266
267 lt_tx_pdu_and_rx_unknown_rsp(LL_ENC_REQ);
268 }
269
270 #if !defined(CONFIG_BT_CTLR_PER_INIT_FEAT_XCHG)
ZTEST(unsupported,test_no_per_feat_exch_per_rem)271 ZTEST(unsupported, test_no_per_feat_exch_per_rem)
272 {
273 /* Role */
274 test_set_role(&test_conn, BT_HCI_ROLE_PERIPHERAL);
275
276 lt_tx_pdu_and_rx_unknown_rsp(LL_PERIPH_FEAT_XCHG);
277 }
278
ZTEST(unsupported,test_no_per_feat_exch_cen_rem)279 ZTEST(unsupported, test_no_per_feat_exch_cen_rem)
280 {
281 /* Role */
282 test_set_role(&test_conn, BT_HCI_ROLE_CENTRAL);
283
284 lt_tx_pdu_and_rx_unknown_rsp(LL_PERIPH_FEAT_XCHG);
285 }
286 #endif /* CONFIG_BT_CTLR_PER_INIT_FEAT_XCHG */
287
288
289 #if !defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
ZTEST(unsupported,test_no_cpr_per_rem)290 ZTEST(unsupported, test_no_cpr_per_rem)
291 {
292 /* Role */
293 test_set_role(&test_conn, BT_HCI_ROLE_PERIPHERAL);
294
295 lt_tx_pdu_and_rx_unknown_rsp(LL_CONNECTION_PARAM_REQ);
296 }
297
ZTEST(unsupported,test_no_cpr_cen_rem)298 ZTEST(unsupported, test_no_cpr_cen_rem)
299 {
300 /* Role */
301 test_set_role(&test_conn, BT_HCI_ROLE_CENTRAL);
302
303 lt_tx_pdu_and_rx_unknown_rsp(LL_CONNECTION_PARAM_REQ);
304 }
305 #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
306
307
308 #if !defined(CONFIG_BT_CTLR_PHY)
ZTEST(unsupported,test_no_phy_per_rem)309 ZTEST(unsupported, test_no_phy_per_rem)
310 {
311 /* Role */
312 test_set_role(&test_conn, BT_HCI_ROLE_PERIPHERAL);
313
314 lt_tx_pdu_and_rx_unknown_rsp(LL_PHY_REQ);
315 }
316
ZTEST(unsupported,test_no_phy_cen_rem)317 ZTEST(unsupported, test_no_phy_cen_rem)
318 {
319 /* Role */
320 test_set_role(&test_conn, BT_HCI_ROLE_CENTRAL);
321
322 lt_tx_pdu_and_rx_unknown_rsp(LL_PHY_REQ);
323 }
324 #endif /* CONFIG_BT_CTLR_PHY */
325
326
327 ZTEST_SUITE(invalid, NULL, NULL, unsupported_setup, NULL, NULL);
328 ZTEST_SUITE(undefined, NULL, NULL, unsupported_setup, NULL, NULL);
329 ZTEST_SUITE(unsupported, NULL, NULL, unsupported_setup, NULL, NULL);
330