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
864 /* Note: ULL_ADV_PDU_EXTRA_DATA_ALLOC_ALWAYS is just information that extra_data
865 * is required in case of this ull_adv_sync_pdu_alloc.
866 */
867 err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_ALWAYS, &pdu_prev, &pdu,
868 NULL, &extra_data, ter_idx);
869 if (err != BT_HCI_ERR_SUCCESS) {
870 return err;
871 }
872
873 ull_adv_sync_extra_data_set_clear(NULL, extra_data, ULL_ADV_PDU_HDR_FIELD_CTE_INFO, 0,
874 df_cfg);
875
876 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
877 if (df_cfg->cte_count > 1) {
878 pdu_add_field_flags =
879 ULL_ADV_PDU_HDR_FIELD_CTE_INFO | ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
880 } else
881 #endif /* CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1 */
882 {
883 pdu_add_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
884 }
885
886 (void)memcpy(&hdr_data[ULL_ADV_HDR_DATA_CTE_INFO_OFFSET],
887 &cte_info, sizeof(cte_info));
888
889 err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu, pdu_add_field_flags, 0,
890 hdr_data);
891 if (err != BT_HCI_ERR_SUCCESS) {
892 return err;
893 }
894
895 *first_pdu = pdu;
896
897 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
898 if (df_cfg->cte_count > 1) {
899 struct pdu_adv_aux_ptr *aux_ptr;
900 uint32_t offs_us;
901
902 (void)memcpy(&aux_ptr,
903 &hdr_data[ULL_ADV_HDR_DATA_CTE_INFO_SIZE +
904 ULL_ADV_HDR_DATA_LEN_SIZE],
905 sizeof(aux_ptr));
906
907 /* Fill the aux offset in the PDU */
908 offs_us = PDU_AC_US(pdu->len, adv->lll.phy_s,
909 adv->lll.phy_flags) +
910 EVENT_SYNC_B2B_MAFS_US;
911 offs_us += CTE_LEN_US(cte_info.time);
912 ull_adv_aux_ptr_fill(aux_ptr, offs_us, adv->lll.phy_s);
913 }
914
915 err = per_adv_chain_cte_info_set(lll_sync, pdu_prev, pdu, df_cfg->cte_count, &cte_info);
916 if (err != BT_HCI_ERR_SUCCESS) {
917 return err;
918 }
919 #endif /* CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1 */
920
921 return BT_HCI_ERR_SUCCESS;
922 }
923
924 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
pdu_ext_adv_is_empty_without_cte(const struct pdu_adv * pdu)925 static bool pdu_ext_adv_is_empty_without_cte(const struct pdu_adv *pdu)
926 {
927 if (pdu->len != PDU_AC_PAYLOAD_SIZE_MIN) {
928 const struct pdu_adv_ext_hdr *ext_hdr;
929 uint8_t size_rem = 0;
930
931 if ((pdu->adv_ext_ind.ext_hdr_len + PDU_AC_EXT_HEADER_SIZE_MIN) != pdu->len) {
932 /* There are adv. data in PDU */
933 return false;
934 }
935
936 /* Check size of the ext. header without cte_info and aux_ptr. If that is minimum
937 * extended PDU size then the PDU was allocated to transport CTE only.
938 */
939 ext_hdr = &pdu->adv_ext_ind.ext_hdr;
940
941 if (ext_hdr->cte_info) {
942 size_rem += sizeof(struct pdu_cte_info);
943 }
944 if (ext_hdr->aux_ptr) {
945 size_rem += sizeof(struct pdu_adv_aux_ptr);
946 }
947 if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) && ext_hdr->adi) {
948 size_rem += sizeof(struct pdu_adv_adi);
949 }
950
951 if ((pdu->adv_ext_ind.ext_hdr_len - size_rem) != PDU_AC_EXT_HEADER_SIZE_MIN) {
952 return false;
953 }
954 }
955
956 return true;
957 }
958
959 /*
960 * @brief Function removes content of cte_info field in periodic advertising chain.
961 *
962 * The function removes cte_info from extended advertising header in all PDUs in periodic
963 * advertising chain. If particular PDU is empty (holds cte_info only) it will be removed from
964 * chain.
965 *
966 * @param[in] lll_sync Pointer to periodic advertising sync object.
967 * @param[in-out] pdu_prev Pointer to a PDU that is already in use by LLL or was updated with new
968 * PDU payload. Points to last PDU in a previous chain after return.
969 * @param[in-out] pdu Pointer to a new head of periodic advertising chain. The pointer may have
970 * the same value as @p pdu_prev, if payload of PDU pointerd by @p pdu_prev
971 * was already updated. Points to last PDU in a new chain after return.
972 *
973 * @return Zero in case of success, other value in case of failure.
974 */
rem_cte_info_from_per_adv_chain(struct lll_adv_sync * lll_sync,struct pdu_adv ** pdu_prev,struct pdu_adv ** pdu)975 static uint8_t rem_cte_info_from_per_adv_chain(struct lll_adv_sync *lll_sync,
976 struct pdu_adv **pdu_prev, struct pdu_adv **pdu)
977 {
978 struct pdu_adv *pdu_new, *pdu_chained;
979 uint8_t pdu_rem_field_flags;
980 bool new_chain;
981 uint8_t err;
982
983 pdu_rem_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
984
985 /* It is possible that the function is called after e.g. advertising data were updated.
986 * In such situation the function will run on already allocated chain. Do not allocate
987 * new chain then. Reuse already allocated PDUs and allocate new ones only if the chain
988 * was not updated yet.
989 */
990 new_chain = (*pdu_prev == *pdu ? false : true);
991
992 /* Get next PDU in a chain. Alway use pdu_prev because it points to actual
993 * former chain.
994 */
995 pdu_chained = lll_adv_pdu_linked_next_get(*pdu_prev);
996
997 /* Go through existing chain and remove CTE info. */
998 while (pdu_chained) {
999 if (pdu_ext_adv_is_empty_without_cte(pdu_chained)) {
1000 /* If there is an empty PDU then all remaining PDUs should be released. */
1001 if (!new_chain) {
1002 lll_adv_pdu_linked_release_all(pdu_chained);
1003
1004 /* Set new end of chain in PDUs linked list. If pdu differs from
1005 * prev_pdu then it is already end of a chain. If it doesn't differ,
1006 * then chain end is changed in right place by use of pdu_prev.
1007 * That makes sure there is no PDU released twice (here and when LLL
1008 * swaps PDU buffers).
1009 */
1010 lll_adv_pdu_linked_append(NULL, *pdu_prev);
1011 }
1012 pdu_chained = NULL;
1013 } else {
1014 /* Update one before pdu_chained */
1015 err = ull_adv_sync_pdu_set_clear(lll_sync, *pdu_prev, *pdu, 0,
1016 pdu_rem_field_flags, NULL);
1017 if (err != BT_HCI_ERR_SUCCESS) {
1018 /* TODO: return here leaves periodic advertising chain in
1019 * an inconsistent state. Add gracefull return or assert.
1020 */
1021 return err;
1022 }
1023
1024 /* Prepare for next iteration. Allocate new PDU or move to next one in
1025 * a chain.
1026 */
1027 if (new_chain) {
1028 pdu_new = lll_adv_pdu_alloc_pdu_adv();
1029 lll_adv_pdu_linked_append(pdu_new, *pdu);
1030 *pdu = pdu_new;
1031 } else {
1032 *pdu = lll_adv_pdu_linked_next_get(*pdu);
1033 }
1034
1035 /* Move to next chained PDU (it moves through chain that is in use
1036 * by LLL or is new one with updated advertising payload).
1037 */
1038 *pdu_prev = pdu_chained;
1039 pdu_chained = lll_adv_pdu_linked_next_get(*pdu_prev);
1040 }
1041 }
1042
1043 return BT_HCI_ERR_SUCCESS;
1044 }
1045 #endif /* (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1) */
1046
1047 /*
1048 * @brief Function removes content of cte_info field from periodic advertising PDUs.
1049 *
1050 * @param adv Pointer to periodic advertising set.
1051 * @param df_cfg Pointer to direction finding configuration
1052 * @param[out] ter_idx Pointer used to return index of allocated or updated PDU.
1053 * Index is required for scheduling the PDU for transmission in LLL.
1054 * @param[out] first_pdu Pointer to return address of first PDU in a chain
1055 *
1056 * @return Zero in case of success, other value in case of failure.
1057 */
cte_info_clear(struct ll_adv_set * adv,struct lll_df_adv_cfg * df_cfg,uint8_t * ter_idx,struct pdu_adv ** first_pdu)1058 static uint8_t cte_info_clear(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_cfg,
1059 uint8_t *ter_idx, struct pdu_adv **first_pdu)
1060 {
1061 void *extra_data_prev, *extra_data;
1062 struct pdu_adv *pdu_prev, *pdu;
1063 struct lll_adv_sync *lll_sync;
1064 uint8_t pdu_rem_field_flags;
1065 uint8_t err;
1066
1067 lll_sync = adv->lll.sync;
1068
1069 /* NOTE: ULL_ADV_PDU_EXTRA_DATA_ALLOC_NEVER is just information that extra_data
1070 * should be removed in case of this call ull_adv_sync_pdu_alloc.
1071 */
1072 err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_NEVER, &pdu_prev, &pdu,
1073 &extra_data_prev, &extra_data, ter_idx);
1074 if (err != BT_HCI_ERR_SUCCESS) {
1075 return err;
1076 }
1077
1078 if (extra_data) {
1079 ull_adv_sync_extra_data_set_clear(extra_data_prev, extra_data, 0,
1080 ULL_ADV_PDU_HDR_FIELD_CTE_INFO, NULL);
1081 }
1082
1083 *first_pdu = pdu;
1084
1085 pdu_rem_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
1086
1087 #if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
1088 err = rem_cte_info_from_per_adv_chain(lll_sync, &pdu_prev, &pdu);
1089 if (err != BT_HCI_ERR_SUCCESS) {
1090 return err;
1091 }
1092
1093 /* Update last PDU in a chain. It may not have aux_ptr.
1094 * NOTE: If there is no AuxPtr flag in the PDU, attempt to remove it does not harm.
1095 */
1096 pdu_rem_field_flags |= ULL_ADV_PDU_HDR_FIELD_AUX_PTR;
1097 #endif /* CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1 */
1098
1099 err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu, 0, pdu_rem_field_flags, NULL);
1100 if (err != BT_HCI_ERR_SUCCESS) {
1101 /* TODO: return here leaves periodic advertising chain in an inconsistent state.
1102 * Add gracefull return or assert.
1103 */
1104 return err;
1105 }
1106
1107 return BT_HCI_ERR_SUCCESS;
1108 }
1109 #endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
1110
1111 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_TX)
1112 /* @brief Function sets CTE transmission parameters for a connection.
1113 *
1114 * @param handle Connection handle.
1115 * @param cte_types Bitfield holding information about
1116 * allowed CTE types.
1117 * @param switch_pattern_len Number of antenna ids in switch pattern.
1118 * @param ant_id Array of antenna identifiers.
1119 *
1120 * @return Status of command completion.
1121 */
ll_df_set_conn_cte_tx_params(uint16_t handle,uint8_t cte_types,uint8_t switch_pattern_len,const uint8_t * ant_ids)1122 uint8_t ll_df_set_conn_cte_tx_params(uint16_t handle, uint8_t cte_types, uint8_t switch_pattern_len,
1123 const uint8_t *ant_ids)
1124 {
1125 struct lll_df_conn_tx_cfg *df_tx_cfg;
1126 struct ll_conn *conn;
1127
1128 conn = ll_connected_get(handle);
1129 if (!conn) {
1130 return BT_HCI_ERR_UNKNOWN_CONN_ID;
1131 }
1132
1133 df_tx_cfg = &conn->lll.df_tx_cfg;
1134
1135 if (df_tx_cfg->cte_rsp_en) {
1136 return BT_HCI_ERR_CMD_DISALLOWED;
1137 }
1138
1139 /* Bits other than representing AoA, AoD 1us, AoD 2us are RFU */
1140 if (cte_types == 0U ||
1141 ((cte_types & (~(uint8_t)(BT_HCI_LE_AOA_CTE_RSP | BT_HCI_LE_AOD_CTE_RSP_1US |
1142 BT_HCI_LE_AOD_CTE_RSP_2US))) != 0U)) {
1143 return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1144 }
1145
1146 if (!IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX)) {
1147 if (cte_types & BT_HCI_LE_AOD_CTE_RSP_2US) {
1148 return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1149 }
1150
1151 if ((cte_types & BT_HCI_LE_AOD_CTE_RSP_1US) &&
1152 !IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)) {
1153 return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1154 }
1155 }
1156
1157 /* Check antenna switching pattern only whether CTE TX in AoD mode is allowed */
1158 if (((cte_types & BT_HCI_LE_AOD_CTE_RSP_1US) || (cte_types & BT_HCI_LE_AOD_CTE_RSP_2US)) &&
1159 (switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
1160 switch_pattern_len > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN || !ant_ids)) {
1161 return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1162 }
1163
1164 (void)memcpy(df_tx_cfg->ant_ids, ant_ids, switch_pattern_len);
1165 df_tx_cfg->ant_sw_len = switch_pattern_len;
1166
1167 df_tx_cfg->cte_types_allowed = cte_types;
1168 df_tx_cfg->is_initialized = 1U;
1169
1170 return BT_HCI_ERR_SUCCESS;
1171 }
1172 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */
1173
1174 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
1175 /**
1176 * @brief Function sets CTE reception parameters for a connection.
1177 *
1178 * @note: The CTE may not be send/received with PHY CODED. The BT Core 5.3 specification does not
1179 * mention special handling of CTE receive and sampling while the functionality is enabled
1180 * for a connection that currently uses PHY CODED. Enable of CTE receive for a PHY CODED
1181 * will introduce complications for TISF maintenance by software switch. To avoid that
1182 * the lower link layer will enable the functionality when connection uses PHY UNCODED only.
1183 *
1184 * @param handle Connection handle.
1185 * @param sampling_enable Enable or disable CTE RX. When the parameter is set to false,
1186 * @p slot_durations, @p switch_pattern_len and @ant_ids are ignored.
1187 * @param slot_durations Switching and sampling slot durations for AoA mode.
1188 * @param switch_pattern_len Number of antenna ids in switch pattern.
1189 * @param ant_ids Array of antenna identifiers.
1190 *
1191 * @return HCI status of command completion.
1192 */
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)1193 uint8_t ll_df_set_conn_cte_rx_params(uint16_t handle, uint8_t sampling_enable,
1194 uint8_t slot_durations, uint8_t switch_pattern_len,
1195 const uint8_t *ant_ids)
1196 {
1197 struct lll_df_conn_rx_params *params_rx;
1198 struct dbuf_hdr *params_buf_hdr;
1199 struct lll_df_conn_rx_cfg *cfg_rx;
1200 struct ll_conn *conn;
1201 uint8_t params_idx;
1202
1203 conn = ll_connected_get(handle);
1204 if (!conn) {
1205 return BT_HCI_ERR_UNKNOWN_CONN_ID;
1206 }
1207
1208 cfg_rx = &conn->lll.df_rx_cfg;
1209 /* This is an information for HCI_LE_Connection_CTE_Request_Enable that
1210 * HCI_LE_Set_Connection_CTE_Receive_Parameters was called at least once.
1211 */
1212 cfg_rx->is_initialized = 1U;
1213 params_buf_hdr = &cfg_rx->hdr;
1214
1215 params_rx = dbuf_alloc(params_buf_hdr, ¶ms_idx);
1216
1217 if (!sampling_enable) {
1218 params_rx->is_enabled = false;
1219 } else {
1220 /* According to Core 5.3 Vol 4, Part E, section 7.8.83 slot_durations,
1221 * switch_pattern_len and ant_ids are used only for AoA and do not affect
1222 * reception of AoD CTE. If AoA is not supported relax command validation
1223 * to improve interoperability with different Host implementations.
1224 */
1225 if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)) {
1226 if (!((IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US) &&
1227 slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US) ||
1228 slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US)) {
1229 return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1230 }
1231
1232 if (switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
1233 switch_pattern_len > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN || !ant_ids) {
1234 return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1235 }
1236 }
1237
1238 params_rx->is_enabled = true;
1239 params_rx->slot_durations = slot_durations;
1240 (void)memcpy(params_rx->ant_ids, ant_ids, switch_pattern_len);
1241 params_rx->ant_sw_len = switch_pattern_len;
1242 }
1243
1244 dbuf_enqueue(params_buf_hdr, params_idx);
1245
1246 return BT_HCI_ERR_SUCCESS;
1247 }
1248 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
1249
1250 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
df_conn_cte_req_disable(void * param)1251 static void df_conn_cte_req_disable(void *param)
1252 {
1253 k_sem_give(param);
1254 }
1255 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
1256
1257 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
1258 /* @brief Function enables or disables CTE request control procedure for a connection.
1259 *
1260 * The procedure may be enabled in two modes:
1261 * - single-shot, it is autmatically disabled when the occurrence finishes.
1262 * - periodic, it is executed periodically until disabled, connection is lost or PHY is changed
1263 * to the one that does not support CTE.
1264 *
1265 * @param handle Connection handle.
1266 * @param enable Enable or disable CTE request. When the parameter is set to false
1267 * @p cte_request_interval, @requested_cte_length and
1268 * @p requested_cte_type are ignored.
1269 * @param cte_request_interval Value zero enables single-shot mode. Other values enable periodic
1270 * mode. In periodic mode, the value is a number of connection envets
1271 * the procedure is executed. The value may not be lower than
1272 * connection peer latency.
1273 * @param requested_cte_length Minimum value of CTE length requested from peer.
1274 * @param requested_cte_type Type of CTE requested from peer.
1275 *
1276 * @return HCI Status of command completion.
1277 */
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)1278 uint8_t ll_df_set_conn_cte_req_enable(uint16_t handle, uint8_t enable,
1279 uint16_t cte_request_interval, uint8_t requested_cte_length,
1280 uint8_t requested_cte_type)
1281 {
1282 struct ll_conn *conn;
1283
1284 conn = ll_connected_get(handle);
1285 if (!conn) {
1286 return BT_HCI_ERR_UNKNOWN_CONN_ID;
1287 }
1288
1289 if (!enable) {
1290 ull_cp_cte_req_set_disable(conn);
1291
1292 return BT_HCI_ERR_SUCCESS;
1293 }
1294
1295 if (!conn->lll.df_rx_cfg.is_initialized) {
1296 return BT_HCI_ERR_CMD_DISALLOWED;
1297 }
1298
1299 if (conn->llcp.cte_req.is_enabled) {
1300 return BT_HCI_ERR_CMD_DISALLOWED;
1301 }
1302
1303 #if defined(CONFIG_BT_CTLR_PHY)
1304 /* CTE request may be enabled only in case the receiver PHY is not CODED */
1305 if (conn->lll.phy_rx == PHY_CODED) {
1306 return BT_HCI_ERR_CMD_DISALLOWED;
1307 }
1308 #endif /* CONFIG_BT_CTLR_PHY */
1309
1310 if (cte_request_interval != 0 && cte_request_interval < conn->lll.latency) {
1311 return BT_HCI_ERR_CMD_DISALLOWED;
1312 }
1313
1314 if (requested_cte_length < BT_HCI_LE_CTE_LEN_MIN ||
1315 requested_cte_length > BT_HCI_LE_CTE_LEN_MAX) {
1316 return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1317 }
1318
1319 if (requested_cte_type != BT_HCI_LE_AOA_CTE &&
1320 requested_cte_type != BT_HCI_LE_AOD_CTE_1US &&
1321 requested_cte_type != BT_HCI_LE_AOD_CTE_2US) {
1322 return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
1323 }
1324
1325 conn->llcp.cte_req.is_enabled = 1U;
1326 conn->llcp.cte_req.req_interval = cte_request_interval;
1327 conn->llcp.cte_req.cte_type = requested_cte_type;
1328 conn->llcp.cte_req.min_cte_len = requested_cte_length;
1329
1330 return ull_cp_cte_req(conn, requested_cte_length, requested_cte_type);
1331 }
1332 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
1333
1334 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
1335 /**
1336 * @brief Function enables or disables CTE response control procedure for a connection.
1337 *
1338 * @param handle Connection handle.
1339 * @param enable Enable or disable CTE response.
1340 *
1341 * @return HCI Status of command completion.
1342 */
ll_df_set_conn_cte_rsp_enable(uint16_t handle,uint8_t enable)1343 uint8_t ll_df_set_conn_cte_rsp_enable(uint16_t handle, uint8_t enable)
1344 {
1345 struct ll_conn *conn;
1346
1347 conn = ll_connected_get(handle);
1348 if (!conn) {
1349 return BT_HCI_ERR_UNKNOWN_CONN_ID;
1350 }
1351
1352 if (enable) {
1353 if (!conn->lll.df_tx_cfg.is_initialized) {
1354 return BT_HCI_ERR_CMD_DISALLOWED;
1355 }
1356
1357 #if defined(CONFIG_BT_CTLR_PHY)
1358 /* CTE may not be send over CODED PHY */
1359 if (conn->lll.phy_tx == PHY_CODED) {
1360 return BT_HCI_ERR_CMD_DISALLOWED;
1361 }
1362 #endif /* CONFIG_BT_CTLR_PHY */
1363 conn->lll.df_tx_cfg.cte_rsp_en = 1U;
1364
1365 ull_cp_cte_rsp_enable(conn, enable, LLL_DF_MAX_CTE_LEN,
1366 conn->lll.df_tx_cfg.cte_types_allowed);
1367 } else {
1368 conn->lll.df_tx_cfg.cte_rsp_en = false;
1369
1370 if (conn->llcp.cte_rsp.is_active) {
1371 struct k_sem sem;
1372
1373 k_sem_init(&sem, 0U, 1U);
1374 conn->llcp.cte_rsp.disable_param = &sem;
1375 conn->llcp.cte_rsp.disable_cb = df_conn_cte_req_disable;
1376
1377 if (!conn->llcp.cte_rsp.is_active) {
1378 k_sem_take(&sem, K_FOREVER);
1379 }
1380 }
1381 }
1382
1383 return BT_HCI_ERR_SUCCESS;
1384 }
1385 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
1386
1387 /* @brief Function provides information about Direction Finding
1388 * antennas switching and sampling related settings.
1389 *
1390 * @param[out]switch_sample_rates Pointer to store available antennas
1391 * switch-sampling configurations.
1392 * @param[out]num_ant Pointer to store number of available
1393 * antennas.
1394 * @param[out]max_switch_pattern_len Pointer to store maximum number of
1395 * antennas ids in switch pattern.
1396 * @param[out]max_cte_len Pointer to store maximum length of CTE
1397 * in [8us] units.
1398 */
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)1399 void ll_df_read_ant_inf(uint8_t *switch_sample_rates, uint8_t *num_ant,
1400 uint8_t *max_switch_pattern_len, uint8_t *max_cte_len)
1401 {
1402 *switch_sample_rates = 0;
1403 if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) &&
1404 IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)) {
1405 *switch_sample_rates |= DF_AOD_1US_TX;
1406 }
1407
1408 if (IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX) &&
1409 IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US)) {
1410 *switch_sample_rates |= DF_AOD_1US_RX;
1411 }
1412
1413 if (IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX) &&
1414 IS_ENABLED(CONFIG_BT_CTLR_DF_CTE_RX_SAMPLE_1US)) {
1415 *switch_sample_rates |= DF_AOA_1US;
1416 }
1417
1418 *max_switch_pattern_len = BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN;
1419 *num_ant = lll_df_ant_num_get();
1420 *max_cte_len = LLL_DF_MAX_CTE_LEN;
1421 }
1422