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