1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <stddef.h>
9 #include <zephyr/ztest.h>
10 
11 #include <zephyr/bluetooth/bluetooth.h>
12 #include <zephyr/bluetooth/hci.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <host/hci_core.h>
15 
16 #include "util/util.h"
17 #include "util/memq.h"
18 #include "util/mem.h"
19 #include "util/dbuf.h"
20 
21 #include "pdu_df.h"
22 #include "lll/pdu_vendor.h"
23 #include "pdu.h"
24 
25 #include "hal/ccm.h"
26 
27 #include "lll.h"
28 #include "lll/lll_adv_types.h"
29 #include "lll_adv.h"
30 #include "lll/lll_adv_pdu.h"
31 #include "lll/lll_adv_internal.h"
32 #include "lll_adv_sync.h"
33 #include "lll/lll_df_types.h"
34 
35 #include "ull_adv_types.h"
36 #include "ull_adv_internal.h"
37 
38 #include "ll.h"
39 #include "common.h"
40 
41 #define TEST_ADV_SET_HANDLE 0
42 #define TEST_CTE_COUNT 3
43 #define TEST_PER_ADV_CHAIN_LENGTH 5
44 #define TEST_PER_ADV_CHAIN_INCREASED_LENGTH 7
45 #define TEST_PER_ADV_CHAIN_DECREASED_LENGTH (TEST_CTE_COUNT - 1)
46 #define TEST_PER_ADV_SINGLE_PDU 1
47 #define TEST_CTE_SINGLE 1
48 /* It does not matter for purpose of this tests what is the type or length of CTE used. */
49 #define TEST_CTE_TYPE BT_HCI_LE_AOD_CTE_2US
50 
ZTEST(test_add_cte_to_per_adv_chain,test_remove_cte_from_chain_extended_to_tx_all_cte)51 ZTEST(test_add_cte_to_per_adv_chain, test_remove_cte_from_chain_extended_to_tx_all_cte)
52 {
53 	struct ll_adv_set *adv;
54 	uint8_t handle;
55 	int err;
56 
57 	/* Setup for test */
58 	adv = common_create_adv_set(TEST_ADV_SET_HANDLE);
59 	common_prepare_df_cfg(adv, TEST_CTE_COUNT);
60 	common_create_per_adv_chain(adv, TEST_PER_ADV_SINGLE_PDU);
61 
62 	handle = ull_adv_handle_get(adv);
63 
64 	ll_df_set_cl_cte_tx_enable(handle, true);
65 
66 	err = ll_df_set_cl_cte_tx_enable(handle, false);
67 	zassert_equal(err, 0,
68 		      "Unexpected error while disabling CTE for periodic advertising chain, err: %d",
69 		      err);
70 	/* Validate result */
71 	common_validate_per_adv_chain(adv, TEST_PER_ADV_SINGLE_PDU);
72 
73 	common_teardown(adv);
74 }
75 
ZTEST(test_add_cte_to_per_adv_chain,test_remove_cte_from_chain_where_each_pdu_includes_cte)76 ZTEST(test_add_cte_to_per_adv_chain, test_remove_cte_from_chain_where_each_pdu_includes_cte)
77 {
78 	struct ll_adv_set *adv;
79 	uint8_t handle;
80 	int err;
81 
82 	/* Setup for test */
83 	adv = common_create_adv_set(TEST_ADV_SET_HANDLE);
84 	/* Use the same number for PDUs in a chain as for CTE request */
85 	common_prepare_df_cfg(adv, TEST_CTE_COUNT);
86 	common_create_per_adv_chain(adv, TEST_CTE_COUNT);
87 
88 	handle = ull_adv_handle_get(adv);
89 
90 	err = ll_df_set_cl_cte_tx_enable(handle, true);
91 	zassert_equal(err, 0,
92 		      "Unexpected error while enabling CTE for periodic advertising chain, err: %d",
93 		      err);
94 
95 	err = ll_df_set_cl_cte_tx_enable(handle, false);
96 	zassert_equal(err, 0,
97 		      "Unexpected error while disabling CTE for periodic advertising chain, err: %d",
98 		      err);
99 	/* Validate result */
100 	common_validate_per_adv_chain(adv, TEST_CTE_COUNT);
101 
102 	common_teardown(adv);
103 }
104 
ZTEST(test_add_cte_to_per_adv_chain,test_remove_cte_from_chain_with_more_pdu_than_cte)105 ZTEST(test_add_cte_to_per_adv_chain, test_remove_cte_from_chain_with_more_pdu_than_cte)
106 {
107 	struct ll_adv_set *adv;
108 	uint8_t handle;
109 	int err;
110 
111 	/* Setup for test */
112 	adv = common_create_adv_set(TEST_ADV_SET_HANDLE);
113 	/* Use the same number for PDUs in a chain as for CTE request */
114 	common_prepare_df_cfg(adv, TEST_CTE_COUNT);
115 	common_create_per_adv_chain(adv, TEST_PER_ADV_CHAIN_LENGTH);
116 
117 	handle = ull_adv_handle_get(adv);
118 
119 	ll_df_set_cl_cte_tx_enable(handle, true);
120 
121 	err = ll_df_set_cl_cte_tx_enable(handle, false);
122 	zassert_equal(err, 0,
123 		      "Unexpected error while disabling CTE for periodic advertising chain, err: %d",
124 		      err);
125 	/* Validate result */
126 	common_validate_per_adv_chain(adv, TEST_PER_ADV_CHAIN_LENGTH);
127 
128 	common_teardown(adv);
129 }
130 
ZTEST(test_add_cte_to_per_adv_chain,test_remove_cte_from_single_pdu_chain)131 ZTEST(test_add_cte_to_per_adv_chain, test_remove_cte_from_single_pdu_chain)
132 {
133 	struct ll_adv_set *adv;
134 	uint8_t handle;
135 	int err;
136 
137 	/* Setup for test */
138 	adv = common_create_adv_set(TEST_ADV_SET_HANDLE);
139 	/* Use the same number for PDUs in a chain as for CTE request */
140 	common_prepare_df_cfg(adv, TEST_CTE_SINGLE);
141 	common_create_per_adv_chain(adv, TEST_PER_ADV_SINGLE_PDU);
142 
143 	handle = ull_adv_handle_get(adv);
144 
145 	ll_df_set_cl_cte_tx_enable(handle, true);
146 
147 	err = ll_df_set_cl_cte_tx_enable(handle, false);
148 	zassert_equal(err, 0,
149 		      "Unexpected error while disabling CTE for periodic advertising chain, err: %d",
150 		      err);
151 	/* Validate result */
152 	common_validate_per_adv_chain(adv, TEST_PER_ADV_SINGLE_PDU);
153 
154 	common_teardown(adv);
155 }
156 
remove_cte_from_chain_after_enqueue_to_lll(uint8_t cte_count,uint8_t init_chain_length,uint8_t expected_mem_pdu_used_count_for_enable,uint8_t expected_mem_pdu_used_count_for_disable,uint8_t expected_pdu_in_chain_after_cte_disable,uint8_t updated_chain_length,uint8_t expected_end_fifo_free_pdu_count,bool new_chain_before_cte_disable)157 static void remove_cte_from_chain_after_enqueue_to_lll(
158 	uint8_t cte_count, uint8_t init_chain_length,
159 	uint8_t expected_mem_pdu_used_count_for_enable,
160 	uint8_t expected_mem_pdu_used_count_for_disable,
161 	uint8_t expected_pdu_in_chain_after_cte_disable, uint8_t updated_chain_length,
162 	uint8_t expected_end_fifo_free_pdu_count, bool new_chain_before_cte_disable)
163 {
164 	uint32_t pdu_mem_cnt_expected, pdu_mem_cnt;
165 	struct pdu_adv *pdu_prev, *pdu_new;
166 	struct ll_adv_set *adv;
167 	uint32_t pdu_fifo_cnt;
168 	uint8_t handle;
169 	uint8_t upd;
170 	int err;
171 
172 	pdu_mem_cnt_expected = lll_adv_pdu_mem_free_count_get();
173 
174 	/* Setup for test */
175 	adv = common_create_adv_set(TEST_ADV_SET_HANDLE);
176 	/* Use smaller number of CTE for request than number of PDUs in an initial chain.
177 	 * In such situation chain should not be extended and PDUs pool should be not affected.
178 	 */
179 	common_prepare_df_cfg(adv, cte_count);
180 	common_create_per_adv_chain(adv, init_chain_length);
181 
182 	handle = ull_adv_handle_get(adv);
183 
184 	err = ll_df_set_cl_cte_tx_enable(handle, true);
185 	zassert_equal(err, 0,
186 		      "Unexpected error while enabling CTE for periodic advertising chain, err: %d",
187 		      err);
188 
189 	/* Swap PDU double buffer and get new latest PDU data */
190 	pdu_new = lll_adv_sync_data_latest_get(adv->lll.sync, NULL, &upd);
191 	zassert_not_equal(pdu_new, NULL,
192 			  "Unexpected value of new PDU pointer after PDU double buffer swap");
193 
194 	pdu_prev = lll_adv_sync_data_peek(adv->lll.sync, NULL);
195 	zassert_equal(pdu_prev, pdu_new,
196 		      "Unexpected value of previous PDU pointer after PDU double buffer swap");
197 
198 	/* Free PDUs fifo should hold single PDU released during double buffer swap. The PDU
199 	 * was allocated during advertising set creation.
200 	 */
201 	pdu_fifo_cnt = lll_adv_free_pdu_fifo_count_get();
202 	zassert_equal(pdu_fifo_cnt, TEST_PER_ADV_SINGLE_PDU,
203 		      "Unexpected number of free PDUs in a fifo: %d", pdu_fifo_cnt);
204 
205 	/* Expected free PDUs count is decreased by:
206 	 * - single PDU allocated during advertising set creation,
207 	 * - number of PDUs allocated for per. adv. chain to Tx CTE
208 	 */
209 	pdu_mem_cnt_expected -= expected_mem_pdu_used_count_for_enable;
210 	pdu_mem_cnt = lll_adv_pdu_mem_free_count_get();
211 	zassert_equal(pdu_mem_cnt, pdu_mem_cnt_expected,
212 		      "Unexpected amount of free PDUs memory: %d, expected %d", pdu_mem_cnt,
213 		      pdu_mem_cnt_expected);
214 
215 	if (new_chain_before_cte_disable) {
216 		common_create_per_adv_chain(adv, updated_chain_length);
217 	}
218 
219 	err = ll_df_set_cl_cte_tx_enable(handle, false);
220 	zassert_equal(err, 0,
221 		      "Unexpected error while disabling CTE for periodic advertising chain, err: %d",
222 		      err);
223 	/* Validate result */
224 	common_validate_per_adv_chain(adv, expected_pdu_in_chain_after_cte_disable);
225 
226 	/* Swap PDU double buffer to check correctness of release former PDUs */
227 	pdu_new = lll_adv_sync_data_latest_get(adv->lll.sync, NULL, &upd);
228 	zassert_not_equal(pdu_new, NULL,
229 			  "Unexpected value of PDU pointer after PDU double buffer swap");
230 
231 	/* Validate number of released PDUs */
232 
233 	/* Number of free PDUs in a fifo is a number of released PDUs from former periodic
234 	 * advertising chain. One free PDU that had been in a fifo was used for allocation of
235 	 * the new PDU without CTE.
236 	 */
237 	pdu_fifo_cnt = lll_adv_free_pdu_fifo_count_get();
238 	zassert_equal(pdu_fifo_cnt, expected_end_fifo_free_pdu_count,
239 		      "Unexpected number of free PDUs in a fifo: %d", pdu_fifo_cnt);
240 
241 	/* Number of free PDUs in memory pool may decreased. Single PDU for AUX_SYNC_IND was
242 	 * acquired from free PDUs fifo. The memory pool will decrease by number of non empty PDUs
243 	 * in a chain subtracted by 1 (PDU taken from free PDUs fifo).
244 	 */
245 	pdu_mem_cnt_expected -= expected_mem_pdu_used_count_for_disable;
246 
247 	pdu_mem_cnt = lll_adv_pdu_mem_free_count_get();
248 	zassert_equal(pdu_mem_cnt, pdu_mem_cnt_expected,
249 		      "Unexpected amount of free PDUs memory: %d, expected %d", pdu_mem_cnt,
250 		      pdu_mem_cnt_expected);
251 
252 	common_teardown(adv);
253 }
254 
ZTEST(test_add_cte_to_per_adv_chain,test_remove_cte_from_chain_extended_to_tx_all_cte_after_enqueue_to_lll)255 ZTEST(test_add_cte_to_per_adv_chain,
256 	test_remove_cte_from_chain_extended_to_tx_all_cte_after_enqueue_to_lll)
257 {
258 	uint8_t cte_count = TEST_CTE_COUNT;
259 	uint8_t init_chain_length = TEST_PER_ADV_SINGLE_PDU;
260 	uint8_t expected_mem_pdu_used_count_for_enable = TEST_CTE_COUNT + TEST_PER_ADV_SINGLE_PDU;
261 	uint8_t expected_mem_pdu_used_count_for_disable = 0;
262 	uint8_t expected_pdu_in_chain_after_cte_disable = TEST_PER_ADV_SINGLE_PDU;
263 	uint8_t updated_chain_length = 0;
264 	uint8_t expected_end_fifo_free_pdu_count = TEST_CTE_COUNT;
265 	bool new_chain_before_cte_disable = false;
266 
267 	remove_cte_from_chain_after_enqueue_to_lll(
268 		cte_count, init_chain_length, expected_mem_pdu_used_count_for_enable,
269 		expected_mem_pdu_used_count_for_disable, expected_pdu_in_chain_after_cte_disable,
270 		updated_chain_length, expected_end_fifo_free_pdu_count,
271 		new_chain_before_cte_disable);
272 }
273 
ZTEST(test_add_cte_to_per_adv_chain,test_remove_cte_from_chain_with_more_pdu_than_cte_after_enqueue_to_lll)274 ZTEST(test_add_cte_to_per_adv_chain,
275 	test_remove_cte_from_chain_with_more_pdu_than_cte_after_enqueue_to_lll)
276 {
277 	uint8_t cte_count = TEST_CTE_COUNT;
278 	uint8_t init_chain_length = TEST_PER_ADV_CHAIN_LENGTH;
279 	uint8_t expected_mem_pdu_used_count_for_enable =
280 		TEST_PER_ADV_CHAIN_LENGTH + TEST_PER_ADV_SINGLE_PDU;
281 	uint8_t expected_mem_pdu_used_count_for_disable =
282 		TEST_PER_ADV_CHAIN_LENGTH - TEST_PER_ADV_SINGLE_PDU;
283 	uint8_t expected_pdu_in_chain_after_cte_disable = TEST_PER_ADV_CHAIN_LENGTH;
284 	uint8_t updated_chain_length = 0;
285 	uint8_t expected_end_fifo_free_pdu_count = TEST_PER_ADV_CHAIN_LENGTH;
286 	bool new_chain_before_cte_disable = false;
287 
288 	remove_cte_from_chain_after_enqueue_to_lll(
289 		cte_count, init_chain_length, expected_mem_pdu_used_count_for_enable,
290 		expected_mem_pdu_used_count_for_disable, expected_pdu_in_chain_after_cte_disable,
291 		updated_chain_length, expected_end_fifo_free_pdu_count,
292 		new_chain_before_cte_disable);
293 }
294 
ZTEST(test_add_cte_to_per_adv_chain,test_remove_cte_from_chain_length_increased_after_enqueue_to_lll)295 ZTEST(test_add_cte_to_per_adv_chain,
296 	test_remove_cte_from_chain_length_increased_after_enqueue_to_lll)
297 {
298 	uint8_t cte_count = TEST_CTE_COUNT;
299 	uint8_t init_chain_length = TEST_PER_ADV_CHAIN_LENGTH;
300 	uint8_t expected_mem_pdu_used_count_for_enable =
301 		TEST_PER_ADV_CHAIN_LENGTH + TEST_PER_ADV_SINGLE_PDU;
302 	uint8_t expected_mem_pdu_used_count_for_disable =
303 		TEST_PER_ADV_CHAIN_INCREASED_LENGTH - TEST_PER_ADV_SINGLE_PDU;
304 	uint8_t expected_pdu_in_chain_after_cte_disable = TEST_PER_ADV_CHAIN_INCREASED_LENGTH;
305 	uint8_t updated_chain_length = TEST_PER_ADV_CHAIN_INCREASED_LENGTH;
306 	uint8_t expected_end_fifo_free_pdu_count = TEST_PER_ADV_CHAIN_LENGTH;
307 	bool new_chain_before_cte_disable = true;
308 
309 	remove_cte_from_chain_after_enqueue_to_lll(
310 		cte_count, init_chain_length, expected_mem_pdu_used_count_for_enable,
311 		expected_mem_pdu_used_count_for_disable, expected_pdu_in_chain_after_cte_disable,
312 		updated_chain_length, expected_end_fifo_free_pdu_count,
313 		new_chain_before_cte_disable);
314 }
315 
ZTEST(test_add_cte_to_per_adv_chain,test_remove_cte_from_chain_length_decreased_after_enqueue_to_lll)316 ZTEST(test_add_cte_to_per_adv_chain,
317 	test_remove_cte_from_chain_length_decreased_after_enqueue_to_lll)
318 {
319 	uint8_t cte_count = TEST_CTE_COUNT;
320 	uint8_t init_chain_length = TEST_PER_ADV_CHAIN_LENGTH;
321 	uint8_t expected_mem_pdu_used_count_for_enable =
322 		TEST_PER_ADV_CHAIN_LENGTH + TEST_PER_ADV_SINGLE_PDU;
323 	uint8_t expected_mem_pdu_used_count_for_disable =
324 		TEST_PER_ADV_CHAIN_DECREASED_LENGTH - TEST_PER_ADV_SINGLE_PDU;
325 	uint8_t expected_pdu_in_chain_after_cte_disable = TEST_PER_ADV_CHAIN_DECREASED_LENGTH;
326 	uint8_t updated_chain_length = TEST_PER_ADV_CHAIN_DECREASED_LENGTH;
327 	uint8_t expected_end_fifo_free_pdu_count = TEST_PER_ADV_CHAIN_LENGTH;
328 	bool new_chain_before_cte_disable = true;
329 
330 	remove_cte_from_chain_after_enqueue_to_lll(
331 		cte_count, init_chain_length, expected_mem_pdu_used_count_for_enable,
332 		expected_mem_pdu_used_count_for_disable, expected_pdu_in_chain_after_cte_disable,
333 		updated_chain_length, expected_end_fifo_free_pdu_count,
334 		new_chain_before_cte_disable);
335 }
336 
337 ZTEST_SUITE(test_remove_cte_from_per_adv_chain, NULL, NULL, NULL, NULL, NULL);
338