1 /*
2  * Copyright (c) 2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include <zephyr/kernel.h>
9 #include <soc.h>
10 #include <zephyr/sys/util.h>
11 #include <zephyr/bluetooth/hci_types.h>
12 
13 #include "hal/cpu.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/mfifo.h"
20 #include "util/dbuf.h"
21 
22 #include "pdu_df.h"
23 #include "lll/pdu_vendor.h"
24 #include "pdu.h"
25 
26 #include "lll.h"
27 #include "lll/lll_adv_types.h"
28 #include "lll_adv.h"
29 #include "lll/lll_adv_pdu.h"
30 #include "lll_scan.h"
31 #include "lll/lll_df_types.h"
32 #include "lll_sync.h"
33 #include "lll_sync_iso.h"
34 #include "lll_conn.h"
35 #include "lll_conn_iso.h"
36 #include "lll_df.h"
37 #include "lll/lll_df_internal.h"
38 
39 #include "isoal.h"
40 #include "ull_scan_types.h"
41 #include "ull_sync_types.h"
42 #include "ull_adv_types.h"
43 #include "ull_tx_queue.h"
44 #include "ull_conn_types.h"
45 #include "ull_iso_types.h"
46 #include "ull_conn_iso_types.h"
47 #include "ull_df_types.h"
48 #include "ull_llcp.h"
49 
50 #include "ull_internal.h"
51 #include "ull_adv_internal.h"
52 #include "ull_sync_internal.h"
53 #include "ull_conn_internal.h"
54 #include "ull_df_internal.h"
55 
56 #include "ll.h"
57 
58 #include "hal/debug.h"
59 
60 #if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX) || defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) || \
61 	defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
62 
63 #define CTE_LEN_MAX_US 160U
64 
65 #define IQ_REPORT_HEADER_SIZE      (offsetof(struct node_rx_iq_report, pdu))
66 #define IQ_REPORT_STRUCT_OVERHEAD  (IQ_REPORT_HEADER_SIZE)
67 #define IQ_SAMPLE_SIZE (sizeof(struct iq_sample))
68 
69 #define IQ_REPORT_RX_NODE_POOL_ELEMENT_SIZE              \
70 	MROUND(IQ_REPORT_STRUCT_OVERHEAD + (IQ_SAMPLE_TOTAL_CNT * IQ_SAMPLE_SIZE))
71 #define IQ_REPORT_POOL_SIZE (IQ_REPORT_RX_NODE_POOL_ELEMENT_SIZE * IQ_REPORT_CNT)
72 
73 /* Memory pool to store IQ reports data */
74 static struct {
75 	void *free;
76 	uint8_t pool[IQ_REPORT_POOL_SIZE];
77 } mem_iq_report;
78 
79 /* FIFO to store free IQ report norde_rx objects for LLL to ULL handover. */
80 static MFIFO_DEFINE(iq_report_free, sizeof(void *), IQ_REPORT_CNT);
81 
82 /* Number of available instance of linked list to be used for node_rx_iq_reports. */
83 static uint8_t mem_link_iq_report_quota_pdu;
84 
85 #if defined(CONFIG_BT_CTLR_DF_DEBUG_ENABLE)
86 /* Debug variable to store information about current number of allocated node_rx_iq_report.
87  * It supports verification if there is a resource leak.
88  * The variable may not be used when multiple
89  * advertising syncs are enabled. Checks may fail because CTE reception may be enabled/disabled
90  * in different moments, hence there may be allocated reports when it is expected not to.
91  */
92 COND_CODE_1(CONFIG_BT_PER_ADV_SYNC_MAX, (static uint32_t iq_report_alloc_count;), (EMPTY))
93 #define IF_SINGLE_ADV_SYNC_SET(code) COND_CODE_1(CONFIG_BT_PER_ADV_SYNC_MAX, (code), (EMPTY))
94 #endif /* CONFIG_BT_CTLR_DF_DEBUG_ENABLE */
95 #endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX || CONFIG_BT_CTLR_DF_CONN_CTE_RX*/
96 
97 #if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
98 /* Make sure the configuration follows BT Core 5.3. Vol 4 Part E section 7.8.82 about
99  * max CTE count sampled in periodic advertising chain.
100  */
101 BUILD_ASSERT(CONFIG_BT_CTLR_DF_PER_SCAN_CTE_NUM_MAX <= BT_HCI_LE_SAMPLE_CTE_COUNT_MAX,
102 	     "Max advertising CTE count exceed BT_HCI_LE_SAMPLE_CTE_COUNT_MAX");
103 #endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
104 
105 /* ToDo:
106  * - Add release of df_adv_cfg when adv_sync is released.
107  *   Open question, should df_adv_cfg be released when Adv. CTE is disabled?
108  *   If yes that would mean, end user must always run ll_df_set_cl_cte_tx_params
109  *   before consecutive Adv CTE enable.
110  */
111 
112 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
113 /* Make sure the configuration follows BT Core 5.3. Vol 4 Part E section 7.8.80 about
114  * max CTE count in a periodic advertising chain.
115  */
116 BUILD_ASSERT(CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX <= BT_HCI_LE_CTE_COUNT_MAX,
117 	     "Max advertising CTE count exceed BT_HCI_LE_CTE_COUNT_MAX");
118 
119 static struct lll_df_adv_cfg lll_df_adv_cfg_pool[CONFIG_BT_CTLR_ADV_AUX_SET];
120 static void *df_adv_cfg_free;
121 static uint8_t cte_info_clear(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_cfg,
122 			      uint8_t *ter_idx, struct pdu_adv **first_pdu);
123 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
124 
125 /* @brief Function performs common steps for initialization and reset
126  * of Direction Finding ULL module.
127  *
128  * @return      Zero in case of success, other value in case of failure.
129  */
130 static int init_reset(void);
131 
132 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
133 /* @brief Function acquires memory for DF advertising configuration.
134  *
135  * The memory is acquired from private @ref lll_df_adv_cfg_pool memory store.
136  *
137  * @return Pointer to lll_df_adv_cfg or NULL if there is no more free memory.
138  */
139 static struct lll_df_adv_cfg *df_adv_cfg_acquire(void);
140 
141 static uint8_t cte_info_set(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_cfg, uint8_t *ter_idx,
142 			    struct pdu_adv **first_pdu);
143 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
144 
145 /* @brief Function performs ULL Direction Finding initialization
146  *
147  * @return      Zero in case of success, other value in case of failure.
148  */
ull_df_init(void)149 int ull_df_init(void)
150 {
151 	int err;
152 
153 	err = init_reset();
154 	if (err) {
155 		return err;
156 	}
157 
158 	return 0;
159 }
160 
161 /* @brief Function performs ULL Direction Finding reset
162  *
163  * @return      Zero in case of success, other value in case of failure.
164  */
ull_df_reset(void)165 int ull_df_reset(void)
166 {
167 	int err;
168 
169 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
170 	struct ll_adv_set *adv;
171 	uint8_t handle;
172 
173 	/* Get the advertising set instance */
174 	for (handle = 0U; handle < BT_CTLR_ADV_SET; handle++) {
175 		adv = ull_adv_is_created_get(handle);
176 		if (!adv) {
177 			continue;
178 		}
179 
180 		adv->df_cfg = NULL;
181 	}
182 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
183 
184 	err = init_reset();
185 	if (err) {
186 		return err;
187 	}
188 
189 	return 0;
190 }
191 
init_reset(void)192 static int init_reset(void)
193 {
194 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
195 	/* Initialize advertising DF memory configuration pool. */
196 	mem_init(lll_df_adv_cfg_pool, sizeof(struct lll_df_adv_cfg),
197 		 sizeof(lll_df_adv_cfg_pool) / sizeof(struct lll_df_adv_cfg),
198 		 &df_adv_cfg_free);
199 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
200 
201 #if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX) || defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) || \
202 	defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
203 	/* Re-initialize the free IQ report mfifo */
204 	MFIFO_INIT(iq_report_free);
205 
206 	/* Initialize IQ report memory pool. */
207 	mem_init(mem_iq_report.pool, (IQ_REPORT_RX_NODE_POOL_ELEMENT_SIZE),
208 		 sizeof(mem_iq_report.pool) / (IQ_REPORT_RX_NODE_POOL_ELEMENT_SIZE),
209 		 &mem_iq_report.free);
210 
211 	/* Allocate free IQ report node rx */
212 	mem_link_iq_report_quota_pdu = IQ_REPORT_CNT;
213 	ull_df_rx_iq_report_alloc(UINT8_MAX);
214 #endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX || CONFIG_BT_CTLR_DF_CONN_CTE_RX */
215 	return 0;
216 }
217 
218 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
219 /* @brief Function sets CTE transmission parameters for periodic advertising.
220  *
221  * @param[in]adv_handle                 Handle of advertising set.
222  * @param[in]cte_len                    Length of CTE in 8us units.
223  * @param[in]cte_type                   Type of CTE to be used for transmission.
224  * @param[in]cte_count                  Number of CTE that should be transmitted
225  *                                      during each periodic advertising
226  *                                      interval.
227  * @param[in]num_ant_ids                Number of antenna IDs in switching
228  *                                      pattern. May be zero if CTE type is
229  *                                      AoA.
230  * @param[in]ant_ids                    Array of antenna IDs in a switching
231  *                                      pattern. May be NULL if CTE type is AoA.
232  *
233  * @return Status of command completion.
234  */
ll_df_set_cl_cte_tx_params(uint8_t adv_handle,uint8_t cte_len,uint8_t cte_type,uint8_t cte_count,uint8_t num_ant_ids,uint8_t * ant_ids)235 uint8_t ll_df_set_cl_cte_tx_params(uint8_t adv_handle, uint8_t cte_len,
236 				   uint8_t cte_type, uint8_t cte_count,
237 				   uint8_t num_ant_ids, uint8_t *ant_ids)
238 {
239 	struct lll_df_adv_cfg *cfg;
240 	struct ll_adv_set *adv;
241 
242 	/* Get the advertising set instance */
243 	adv = ull_adv_is_created_get(adv_handle);
244 	if (!adv) {
245 		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
246 	}
247 
248 	if (cte_len < BT_HCI_LE_CTE_LEN_MIN ||
249 	    cte_len > BT_HCI_LE_CTE_LEN_MAX) {
250 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
251 	}
252 
253 	/* Max number of CTE in a single periodic advertising event is limited
254 	 * by configuration. It shall not be greater than BT_HCI_LE_CTE_COUNT_MAX.
255 	 */
256 	if (cte_count < BT_HCI_LE_CTE_COUNT_MIN ||
257 	    cte_count > CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX) {
258 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
259 	}
260 
261 	if (!(IS_ENABLED(CONFIG_BT_CTLR_DF_ADV_CTE_TX) &&
262 	      ((cte_type == BT_HCI_LE_AOA_CTE) ||
263 		(IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) &&
264 		 ((cte_type == BT_HCI_LE_AOD_CTE_2US) ||
265 		  (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US) &&
266 		   cte_type == BT_HCI_LE_AOD_CTE_1US)))))) {
267 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
268 	}
269 
270 	if ((cte_type == BT_HCI_LE_AOD_CTE_1US || cte_type == BT_HCI_LE_AOD_CTE_2US) &&
271 	    (num_ant_ids < BT_HCI_LE_CTE_LEN_MIN ||
272 	     num_ant_ids > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN || !ant_ids)) {
273 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
274 	}
275 
276 	if (!adv->df_cfg) {
277 		adv->df_cfg = df_adv_cfg_acquire();
278 	}
279 
280 	cfg = adv->df_cfg;
281 
282 	if (cfg->is_enabled) {
283 		return BT_HCI_ERR_CMD_DISALLOWED;
284 	}
285 
286 	cfg->cte_count = cte_count;
287 	cfg->cte_length = cte_len;
288 	cfg->cte_type = cte_type;
289 
290 	if (cte_type == BT_HCI_LE_AOD_CTE_1US ||
291 	    cte_type == BT_HCI_LE_AOD_CTE_2US) {
292 		/* Note:
293 		 * Are we going to check antenna identifiers if they are valid?
294 		 * BT 5.2 Core spec. Vol. 4 Part E Section 7.8.80 says
295 		 * that not all controller may be able to do that.
296 		 */
297 		memcpy(cfg->ant_ids, ant_ids, num_ant_ids);
298 		cfg->ant_sw_len = num_ant_ids;
299 	} else {
300 		cfg->ant_sw_len = 0;
301 	}
302 
303 	return BT_HCI_ERR_SUCCESS;
304 }
305 
306 /* @brief Function enables or disables CTE TX for periodic advertising.
307  *
308  * @param[in] handle                    Advertising set handle.
309  * @param[in] cte_enable                Enable or disable CTE TX
310  *
311  * @return Status of command completion.
312  */
ll_df_set_cl_cte_tx_enable(uint8_t adv_handle,uint8_t cte_enable)313 uint8_t ll_df_set_cl_cte_tx_enable(uint8_t adv_handle, uint8_t cte_enable)
314 {
315 	struct lll_adv_sync *lll_sync;
316 	struct lll_df_adv_cfg *df_cfg;
317 	struct ll_adv_sync_set *sync;
318 	struct ll_adv_set *adv;
319 	uint8_t err, ter_idx;
320 	struct pdu_adv *pdu;
321 
322 	/* Get the advertising set instance */
323 	adv = ull_adv_is_created_get(adv_handle);
324 	if (!adv) {
325 		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
326 	}
327 
328 	lll_sync = adv->lll.sync;
329 	/* If there is no sync in advertising set, then the HCI_LE_Set_-
330 	 * Periodic_Advertising_Parameters command was not issued before.
331 	 */
332 	if (!lll_sync) {
333 		return BT_HCI_ERR_CMD_DISALLOWED;
334 	}
335 
336 	sync = HDR_LLL2ULL(lll_sync);
337 
338 	/* If df_cfg is NULL, then the HCI_LE_Set_Connectionless_CTE_Transmit_-
339 	 * Parameters command was not issued before.
340 	 */
341 	df_cfg = adv->df_cfg;
342 	if (!df_cfg) {
343 		return BT_HCI_ERR_CMD_DISALLOWED;
344 	}
345 
346 	if (adv->lll.phy_s == PHY_CODED) {
347 		return BT_HCI_ERR_CMD_DISALLOWED;
348 	}
349 
350 	if (!cte_enable) {
351 		if (!df_cfg->is_enabled) {
352 			return BT_HCI_ERR_CMD_DISALLOWED;
353 		}
354 
355 		err = cte_info_clear(adv, df_cfg, &ter_idx, &pdu);
356 		if (err) {
357 			return err;
358 		}
359 
360 		df_cfg->is_enabled = 0U;
361 	} else {
362 		if (df_cfg->is_enabled) {
363 			return BT_HCI_ERR_CMD_DISALLOWED;
364 		}
365 
366 		err = cte_info_set(adv, df_cfg, &ter_idx, &pdu);
367 		if (err) {
368 			return err;
369 		}
370 
371 		df_cfg->is_enabled = 1U;
372 	}
373 
374 	if (sync->is_started) {
375 		err = ull_adv_sync_time_update(sync, pdu);
376 		if (err) {
377 			return err;
378 		}
379 	}
380 
381 	lll_adv_sync_data_enqueue(adv->lll.sync, ter_idx);
382 
383 	return BT_HCI_ERR_SUCCESS;
384 }
385 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
386 
387 #if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
388 /* @brief Function sets IQ sampling enabled or disabled.
389  *
390  * Set IQ sampling enable for received PDUs that has attached CTE.
391  *
392  * @param[in]handle                     Connection handle.
393  * @param[in]sampling_enable            Enable or disable CTE RX
394  * @param[in]slot_durations             Switching and sampling slot durations for
395  *                                      AoA mode.
396  * @param[in]max_cte_count              Maximum number of sampled CTEs in single
397  *                                      periodic advertising event.
398  * @param[in]switch_pattern_len         Number of antenna ids in switch pattern.
399  * @param[in]ant_ids                    Array of antenna identifiers.
400  *
401  * @return Status of command completion.
402  *
403  * @Note This function may put TX thread into wait state. This may lead to a
404  *       situation that ll_sync_set instance is relased (RX thread has higher
405  *       priority than TX thread). ll_sync_set instance may not be accessed after
406  *       call to ull_sync_slot_update.
407  *       This is related with possible race condition with RX thread handling
408  *       periodic sync lost event.
409  */
ll_df_set_cl_iq_sampling_enable(uint16_t handle,uint8_t sampling_enable,uint8_t slot_durations,uint8_t max_cte_count,uint8_t switch_pattern_len,uint8_t * ant_ids)410 uint8_t ll_df_set_cl_iq_sampling_enable(uint16_t handle,
411 					uint8_t sampling_enable,
412 					uint8_t slot_durations,
413 					uint8_t max_cte_count,
414 					uint8_t switch_pattern_len,
415 					uint8_t *ant_ids)
416 {
417 	struct lll_df_sync_cfg *cfg, *cfg_prev;
418 	uint32_t slot_minus_us = 0;
419 	uint32_t slot_plus_us = 0;
420 	struct ll_sync_set *sync;
421 	struct lll_sync *lll;
422 	uint8_t cfg_idx;
423 
424 	/* After this call and before ull_sync_slot_update the function may not
425 	 * call any kernel API that may put the thread into wait state. It may
426 	 * cause race condition with RX thread and lead to use of released memory.
427 	 */
428 	sync = ull_sync_is_enabled_get(handle);
429 	if (!sync) {
430 		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
431 	}
432 
433 	lll = &sync->lll;
434 
435 	/* CTE is not supported for CODED Phy */
436 	if (lll->phy == PHY_CODED) {
437 		return BT_HCI_ERR_CMD_DISALLOWED;
438 	}
439 
440 	cfg_prev = lll_df_sync_cfg_curr_get(&lll->df_cfg);
441 	cfg = lll_df_sync_cfg_alloc(&lll->df_cfg, &cfg_idx);
442 
443 	if (!sampling_enable) {
444 		if (!cfg_prev->is_enabled) {
445 			/* Disable already disabled CTE Rx */
446 			return BT_HCI_ERR_SUCCESS;
447 		}
448 		slot_minus_us = CTE_LEN_MAX_US;
449 		cfg->is_enabled = 0U;
450 	} else {
451 
452 #if defined(CONFIG_BT_CTLR_DF_DEBUG_ENABLE)
453 		/* When CTE is enabled there should be no iq report allocated */
454 		IF_SINGLE_ADV_SYNC_SET(LL_ASSERT(iq_report_alloc_count == 0));
455 #endif /* CONFIG_BT_CTLR_DF_DEBUG_ENABLE */
456 
457 		/* Enable of already enabled CTE updates AoA configuration */
458 
459 		/* According to Core 5.3 Vol 4, Part E, section 7.8.82 slot_durations,
460 		 * switch_pattern_len and ant_ids are used only for AoA and do not affect
461 		 * reception of AoD CTE. If AoA is not supported relax command validation
462 		 * to improve interoperability with different Host implementations.
463 		 */
464 		if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)) {
465 			if (!((IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US) &&
466 			       slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US) ||
467 			      slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US)) {
468 				return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
469 			}
470 
471 			if (switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
472 			    switch_pattern_len > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN || !ant_ids) {
473 				return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
474 			}
475 
476 			(void)memcpy(cfg->ant_ids, ant_ids, switch_pattern_len);
477 		}
478 		cfg->slot_durations = slot_durations;
479 		cfg->ant_sw_len = switch_pattern_len;
480 
481 		/* max_cte_count equal to 0x0 has special meaning - sample and
482 		 * report continuously until there are CTEs received.
483 		 */
484 		if (max_cte_count > CONFIG_BT_CTLR_DF_PER_SCAN_CTE_NUM_MAX) {
485 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
486 		}
487 		cfg->max_cte_count = max_cte_count;
488 
489 		cfg->is_enabled = 1U;
490 
491 		if (!cfg_prev->is_enabled) {
492 			/* Extend sync event by maximum CTE duration.
493 			 * CTE duration depends on transmitter configuration
494 			 * so it is unknown for receiver upfront.
495 			 * BT_HCI_LE_CTE_LEN_MAX is in 8us units.
496 			 */
497 			slot_plus_us = BT_HCI_LE_CTE_LEN_MAX * 8U;
498 		}
499 	}
500 
501 	lll_df_sync_cfg_enqueue(&lll->df_cfg, cfg_idx);
502 
503 	if (slot_plus_us || slot_minus_us) {
504 		int err;
505 		/* Update of sync slot may fail due to race condition.
506 		 * If periodic sync is lost, the ticker event will be stopped.
507 		 * The stop operation may preempt call to this functions.
508 		 * So update may be called after that. Accept this failure
509 		 * (-ENOENT) gracefully.
510 		 * Periodic sync lost event also disables the CTE sampling.
511 		 */
512 		err = ull_sync_slot_update(sync, slot_plus_us, slot_minus_us);
513 		LL_ASSERT(err == 0 || err == -ENOENT);
514 	}
515 
516 	return 0;
517 }
518 
ull_df_sync_cfg_init(struct lll_df_sync * df_cfg)519 void ull_df_sync_cfg_init(struct lll_df_sync *df_cfg)
520 {
521 	(void)memset(&df_cfg->cfg, 0, sizeof(df_cfg->cfg));
522 	df_cfg->first = 0U;
523 	df_cfg->last = 0U;
524 }
525 
ull_df_sync_cfg_is_not_enabled(struct lll_df_sync * df_cfg)526 bool ull_df_sync_cfg_is_not_enabled(struct lll_df_sync *df_cfg)
527 {
528 	struct lll_df_sync_cfg *cfg;
529 
530 	/* If new CTE sampling configuration was enqueued, get reference to
531 	 * latest configuration without swapping buffers. Buffer should be
532 	 * swapped only at the beginning of the radio event.
533 	 *
534 	 * We may not get here if CTE sampling is not enabled in current
535 	 * configuration.
536 	 */
537 	if (lll_df_sync_cfg_is_modified(df_cfg)) {
538 		cfg = lll_df_sync_cfg_peek(df_cfg);
539 	} else {
540 		cfg = lll_df_sync_cfg_curr_get(df_cfg);
541 	}
542 
543 	return !cfg->is_enabled;
544 }
545 #endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
546 
547 #if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX) || defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) || \
548 	defined(CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT)
ull_df_iq_report_alloc_peek(uint8_t count)549 void *ull_df_iq_report_alloc_peek(uint8_t count)
550 {
551 	if (count > MFIFO_AVAIL_COUNT_GET(iq_report_free)) {
552 		return NULL;
553 	}
554 
555 	return MFIFO_DEQUEUE_PEEK(iq_report_free);
556 }
557 
ull_df_iq_report_alloc_peek_iter(uint8_t * idx)558 void *ull_df_iq_report_alloc_peek_iter(uint8_t *idx)
559 {
560 	return *(void **)MFIFO_DEQUEUE_ITER_GET(iq_report_free, idx);
561 }
562 
ull_df_iq_report_alloc(void)563 void *ull_df_iq_report_alloc(void)
564 {
565 #if defined(CONFIG_BT_CTLR_DF_DEBUG_ENABLE)
566 	IF_SINGLE_ADV_SYNC_SET(iq_report_alloc_count++);
567 #endif /* CONFIG_BT_CTLR_DF_DEBUG_ENABLE */
568 
569 	return MFIFO_DEQUEUE(iq_report_free);
570 }
571 
ull_df_iq_report_mem_release(struct node_rx_hdr * rx)572 void ull_df_iq_report_mem_release(struct node_rx_hdr *rx)
573 {
574 #if defined(CONFIG_BT_CTLR_DF_DEBUG_ENABLE)
575 	IF_SINGLE_ADV_SYNC_SET(iq_report_alloc_count--);
576 #endif /* CONFIG_BT_CTLR_DF_DEBUG_ENABLE */
577 
578 	mem_release(rx, &mem_iq_report.free);
579 }
580 
ull_iq_report_link_inc_quota(int8_t delta)581 void ull_iq_report_link_inc_quota(int8_t delta)
582 {
583 	LL_ASSERT(delta <= 0 || mem_link_iq_report_quota_pdu < (IQ_REPORT_CNT));
584 
585 	mem_link_iq_report_quota_pdu += delta;
586 }
587 
ull_df_rx_iq_report_alloc(uint8_t max)588 void ull_df_rx_iq_report_alloc(uint8_t max)
589 {
590 	uint8_t idx;
591 
592 	if (max > mem_link_iq_report_quota_pdu) {
593 		max = mem_link_iq_report_quota_pdu;
594 	}
595 
596 	while ((max--) && MFIFO_ENQUEUE_IDX_GET(iq_report_free, &idx)) {
597 		memq_link_t *link;
598 		struct node_rx_hdr *rx;
599 
600 		link = ll_rx_link_alloc();
601 		if (!link) {
602 			return;
603 		}
604 
605 		rx = mem_acquire(&mem_iq_report.free);
606 		if (!rx) {
607 			ll_rx_link_release(link);
608 			return;
609 		}
610 
611 		rx->link = link;
612 
613 		MFIFO_BY_IDX_ENQUEUE(iq_report_free, idx, rx);
614 
615 		ull_iq_report_link_inc_quota(-1);
616 	}
617 }
618 #endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX || CONFIG_BT_CTLR_DF_CONN_CTE_RX */
619 
620 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
ull_df_conn_cfg_is_not_enabled(struct lll_df_conn_rx_cfg * rx_cfg)621 bool ull_df_conn_cfg_is_not_enabled(struct lll_df_conn_rx_cfg *rx_cfg)
622 {
623 	struct lll_df_conn_rx_params *rx_params;
624 
625 	/* If new CTE sampling configuration was enqueued, get reference to
626 	 * latest configuration without swapping buffers. Buffer should be
627 	 * swapped only at the beginning of the radio event.
628 	 *
629 	 * We may not get here if CTE sampling is not enabled in current
630 	 * configuration.
631 	 */
632 	if (dbuf_is_modified(&rx_cfg->hdr)) {
633 		rx_params = dbuf_peek(&rx_cfg->hdr);
634 	} else {
635 		rx_params = dbuf_curr_get(&rx_cfg->hdr);
636 	}
637 
638 	return !rx_params->is_enabled;
639 }
640 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
641 
642 #if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
643 /* @brief Function releases unused memory for DF advertising configuration.
644  *
645  * The memory is released to private @ref lll_df_adv_cfg_pool memory store.
646  *
647  * @param[in] df_adv_cfg        Pointer to lll_df_adv_cfg memory to be released.
648  */
ull_df_adv_cfg_release(struct lll_df_adv_cfg * df_adv_cfg)649 void ull_df_adv_cfg_release(struct lll_df_adv_cfg *df_adv_cfg)
650 {
651 	mem_release(df_adv_cfg, &df_adv_cfg_free);
652 }
653 
df_adv_cfg_acquire(void)654 static struct lll_df_adv_cfg *df_adv_cfg_acquire(void)
655 {
656 	struct lll_df_adv_cfg *df_adv_cfg;
657 
658 	df_adv_cfg = mem_acquire(&df_adv_cfg_free);
659 	if (!df_adv_cfg) {
660 		return NULL;
661 	}
662 
663 	df_adv_cfg->is_enabled = 0U;
664 
665 	return df_adv_cfg;
666 }
667 
668 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
669 /*
670  * @brief Function sets content of cte_info field in periodic advertising chain.
671  *
672  * The function allocates new PDU (or chain of PDUs) for periodic advertising to
673  * fill it with information about CTE, that is going to be transmitted with the PDU.
674  * If there is already allocated PDU, it will be updated to hold information about
675  * CTE.
676  *
677  * @param lll_sync       Pointer to periodic advertising sync object.
678  * @param pdu_prev       Pointer to a PDU that is already in use by LLL or was updated with new PDU
679  *                       payload.
680  * @param pdu            Pointer to a new head of periodic advertising chain. The pointer may have
681  *                       the same value as @p pdu_prev, if payload of PDU pointed by @p pdu_prev
682  *                       was already updated.
683  * @param cte_count      Number of CTEs that should be transmitted in periodic advertising chain.
684  * @param cte_into       Pointer to instance of cte_info structure that is added to PDUs extended
685  *                       advertising header.
686  *
687  * @return Zero in case of success, other value in case of failure.
688  */
per_adv_chain_cte_info_set(struct lll_adv_sync * lll_sync,struct pdu_adv * pdu_prev,struct pdu_adv * pdu,uint8_t cte_count,struct pdu_cte_info * cte_info)689 static uint8_t per_adv_chain_cte_info_set(struct lll_adv_sync *lll_sync,
690 					  struct pdu_adv *pdu_prev,
691 					  struct pdu_adv *pdu,
692 					  uint8_t cte_count,
693 					  struct pdu_cte_info *cte_info)
694 {
695 	uint8_t hdr_data[ULL_ADV_HDR_DATA_CTE_INFO_SIZE +
696 			 ULL_ADV_HDR_DATA_LEN_SIZE +
697 			 ULL_ADV_HDR_DATA_ADI_PTR_SIZE +
698 			 ULL_ADV_HDR_DATA_LEN_SIZE +
699 			 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE] = {0, };
700 	uint8_t pdu_add_field_flags;
701 	struct pdu_adv *pdu_next;
702 	uint8_t cte_index = 1;
703 	bool adi_in_sync_ind;
704 	bool new_chain;
705 	uint8_t err;
706 
707 	new_chain = (pdu_prev == pdu ? false : true);
708 
709 	pdu_add_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
710 
711 	(void)memcpy(&hdr_data[ULL_ADV_HDR_DATA_CTE_INFO_OFFSET],
712 		     cte_info, sizeof(*cte_info));
713 
714 	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
715 		adi_in_sync_ind = ull_adv_sync_pdu_had_adi(pdu_prev);
716 	}
717 
718 	pdu_prev = lll_adv_pdu_linked_next_get(pdu_prev);
719 
720 	/* Update PDUs in existing chain. Add cte_info to extended advertising
721 	 * header.
722 	 */
723 	while (pdu_prev) {
724 		uint8_t	aux_ptr_offset = ULL_ADV_HDR_DATA_CTE_INFO_SIZE +
725 					 ULL_ADV_HDR_DATA_LEN_SIZE;
726 		uint8_t *hdr_data_ptr;
727 
728 		if (new_chain) {
729 			pdu_next = lll_adv_pdu_alloc_pdu_adv();
730 			lll_adv_pdu_linked_append(pdu_next, pdu);
731 			pdu = pdu_next;
732 		} else {
733 			pdu = lll_adv_pdu_linked_next_get(pdu);
734 		}
735 
736 		pdu_next = lll_adv_pdu_linked_next_get(pdu_prev);
737 
738 		/* If all CTEs were added to chain, remove CTE from flags */
739 		if (cte_index >= cte_count) {
740 			pdu_add_field_flags = 0U;
741 			hdr_data_ptr =
742 				&hdr_data[ULL_ADV_HDR_DATA_CTE_INFO_SIZE];
743 		} else {
744 			++cte_index;
745 			hdr_data_ptr = hdr_data;
746 		}
747 
748 		if (pdu_next) {
749 			pdu_add_field_flags |= ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
750 		} else {
751 			pdu_add_field_flags &= ~ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
752 		}
753 
754 		if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) &&
755 		    adi_in_sync_ind) {
756 			pdu_add_field_flags |= ULL_ADV_PDU_HDR_FIELD_ADI;
757 			aux_ptr_offset += ULL_ADV_HDR_DATA_ADI_PTR_SIZE +
758 					  ULL_ADV_HDR_DATA_LEN_SIZE;
759 		}
760 
761 		err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
762 						 pdu_add_field_flags, 0U,
763 						 hdr_data_ptr);
764 		if (err != BT_HCI_ERR_SUCCESS) {
765 			/* TODO: implement gracefull error handling, cleanup of
766 			 * changed PDUs and notify host about issue during start
767 			 * of CTE transmission.
768 			 */
769 			return err;
770 		}
771 
772 		if (pdu_next) {
773 			const struct lll_adv *lll = lll_sync->adv;
774 			struct pdu_adv_aux_ptr *aux_ptr;
775 			uint32_t offs_us;
776 
777 			(void)memcpy(&aux_ptr, &hdr_data[aux_ptr_offset],
778 				     sizeof(aux_ptr));
779 
780 			/* Fill the aux offset in the PDU */
781 			offs_us = PDU_AC_US(pdu->len, lll->phy_s,
782 					    lll->phy_flags) +
783 				  EVENT_SYNC_B2B_MAFS_US;
784 			offs_us += CTE_LEN_US(cte_info->time);
785 			ull_adv_aux_ptr_fill(aux_ptr, offs_us, lll->phy_s);
786 		}
787 
788 		pdu_prev = pdu_next;
789 	}
790 
791 	/* If there is missing only one CTE do not add aux_ptr to PDU */
792 	if (cte_count - cte_index >= 2) {
793 		pdu_add_field_flags |= ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
794 	} else {
795 		pdu_add_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
796 	}
797 
798 	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) && adi_in_sync_ind) {
799 		pdu_add_field_flags |= ULL_ADV_PDU_HDR_FIELD_ADI;
800 	}
801 
802 	/* Add new PDUs if the number of PDUs in existing chain is lower than
803 	 * requested number of CTEs.
804 	 */
805 	while (cte_index < cte_count) {
806 		const struct lll_adv *lll = lll_sync->adv;
807 
808 		pdu_prev = pdu;
809 		pdu = lll_adv_pdu_alloc_pdu_adv();
810 		if (!pdu) {
811 			/* TODO: implement graceful error handling, cleanup of
812 			 * changed PDUs.
813 			 */
814 			return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
815 		}
816 		ull_adv_sync_pdu_init(pdu, pdu_add_field_flags, lll->phy_s,
817 				      lll->phy_flags, cte_info);
818 
819 		/* Link PDU into a chain */
820 		lll_adv_pdu_linked_append(pdu, pdu_prev);
821 
822 		++cte_index;
823 		/* If next PDU in a chain is last PDU, then remove aux_ptr field
824 		 * flag from extended advertising header.
825 		 */
826 		if (cte_index == cte_count - 1) {
827 			pdu_add_field_flags &= (~ULL_ADV_PDU_HDR_FIELD_AUX_PTR);
828 		}
829 	}
830 
831 	return BT_HCI_ERR_SUCCESS;
832 }
833 #endif /* CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1 */
834 
835 /*
836  * @brief Function sets content of cte_info field for periodic advertising
837  *
838  * @param adv            Pointer to periodic advertising set.
839  * @param df_cfg         Pointer to direction finding configuration
840  * @param[out] ter_idx   Pointer used to return index of allocated or updated PDU.
841  *                       Index is required for scheduling the PDU for transmission in LLL.
842  * @param[out] first_pdu Pointer to return address of first PDU in a periodic advertising chain
843  *
844  * @return Zero in case of success, other value in case of failure.
845  */
cte_info_set(struct ll_adv_set * adv,struct lll_df_adv_cfg * df_cfg,uint8_t * ter_idx,struct pdu_adv ** first_pdu)846 static uint8_t cte_info_set(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_cfg, uint8_t *ter_idx,
847 			    struct pdu_adv **first_pdu)
848 {
849 	uint8_t hdr_data[ULL_ADV_HDR_DATA_CTE_INFO_SIZE +
850 			 ULL_ADV_HDR_DATA_LEN_SIZE +
851 			 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE] = {0, };
852 	struct pdu_adv *pdu_prev, *pdu;
853 	struct lll_adv_sync *lll_sync;
854 	struct pdu_cte_info cte_info;
855 	uint8_t pdu_add_field_flags;
856 	void *extra_data;
857 	uint8_t err;
858 
859 	lll_sync = adv->lll.sync;
860 
861 	cte_info.type = df_cfg->cte_type;
862 	cte_info.time = df_cfg->cte_length;
863 	cte_info.rfu = 0U;
864 
865 	/* Note: ULL_ADV_PDU_EXTRA_DATA_ALLOC_ALWAYS is just information that extra_data
866 	 * is required in case of this ull_adv_sync_pdu_alloc.
867 	 */
868 	extra_data = NULL;
869 	err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_ALWAYS, &pdu_prev, &pdu,
870 				     NULL, &extra_data, ter_idx);
871 	if (err != BT_HCI_ERR_SUCCESS) {
872 		return err;
873 	}
874 
875 	if (extra_data) {
876 		ull_adv_sync_extra_data_set_clear(NULL, extra_data, ULL_ADV_PDU_HDR_FIELD_CTE_INFO,
877 						  0, df_cfg);
878 	}
879 
880 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
881 	if (df_cfg->cte_count > 1) {
882 		pdu_add_field_flags =
883 			ULL_ADV_PDU_HDR_FIELD_CTE_INFO | ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
884 	} else
885 #endif /* CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1 */
886 	{
887 		pdu_add_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
888 	}
889 
890 	(void)memcpy(&hdr_data[ULL_ADV_HDR_DATA_CTE_INFO_OFFSET],
891 		     &cte_info, sizeof(cte_info));
892 
893 	err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu, pdu_add_field_flags, 0,
894 					 hdr_data);
895 	if (err != BT_HCI_ERR_SUCCESS) {
896 		return err;
897 	}
898 
899 	*first_pdu = pdu;
900 
901 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
902 	if (df_cfg->cte_count > 1) {
903 		struct pdu_adv_aux_ptr *aux_ptr;
904 		uint32_t offs_us;
905 
906 		(void)memcpy(&aux_ptr,
907 			     &hdr_data[ULL_ADV_HDR_DATA_CTE_INFO_SIZE +
908 				       ULL_ADV_HDR_DATA_LEN_SIZE],
909 			     sizeof(aux_ptr));
910 
911 		/* Fill the aux offset in the PDU */
912 		offs_us = PDU_AC_US(pdu->len, adv->lll.phy_s,
913 				    adv->lll.phy_flags) +
914 			  EVENT_SYNC_B2B_MAFS_US;
915 		offs_us += CTE_LEN_US(cte_info.time);
916 		ull_adv_aux_ptr_fill(aux_ptr, offs_us, adv->lll.phy_s);
917 	}
918 
919 	err = per_adv_chain_cte_info_set(lll_sync, pdu_prev, pdu, df_cfg->cte_count, &cte_info);
920 	if (err != BT_HCI_ERR_SUCCESS) {
921 		return err;
922 	}
923 #endif /* CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1 */
924 
925 	return BT_HCI_ERR_SUCCESS;
926 }
927 
928 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
pdu_ext_adv_is_empty_without_cte(const struct pdu_adv * pdu)929 static bool pdu_ext_adv_is_empty_without_cte(const struct pdu_adv *pdu)
930 {
931 	if (pdu->len != PDU_AC_PAYLOAD_SIZE_MIN) {
932 		const struct pdu_adv_ext_hdr *ext_hdr;
933 		uint8_t size_rem = 0;
934 
935 		if ((pdu->adv_ext_ind.ext_hdr_len + PDU_AC_EXT_HEADER_SIZE_MIN) != pdu->len) {
936 			/* There are adv. data in PDU */
937 			return false;
938 		}
939 
940 		/* Check size of the ext. header without cte_info and aux_ptr. If that is minimum
941 		 * extended PDU size then the PDU was allocated to transport CTE only.
942 		 */
943 		ext_hdr = &pdu->adv_ext_ind.ext_hdr;
944 
945 		if (ext_hdr->cte_info) {
946 			size_rem += sizeof(struct pdu_cte_info);
947 		}
948 		if (ext_hdr->aux_ptr) {
949 			size_rem += sizeof(struct pdu_adv_aux_ptr);
950 		}
951 		if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) && ext_hdr->adi) {
952 			size_rem += sizeof(struct pdu_adv_adi);
953 		}
954 
955 		if ((pdu->adv_ext_ind.ext_hdr_len - size_rem) != PDU_AC_EXT_HEADER_SIZE_MIN) {
956 			return false;
957 		}
958 	}
959 
960 	return true;
961 }
962 
963 /*
964  * @brief Function removes content of cte_info field in periodic advertising chain.
965  *
966  * The function removes cte_info from extended advertising header in all PDUs in periodic
967  * advertising chain. If particular PDU is empty (holds cte_info only) it will be removed from
968  * chain.
969  *
970  * @param[in] lll_sync     Pointer to periodic advertising sync object.
971  * @param[in-out] pdu_prev Pointer to a PDU that is already in use by LLL or was updated with new
972  *                         PDU payload. Points to last PDU in a previous chain after return.
973  * @param[in-out] pdu      Pointer to a new head of periodic advertising chain. The pointer may have
974  *                         the same value as @p pdu_prev, if payload of PDU pointerd by @p pdu_prev
975  *                         was already updated. Points to last PDU in a new chain after return.
976  *
977  * @return Zero in case of success, other value in case of failure.
978  */
rem_cte_info_from_per_adv_chain(struct lll_adv_sync * lll_sync,struct pdu_adv ** pdu_prev,struct pdu_adv ** pdu)979 static uint8_t rem_cte_info_from_per_adv_chain(struct lll_adv_sync *lll_sync,
980 					       struct pdu_adv **pdu_prev, struct pdu_adv **pdu)
981 {
982 	struct pdu_adv *pdu_new, *pdu_chained;
983 	uint8_t pdu_rem_field_flags;
984 	bool new_chain;
985 	uint8_t err;
986 
987 	pdu_rem_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
988 
989 	/* It is possible that the function is called after e.g. advertising data were updated.
990 	 * In such situation the function will run on already allocated chain. Do not allocate
991 	 * new chain then. Reuse already allocated PDUs and allocate new ones only if the chain
992 	 * was not updated yet.
993 	 */
994 	new_chain = (*pdu_prev == *pdu ? false : true);
995 
996 	/* Get next PDU in a chain. Alway use pdu_prev because it points to actual
997 	 * former chain.
998 	 */
999 	pdu_chained = lll_adv_pdu_linked_next_get(*pdu_prev);
1000 
1001 	/* Go through existing chain and remove CTE info. */
1002 	while (pdu_chained) {
1003 		if (pdu_ext_adv_is_empty_without_cte(pdu_chained)) {
1004 			/* If there is an empty PDU then all remaining PDUs should be released. */
1005 			if (!new_chain) {
1006 				lll_adv_pdu_linked_release_all(pdu_chained);
1007 
1008 				/* Set new end of chain in PDUs linked list. If pdu differs from
1009 				 * prev_pdu then it is already end of a chain. If it doesn't differ,
1010 				 * then chain end is changed in right place by use of pdu_prev.
1011 				 * That makes sure there is no PDU released twice (here and when LLL
1012 				 * swaps PDU buffers).
1013 				 */
1014 				lll_adv_pdu_linked_append(NULL, *pdu_prev);
1015 			}
1016 			pdu_chained = NULL;
1017 		} else {
1018 			/* Update one before pdu_chained */
1019 			err = ull_adv_sync_pdu_set_clear(lll_sync, *pdu_prev, *pdu, 0,
1020 							 pdu_rem_field_flags, NULL);
1021 			if (err != BT_HCI_ERR_SUCCESS) {
1022 				/* TODO: return here leaves periodic advertising chain in
1023 				 * an inconsistent state. Add gracefull return or assert.
1024 				 */
1025 				return err;
1026 			}
1027 
1028 			/* Prepare for next iteration. Allocate new PDU or move to next one in
1029 			 * a chain.
1030 			 */
1031 			if (new_chain) {
1032 				pdu_new = lll_adv_pdu_alloc_pdu_adv();
1033 				lll_adv_pdu_linked_append(pdu_new, *pdu);
1034 				*pdu = pdu_new;
1035 			} else {
1036 				*pdu = lll_adv_pdu_linked_next_get(*pdu);
1037 			}
1038 
1039 			/* Move to next chained PDU (it moves through chain that is in use
1040 			 * by LLL or is new one with updated advertising payload).
1041 			 */
1042 			*pdu_prev = pdu_chained;
1043 			pdu_chained = lll_adv_pdu_linked_next_get(*pdu_prev);
1044 		}
1045 	}
1046 
1047 	return BT_HCI_ERR_SUCCESS;
1048 }
1049 #endif /* (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1) */
1050 
1051 /*
1052  * @brief Function removes content of cte_info field from periodic advertising PDUs.
1053  *
1054  * @param adv            Pointer to periodic advertising set.
1055  * @param df_cfg         Pointer to direction finding configuration
1056  * @param[out] ter_idx   Pointer used to return index of allocated or updated PDU.
1057  *                       Index is required for scheduling the PDU for transmission in LLL.
1058  * @param[out] first_pdu Pointer to return address of first PDU in a chain
1059  *
1060  * @return Zero in case of success, other value in case of failure.
1061  */
cte_info_clear(struct ll_adv_set * adv,struct lll_df_adv_cfg * df_cfg,uint8_t * ter_idx,struct pdu_adv ** first_pdu)1062 static uint8_t cte_info_clear(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_cfg,
1063 			      uint8_t *ter_idx, struct pdu_adv **first_pdu)
1064 {
1065 	void *extra_data_prev, *extra_data;
1066 	struct pdu_adv *pdu_prev, *pdu;
1067 	struct lll_adv_sync *lll_sync;
1068 	uint8_t pdu_rem_field_flags;
1069 	uint8_t err;
1070 
1071 	lll_sync = adv->lll.sync;
1072 
1073 	/* NOTE: ULL_ADV_PDU_EXTRA_DATA_ALLOC_NEVER is just information that extra_data
1074 	 * should be removed in case of this call ull_adv_sync_pdu_alloc.
1075 	 */
1076 	extra_data_prev = NULL;
1077 	extra_data = NULL;
1078 	err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_NEVER, &pdu_prev, &pdu,
1079 				     &extra_data_prev, &extra_data, ter_idx);
1080 	if (err != BT_HCI_ERR_SUCCESS) {
1081 		return err;
1082 	}
1083 
1084 	if (extra_data_prev && extra_data) {
1085 		ull_adv_sync_extra_data_set_clear(extra_data_prev, extra_data, 0,
1086 						  ULL_ADV_PDU_HDR_FIELD_CTE_INFO, NULL);
1087 	}
1088 
1089 	*first_pdu = pdu;
1090 
1091 	pdu_rem_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
1092 
1093 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
1094 	err = rem_cte_info_from_per_adv_chain(lll_sync, &pdu_prev, &pdu);
1095 	if (err != BT_HCI_ERR_SUCCESS) {
1096 		return err;
1097 	}
1098 
1099 	/* Update last PDU in a chain. It may not have aux_ptr.
1100 	 * NOTE: If there is no AuxPtr flag in the PDU, attempt to remove it does not harm.
1101 	 */
1102 	pdu_rem_field_flags |= ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
1103 #endif /* CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1 */
1104 
1105 	err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu, 0, pdu_rem_field_flags, NULL);
1106 	if (err != BT_HCI_ERR_SUCCESS) {
1107 		/* TODO: return here leaves periodic advertising chain in an inconsistent state.
1108 		 * Add gracefull return or assert.
1109 		 */
1110 		return err;
1111 	}
1112 
1113 	return BT_HCI_ERR_SUCCESS;
1114 }
1115 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
1116 
1117 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_TX)
1118 /* @brief Function sets CTE transmission parameters for a connection.
1119  *
1120  * @param handle             Connection handle.
1121  * @param cte_types          Bitfield holding information about
1122  *                           allowed CTE types.
1123  * @param switch_pattern_len Number of antenna ids in switch pattern.
1124  * @param ant_id             Array of antenna identifiers.
1125  *
1126  * @return Status of command completion.
1127  */
ll_df_set_conn_cte_tx_params(uint16_t handle,uint8_t cte_types,uint8_t switch_pattern_len,const uint8_t * ant_ids)1128 uint8_t ll_df_set_conn_cte_tx_params(uint16_t handle, uint8_t cte_types, uint8_t switch_pattern_len,
1129 				     const uint8_t *ant_ids)
1130 {
1131 	struct lll_df_conn_tx_cfg *df_tx_cfg;
1132 	struct ll_conn *conn;
1133 
1134 	conn = ll_connected_get(handle);
1135 	if (!conn) {
1136 		return BT_HCI_ERR_UNKNOWN_CONN_ID;
1137 	}
1138 
1139 	df_tx_cfg = &conn->lll.df_tx_cfg;
1140 
1141 	if (df_tx_cfg->cte_rsp_en) {
1142 		return BT_HCI_ERR_CMD_DISALLOWED;
1143 	}
1144 
1145 	/* Bits other than representing AoA, AoD 1us, AoD 2us are RFU */
1146 	if (cte_types == 0U ||
1147 	    ((cte_types & (~(uint8_t)(BT_HCI_LE_AOA_CTE_RSP | BT_HCI_LE_AOD_CTE_RSP_1US |
1148 				      BT_HCI_LE_AOD_CTE_RSP_2US))) != 0U)) {
1149 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1150 	}
1151 
1152 	if (!IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX)) {
1153 		if (cte_types & BT_HCI_LE_AOD_CTE_RSP_2US) {
1154 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1155 		}
1156 
1157 		if ((cte_types & BT_HCI_LE_AOD_CTE_RSP_1US) &&
1158 		    !IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)) {
1159 			return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1160 		}
1161 	}
1162 
1163 	/* Check antenna switching pattern only whether CTE TX in AoD mode is allowed */
1164 	if (((cte_types & BT_HCI_LE_AOD_CTE_RSP_1US) || (cte_types & BT_HCI_LE_AOD_CTE_RSP_2US)) &&
1165 	    (switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
1166 	     switch_pattern_len > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN || !ant_ids)) {
1167 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1168 	}
1169 
1170 	(void)memcpy(df_tx_cfg->ant_ids, ant_ids, switch_pattern_len);
1171 	df_tx_cfg->ant_sw_len = switch_pattern_len;
1172 
1173 	df_tx_cfg->cte_types_allowed = cte_types;
1174 	df_tx_cfg->is_initialized = 1U;
1175 
1176 	return BT_HCI_ERR_SUCCESS;
1177 }
1178 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */
1179 
1180 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
1181 /**
1182  * @brief Function sets CTE reception parameters for a connection.
1183  *
1184  * @note: The CTE may not be send/received with PHY CODED. The BT Core 5.3 specification does not
1185  *        mention special handling of CTE receive and sampling while the functionality is enabled
1186  *        for a connection that currently uses PHY CODED. Enable of CTE receive for a PHY CODED
1187  *        will introduce complications for TISF maintenance by software switch. To avoid that
1188  *        the lower link layer will enable the functionality when connection uses PHY UNCODED only.
1189  *
1190  * @param handle             Connection handle.
1191  * @param sampling_enable    Enable or disable CTE RX. When the parameter is set to false,
1192  *                           @p slot_durations, @p switch_pattern_len and @ant_ids are ignored.
1193  * @param slot_durations     Switching and sampling slot durations for AoA mode.
1194  * @param switch_pattern_len Number of antenna ids in switch pattern.
1195  * @param ant_ids            Array of antenna identifiers.
1196  *
1197  * @return HCI status of command completion.
1198  */
ll_df_set_conn_cte_rx_params(uint16_t handle,uint8_t sampling_enable,uint8_t slot_durations,uint8_t switch_pattern_len,const uint8_t * ant_ids)1199 uint8_t ll_df_set_conn_cte_rx_params(uint16_t handle, uint8_t sampling_enable,
1200 				     uint8_t slot_durations, uint8_t switch_pattern_len,
1201 				     const uint8_t *ant_ids)
1202 {
1203 	struct lll_df_conn_rx_params *params_rx;
1204 	struct dbuf_hdr *params_buf_hdr;
1205 	struct lll_df_conn_rx_cfg *cfg_rx;
1206 	struct ll_conn *conn;
1207 	uint8_t params_idx;
1208 
1209 	conn = ll_connected_get(handle);
1210 	if (!conn) {
1211 		return BT_HCI_ERR_UNKNOWN_CONN_ID;
1212 	}
1213 
1214 	cfg_rx = &conn->lll.df_rx_cfg;
1215 	/* This is an information for HCI_LE_Connection_CTE_Request_Enable that
1216 	 * HCI_LE_Set_Connection_CTE_Receive_Parameters was called at least once.
1217 	 */
1218 	cfg_rx->is_initialized = 1U;
1219 	params_buf_hdr = &cfg_rx->hdr;
1220 
1221 	params_rx = dbuf_alloc(params_buf_hdr, &params_idx);
1222 
1223 	if (!sampling_enable) {
1224 		params_rx->is_enabled = false;
1225 	} else {
1226 		/* According to Core 5.3 Vol 4, Part E, section 7.8.83 slot_durations,
1227 		 * switch_pattern_len and ant_ids are used only for AoA and do not affect
1228 		 * reception of AoD CTE. If AoA is not supported relax command validation
1229 		 * to improve interoperability with different Host implementations.
1230 		 */
1231 		if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)) {
1232 			if (!((IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US) &&
1233 			       slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US) ||
1234 			      slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US)) {
1235 				return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1236 			}
1237 
1238 			if (switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
1239 			    switch_pattern_len > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN || !ant_ids) {
1240 				return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1241 			}
1242 		}
1243 
1244 		params_rx->is_enabled = true;
1245 		params_rx->slot_durations = slot_durations;
1246 		(void)memcpy(params_rx->ant_ids, ant_ids, switch_pattern_len);
1247 		params_rx->ant_sw_len = switch_pattern_len;
1248 	}
1249 
1250 	dbuf_enqueue(params_buf_hdr, params_idx);
1251 
1252 	return BT_HCI_ERR_SUCCESS;
1253 }
1254 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
1255 
1256 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
df_conn_cte_req_disable(void * param)1257 static void df_conn_cte_req_disable(void *param)
1258 {
1259 	k_sem_give(param);
1260 }
1261 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
1262 
1263 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
1264 /* @brief Function enables or disables CTE request control procedure for a connection.
1265  *
1266  * The procedure may be enabled in two modes:
1267  * - single-shot, it is autmatically disabled when the occurrence finishes.
1268  * - periodic, it is executed periodically until disabled, connection is lost or PHY is changed
1269  *   to the one that does not support CTE.
1270  *
1271  * @param handle               Connection handle.
1272  * @param enable               Enable or disable CTE request. When the parameter is set to false
1273  *                             @p cte_request_interval, @requested_cte_length and
1274  *                             @p requested_cte_type are ignored.
1275  * @param cte_request_interval Value zero enables single-shot mode. Other values enable periodic
1276  *                             mode. In periodic mode, the value is a number of connection envets
1277  *                             the procedure is executed. The value may not be lower than
1278  *                             connection peer latency.
1279  * @param requested_cte_length Minimum value of CTE length requested from peer.
1280  * @param requested_cte_type   Type of CTE requested from peer.
1281  *
1282  * @return HCI Status of command completion.
1283  */
ll_df_set_conn_cte_req_enable(uint16_t handle,uint8_t enable,uint16_t cte_request_interval,uint8_t requested_cte_length,uint8_t requested_cte_type)1284 uint8_t ll_df_set_conn_cte_req_enable(uint16_t handle, uint8_t enable,
1285 				      uint16_t cte_request_interval, uint8_t requested_cte_length,
1286 				      uint8_t requested_cte_type)
1287 {
1288 	struct ll_conn *conn;
1289 
1290 	conn = ll_connected_get(handle);
1291 	if (!conn) {
1292 		return BT_HCI_ERR_UNKNOWN_CONN_ID;
1293 	}
1294 
1295 	if (!enable) {
1296 		ull_cp_cte_req_set_disable(conn);
1297 
1298 		return BT_HCI_ERR_SUCCESS;
1299 	}
1300 
1301 	if (!conn->lll.df_rx_cfg.is_initialized) {
1302 		return BT_HCI_ERR_CMD_DISALLOWED;
1303 	}
1304 
1305 	if (conn->llcp.cte_req.is_enabled) {
1306 		return BT_HCI_ERR_CMD_DISALLOWED;
1307 	}
1308 
1309 #if defined(CONFIG_BT_CTLR_PHY)
1310 	/* CTE request may be enabled only in case the receiver PHY is not CODED */
1311 	if (conn->lll.phy_rx == PHY_CODED) {
1312 		return BT_HCI_ERR_CMD_DISALLOWED;
1313 	}
1314 #endif /* CONFIG_BT_CTLR_PHY */
1315 
1316 	if (cte_request_interval != 0 && cte_request_interval < conn->lll.latency) {
1317 		return BT_HCI_ERR_CMD_DISALLOWED;
1318 	}
1319 
1320 	if (requested_cte_length < BT_HCI_LE_CTE_LEN_MIN ||
1321 	    requested_cte_length > BT_HCI_LE_CTE_LEN_MAX) {
1322 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1323 	}
1324 
1325 	if (requested_cte_type != BT_HCI_LE_AOA_CTE &&
1326 	    requested_cte_type != BT_HCI_LE_AOD_CTE_1US &&
1327 	    requested_cte_type != BT_HCI_LE_AOD_CTE_2US) {
1328 		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1329 	}
1330 
1331 	conn->llcp.cte_req.is_enabled = 1U;
1332 	conn->llcp.cte_req.req_interval = cte_request_interval;
1333 	conn->llcp.cte_req.cte_type = requested_cte_type;
1334 	conn->llcp.cte_req.min_cte_len = requested_cte_length;
1335 
1336 	return ull_cp_cte_req(conn, requested_cte_length, requested_cte_type);
1337 }
1338 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
1339 
1340 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
1341 /**
1342  * @brief Function enables or disables CTE response control procedure for a connection.
1343  *
1344  * @param handle Connection handle.
1345  * @param enable Enable or disable CTE response.
1346  *
1347  * @return HCI Status of command completion.
1348  */
ll_df_set_conn_cte_rsp_enable(uint16_t handle,uint8_t enable)1349 uint8_t ll_df_set_conn_cte_rsp_enable(uint16_t handle, uint8_t enable)
1350 {
1351 	struct ll_conn *conn;
1352 
1353 	conn = ll_connected_get(handle);
1354 	if (!conn) {
1355 		return BT_HCI_ERR_UNKNOWN_CONN_ID;
1356 	}
1357 
1358 	if (enable) {
1359 		if (!conn->lll.df_tx_cfg.is_initialized) {
1360 			return BT_HCI_ERR_CMD_DISALLOWED;
1361 		}
1362 
1363 #if defined(CONFIG_BT_CTLR_PHY)
1364 		/* CTE may not be send over CODED PHY */
1365 		if (conn->lll.phy_tx == PHY_CODED) {
1366 			return BT_HCI_ERR_CMD_DISALLOWED;
1367 		}
1368 #endif /* CONFIG_BT_CTLR_PHY */
1369 		conn->lll.df_tx_cfg.cte_rsp_en = 1U;
1370 
1371 		ull_cp_cte_rsp_enable(conn, enable, LLL_DF_MAX_CTE_LEN,
1372 				conn->lll.df_tx_cfg.cte_types_allowed);
1373 	} else {
1374 		conn->lll.df_tx_cfg.cte_rsp_en = false;
1375 
1376 		if (conn->llcp.cte_rsp.is_active) {
1377 			struct k_sem sem;
1378 
1379 			k_sem_init(&sem, 0U, 1U);
1380 			conn->llcp.cte_rsp.disable_param = &sem;
1381 			conn->llcp.cte_rsp.disable_cb = df_conn_cte_req_disable;
1382 
1383 			if (!conn->llcp.cte_rsp.is_active) {
1384 				k_sem_take(&sem, K_FOREVER);
1385 			}
1386 		}
1387 	}
1388 
1389 	return BT_HCI_ERR_SUCCESS;
1390 }
1391 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
1392 
1393 /* @brief Function provides information about Direction Finding
1394  *        antennas switching and sampling related settings.
1395  *
1396  * @param[out]switch_sample_rates       Pointer to store available antennas
1397  *                                      switch-sampling configurations.
1398  * @param[out]num_ant                   Pointer to store number of available
1399  *                                      antennas.
1400  * @param[out]max_switch_pattern_len    Pointer to store maximum number of
1401  *                                      antennas ids in switch pattern.
1402  * @param[out]max_cte_len               Pointer to store maximum length of CTE
1403  *                                      in [8us] units.
1404  */
ll_df_read_ant_inf(uint8_t * switch_sample_rates,uint8_t * num_ant,uint8_t * max_switch_pattern_len,uint8_t * max_cte_len)1405 void ll_df_read_ant_inf(uint8_t *switch_sample_rates, uint8_t *num_ant,
1406 			uint8_t *max_switch_pattern_len, uint8_t *max_cte_len)
1407 {
1408 	*switch_sample_rates = 0;
1409 	if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) &&
1410 	    IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)) {
1411 		*switch_sample_rates |= DF_AOD_1US_TX;
1412 	}
1413 
1414 	if (IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX) &&
1415 	    IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US)) {
1416 		*switch_sample_rates |= DF_AOD_1US_RX;
1417 	}
1418 
1419 	if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX) &&
1420 	    IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US)) {
1421 		*switch_sample_rates |= DF_AOA_1US;
1422 	}
1423 
1424 	*max_switch_pattern_len = BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN;
1425 	*num_ant = lll_df_ant_num_get();
1426 	*max_cte_len = LLL_DF_MAX_CTE_LEN;
1427 }
1428