1 /*
2 * Copyright (c) 2020-2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <errno.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <string.h>
10
11 #include <zephyr/autoconf.h>
12 #include <zephyr/bluetooth/bluetooth.h>
13 #include <zephyr/bluetooth/conn.h>
14 #include <zephyr/bluetooth/direction.h>
15 #include <zephyr/bluetooth/hci.h>
16 #include <zephyr/bluetooth/hci_types.h>
17 #include <zephyr/bluetooth/hci_vs.h>
18 #include <zephyr/bluetooth/l2cap.h>
19 #include <zephyr/logging/log.h>
20 #include <zephyr/net_buf.h>
21 #include <zephyr/sys/__assert.h>
22 #include <zephyr/sys/atomic.h>
23 #include <zephyr/sys/byteorder.h>
24 #include <zephyr/sys/check.h>
25
26 #include "hci_core.h"
27 #include "conn_internal.h"
28 #include "direction_internal.h"
29
30 LOG_MODULE_REGISTER(bt_df, CONFIG_BT_DF_LOG_LEVEL);
31
32 /* @brief Antenna information for LE Direction Finding */
33 struct bt_le_df_ant_info {
34 /* Bitfield holding optional switching and sampling rates */
35 uint8_t switch_sample_rates;
36 /* Available antennae number */
37 uint8_t num_ant;
38 /* Maximum supported antennae switching pattern length */
39 uint8_t max_switch_pattern_len;
40 /* Maximum length of CTE in 8[us] units */
41 uint8_t max_cte_len;
42 };
43
44 static struct bt_le_df_ant_info df_ant_info;
45 #if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
46 const static uint8_t df_dummy_switch_pattern[BT_HCI_LE_SWITCH_PATTERN_LEN_MIN] = { 0, 0 };
47 #endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */
48
49 #define DF_AOD_TX_1US_SUPPORT(supp) (supp & BT_HCI_LE_1US_AOD_TX)
50 #define DF_AOD_RX_1US_SUPPORT(supp) (supp & BT_HCI_LE_1US_AOD_RX)
51 #define DF_AOA_RX_1US_SUPPORT(supp) (supp & BT_HCI_LE_1US_AOA_RX)
52
53 #define DF_SAMPLING_ANTENNA_NUMBER_MIN 0x2
54
55 #if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
56 static bool valid_cte_rx_common_params(uint8_t cte_types, uint8_t slot_durations,
57 uint8_t num_ant_ids, const uint8_t *ant_ids);
58 #endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */
59
60 #if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
61 static bool valid_cl_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params);
62 static int
63 prepare_cl_cte_rx_enable_cmd_params(struct net_buf **buf, struct bt_le_per_adv_sync *sync,
64 const struct bt_df_per_adv_sync_cte_rx_param *params,
65 bool enable);
66 static int hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool enable,
67 const struct bt_df_per_adv_sync_cte_rx_param *params);
68 #endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
69
70 #if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
71 static int prepare_conn_cte_rx_enable_cmd_params(struct net_buf **buf, struct bt_conn *conn,
72 const struct bt_df_conn_cte_rx_param *params,
73 bool enable);
74 static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
75 const struct bt_df_conn_cte_rx_param *params);
76 #endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
77
get_hci_cte_type(enum bt_df_cte_type type)78 static uint8_t get_hci_cte_type(enum bt_df_cte_type type)
79 {
80 switch (type) {
81 case BT_DF_CTE_TYPE_AOA:
82 return BT_HCI_LE_AOA_CTE;
83 case BT_DF_CTE_TYPE_AOD_1US:
84 return BT_HCI_LE_AOD_CTE_1US;
85 case BT_DF_CTE_TYPE_AOD_2US:
86 return BT_HCI_LE_AOD_CTE_2US;
87 default:
88 LOG_ERR("Wrong CTE type");
89 return BT_HCI_LE_NO_CTE;
90 }
91 }
92
hci_df_set_cl_cte_tx_params(const struct bt_le_ext_adv * adv,const struct bt_df_adv_cte_tx_param * params)93 static int hci_df_set_cl_cte_tx_params(const struct bt_le_ext_adv *adv,
94 const struct bt_df_adv_cte_tx_param *params)
95 {
96 struct bt_hci_cp_le_set_cl_cte_tx_params *cp;
97 struct net_buf *buf;
98
99 /* If AoD is not enabled, ant_ids are ignored by controller:
100 * BT Core spec 5.2 Vol 4, Part E sec. 7.8.80.
101 */
102 if (params->cte_type == BT_DF_CTE_TYPE_AOD_1US ||
103 params->cte_type == BT_DF_CTE_TYPE_AOD_2US) {
104 if (!BT_FEAT_LE_ANT_SWITCH_TX_AOD(bt_dev.le.features)) {
105 return -EINVAL;
106 }
107
108 if (params->cte_type == BT_DF_CTE_TYPE_AOD_1US &&
109 !DF_AOD_TX_1US_SUPPORT(df_ant_info.switch_sample_rates)) {
110 return -EINVAL;
111 }
112
113 if (params->num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
114 params->num_ant_ids > BT_HCI_LE_SWITCH_PATTERN_LEN_MAX ||
115 !params->ant_ids) {
116 return -EINVAL;
117 }
118 } else if (params->cte_type != BT_DF_CTE_TYPE_AOA) {
119 return -EINVAL;
120 }
121
122 if (params->cte_len < BT_HCI_LE_CTE_LEN_MIN ||
123 params->cte_len > BT_HCI_LE_CTE_LEN_MAX) {
124 return -EINVAL;
125 }
126
127 if (params->cte_count < BT_HCI_LE_CTE_COUNT_MIN ||
128 params->cte_count > BT_HCI_LE_CTE_COUNT_MAX) {
129 return -EINVAL;
130 }
131
132 buf = bt_hci_cmd_alloc(K_FOREVER);
133 if (!buf) {
134 return -ENOBUFS;
135 }
136
137 cp = net_buf_add(buf, sizeof(*cp));
138 cp->handle = adv->handle;
139 cp->cte_len = params->cte_len;
140 cp->cte_type = get_hci_cte_type(params->cte_type);
141 cp->cte_count = params->cte_count;
142
143 if (params->num_ant_ids) {
144 uint8_t *dest_ant_ids = net_buf_add(buf, params->num_ant_ids);
145
146 memcpy(dest_ant_ids, params->ant_ids, params->num_ant_ids);
147 cp->switch_pattern_len = params->num_ant_ids;
148 } else {
149 cp->switch_pattern_len = 0;
150 }
151
152 return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CL_CTE_TX_PARAMS,
153 buf, NULL);
154 }
155
156 /* @brief Function provides information about DF antennae number and
157 * controller capabilities related with Constant Tone Extension.
158 *
159 * @param[out] switch_sample_rates Optional switching and sampling rates.
160 * @param[out] num_ant Antennae number.
161 * @param[out] max_switch_pattern_len Maximum supported antennae switching
162 * patterns length.
163 * @param[out] max_cte_len Maximum length of CTE in 8[us] units.
164 *
165 * @return Zero in case of success, other value in case of failure.
166 */
hci_df_read_ant_info(uint8_t * switch_sample_rates,uint8_t * num_ant,uint8_t * max_switch_pattern_len,uint8_t * max_cte_len)167 static int hci_df_read_ant_info(uint8_t *switch_sample_rates,
168 uint8_t *num_ant,
169 uint8_t *max_switch_pattern_len,
170 uint8_t *max_cte_len)
171 {
172 __ASSERT_NO_MSG(switch_sample_rates);
173 __ASSERT_NO_MSG(num_ant);
174 __ASSERT_NO_MSG(max_switch_pattern_len);
175 __ASSERT_NO_MSG(max_cte_len);
176
177 struct bt_hci_rp_le_read_ant_info *rp;
178 struct net_buf *rsp;
179 int err;
180
181 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_ANT_INFO, NULL, &rsp);
182 if (err) {
183 LOG_ERR("Failed to read antenna information");
184 return err;
185 }
186
187 rp = (void *)rsp->data;
188
189 LOG_DBG("DF: sw. sample rates: %x ant num: %u , max sw. pattern len: %u,"
190 "max CTE len %d",
191 rp->switch_sample_rates, rp->num_ant, rp->max_switch_pattern_len, rp->max_cte_len);
192
193 *switch_sample_rates = rp->switch_sample_rates;
194 *num_ant = rp->num_ant;
195 *max_switch_pattern_len = rp->max_switch_pattern_len;
196 *max_cte_len = rp->max_cte_len;
197
198 net_buf_unref(rsp);
199
200 return 0;
201 }
202
203 /* @brief Function handles send of HCI command to enable or disables CTE
204 * transmission for given advertising set.
205 *
206 * @param[in] adv Pointer to advertising set
207 * @param[in] enable Enable or disable CTE TX
208 *
209 * @return Zero in case of success, other value in case of failure.
210 */
hci_df_set_adv_cte_tx_enable(struct bt_le_ext_adv * adv,bool enable)211 static int hci_df_set_adv_cte_tx_enable(struct bt_le_ext_adv *adv,
212 bool enable)
213 {
214 struct bt_hci_cp_le_set_cl_cte_tx_enable *cp;
215 struct bt_hci_cmd_state_set state;
216 struct net_buf *buf;
217
218 buf = bt_hci_cmd_alloc(K_FOREVER);
219 if (!buf) {
220 return -ENOBUFS;
221 }
222
223 cp = net_buf_add(buf, sizeof(*cp));
224 (void)memset(cp, 0, sizeof(*cp));
225
226 cp->handle = adv->handle;
227 cp->cte_enable = enable ? 1 : 0;
228
229 bt_hci_cmd_state_set_init(buf, &state, adv->flags, BT_PER_ADV_CTE_ENABLED,
230 enable);
231
232 return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CL_CTE_TX_ENABLE,
233 buf, NULL);
234 }
235
236 #if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
valid_cte_rx_common_params(uint8_t cte_types,uint8_t slot_durations,uint8_t num_ant_ids,const uint8_t * ant_ids)237 static bool valid_cte_rx_common_params(uint8_t cte_types, uint8_t slot_durations,
238 uint8_t num_ant_ids, const uint8_t *ant_ids)
239 {
240 if (!(cte_types & BT_DF_CTE_TYPE_ALL)) {
241 return false;
242 }
243
244 if (cte_types & BT_DF_CTE_TYPE_AOA) {
245 if (df_ant_info.num_ant < DF_SAMPLING_ANTENNA_NUMBER_MIN ||
246 !BT_FEAT_LE_ANT_SWITCH_RX_AOA(bt_dev.le.features)) {
247 return false;
248 }
249
250 if (!(slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US ||
251 (slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US &&
252 DF_AOA_RX_1US_SUPPORT(df_ant_info.switch_sample_rates)))) {
253 return false;
254 }
255
256 if (num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
257 num_ant_ids > df_ant_info.max_switch_pattern_len || !ant_ids) {
258 return false;
259 }
260 }
261
262 return true;
263 }
264 #endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */
265
266 #if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
valid_cl_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param * params)267 static bool valid_cl_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params)
268 {
269 if (params->max_cte_count > BT_HCI_LE_SAMPLE_CTE_COUNT_MAX) {
270 return false;
271 }
272
273 if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
274 return valid_cte_rx_common_params(params->cte_types, params->slot_durations,
275 params->num_ant_ids, params->ant_ids);
276 }
277
278 return true;
279 }
280
281 static int
prepare_cl_cte_rx_enable_cmd_params(struct net_buf ** buf,struct bt_le_per_adv_sync * sync,const struct bt_df_per_adv_sync_cte_rx_param * params,bool enable)282 prepare_cl_cte_rx_enable_cmd_params(struct net_buf **buf, struct bt_le_per_adv_sync *sync,
283 const struct bt_df_per_adv_sync_cte_rx_param *params,
284 bool enable)
285 {
286 struct bt_hci_cp_le_set_cl_cte_sampling_enable *cp;
287 uint8_t switch_pattern_len;
288
289 if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
290 switch_pattern_len = params->num_ant_ids;
291 } else {
292 switch_pattern_len = ARRAY_SIZE(df_dummy_switch_pattern);
293 }
294
295 /* If CTE Rx is enabled, command parameters total length must include
296 * antenna ids, so command size if extended by num_and_ids.
297 */
298 *buf = bt_hci_cmd_alloc(K_FOREVER);
299 if (!(*buf)) {
300 return -ENOBUFS;
301 }
302
303 cp = net_buf_add(*buf, sizeof(*cp));
304 (void)memset(cp, 0, sizeof(*cp));
305
306 cp->sync_handle = sys_cpu_to_le16(sync->handle);
307 cp->sampling_enable = enable ? 1 : 0;
308
309 if (enable) {
310 const uint8_t *ant_ids;
311 uint8_t *dest_ant_ids;
312
313 cp->max_sampled_cte = params->max_cte_count;
314
315 if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
316 cp->slot_durations = params->slot_durations;
317 ant_ids = params->ant_ids;
318 } else {
319 /* Those values are put here due to constraints from HCI command
320 * specification: Bluetooth Core Spec. 5.3 Vol 4,Part E, sec 7.8.82.
321 * There is no right way to successfully send the command to enable CTE
322 * receive for AoD mode (e.g. device equipped with single antenna).
323 */
324 cp->slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US;
325 ant_ids = &df_dummy_switch_pattern[0];
326 }
327
328 cp->switch_pattern_len = switch_pattern_len;
329 dest_ant_ids = net_buf_add(*buf, cp->switch_pattern_len);
330 memcpy(dest_ant_ids, ant_ids, cp->switch_pattern_len);
331 }
332
333 return 0;
334 }
335
hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync * sync,bool enable,const struct bt_df_per_adv_sync_cte_rx_param * params)336 static int hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool enable,
337 const struct bt_df_per_adv_sync_cte_rx_param *params)
338 {
339 struct bt_hci_rp_le_set_cl_cte_sampling_enable *rp;
340 struct bt_hci_cmd_state_set state;
341 struct net_buf *buf, *rsp;
342 int err;
343
344 if (enable) {
345 if (!valid_cl_cte_rx_params(params)) {
346 return -EINVAL;
347 }
348 }
349
350 err = prepare_cl_cte_rx_enable_cmd_params(&buf, sync, params, enable);
351 if (err) {
352 return err;
353 }
354
355 bt_hci_cmd_state_set_init(buf, &state, sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED, enable);
356
357 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CL_CTE_SAMPLING_ENABLE, buf, &rsp);
358 if (err) {
359 return err;
360 }
361
362 rp = (void *)rsp->data;
363 if (sync->handle != sys_le16_to_cpu(rp->sync_handle)) {
364 err = -EIO;
365 } else {
366 sync->cte_types = (enable ? params->cte_types : 0);
367 }
368
369 net_buf_unref(rsp);
370
371 return err;
372 }
373
hci_df_prepare_connectionless_iq_report(struct net_buf * buf,struct bt_df_per_adv_sync_iq_samples_report * report,struct bt_le_per_adv_sync ** per_adv_sync_to_report)374 int hci_df_prepare_connectionless_iq_report(struct net_buf *buf,
375 struct bt_df_per_adv_sync_iq_samples_report *report,
376 struct bt_le_per_adv_sync **per_adv_sync_to_report)
377 {
378 struct bt_hci_evt_le_connectionless_iq_report *evt;
379 struct bt_le_per_adv_sync *per_adv_sync;
380
381 if (buf->len < sizeof(*evt)) {
382 LOG_ERR("Unexpected end of buffer");
383 return -EINVAL;
384 }
385
386 evt = net_buf_pull_mem(buf, sizeof(*evt));
387
388 per_adv_sync = bt_hci_per_adv_sync_lookup_handle(sys_le16_to_cpu(evt->sync_handle));
389
390 if (!per_adv_sync) {
391 LOG_ERR("Unknown handle 0x%04X for iq samples report",
392 sys_le16_to_cpu(evt->sync_handle));
393 return -EINVAL;
394 }
395
396 if (!atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED)) {
397 LOG_ERR("Received PA CTE report when CTE receive disabled");
398 return -EINVAL;
399 }
400
401 if (!(per_adv_sync->cte_types & BIT(evt->cte_type))) {
402 LOG_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
403 return -EINVAL;
404 }
405
406 report->chan_idx = evt->chan_idx;
407 report->rssi = sys_le16_to_cpu(evt->rssi);
408 report->rssi_ant_id = evt->rssi_ant_id;
409 report->cte_type = BIT(evt->cte_type);
410 report->packet_status = evt->packet_status;
411 report->slot_durations = evt->slot_durations;
412 report->per_evt_counter = sys_le16_to_cpu(evt->per_evt_counter);
413 report->sample_type = BT_DF_IQ_SAMPLE_8_BITS_INT;
414 report->sample_count = evt->sample_count;
415 report->sample = &evt->sample[0];
416
417 *per_adv_sync_to_report = per_adv_sync;
418
419 return 0;
420 }
421
hci_df_vs_prepare_connectionless_iq_report(struct net_buf * buf,struct bt_df_per_adv_sync_iq_samples_report * report,struct bt_le_per_adv_sync ** per_adv_sync_to_report)422 int hci_df_vs_prepare_connectionless_iq_report(struct net_buf *buf,
423 struct bt_df_per_adv_sync_iq_samples_report *report,
424 struct bt_le_per_adv_sync **per_adv_sync_to_report)
425 {
426 struct bt_hci_evt_vs_le_connectionless_iq_report *evt;
427 struct bt_le_per_adv_sync *per_adv_sync;
428
429 if (buf->len < sizeof(*evt)) {
430 LOG_ERR("Unexpected end of buffer");
431 return -EINVAL;
432 }
433
434 evt = net_buf_pull_mem(buf, sizeof(*evt));
435
436 per_adv_sync = bt_hci_per_adv_sync_lookup_handle(sys_le16_to_cpu(evt->sync_handle));
437
438 if (!per_adv_sync) {
439 LOG_ERR("Unknown handle 0x%04X for iq samples report",
440 sys_le16_to_cpu(evt->sync_handle));
441 return -EINVAL;
442 }
443
444 if (!atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED)) {
445 LOG_ERR("Received PA CTE report when CTE receive disabled");
446 return -EINVAL;
447 }
448
449 if (!(per_adv_sync->cte_types & BIT(evt->cte_type))) {
450 LOG_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
451 return -EINVAL;
452 }
453
454 report->chan_idx = evt->chan_idx;
455 report->rssi = sys_le16_to_cpu(evt->rssi);
456 report->rssi_ant_id = evt->rssi_ant_id;
457 report->cte_type = BIT(evt->cte_type);
458 report->packet_status = evt->packet_status;
459 report->slot_durations = evt->slot_durations;
460 report->per_evt_counter = sys_le16_to_cpu(evt->per_evt_counter);
461 report->sample_count = evt->sample_count;
462 report->sample_type = BT_DF_IQ_SAMPLE_16_BITS_INT;
463 report->sample16 = &evt->sample[0];
464
465 *per_adv_sync_to_report = per_adv_sync;
466
467 return 0;
468 }
469 #endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
470
471 #if defined(CONFIG_BT_DF_CONNECTION_CTE_TX)
valid_conn_cte_tx_params(const struct bt_df_conn_cte_tx_param * params)472 static bool valid_conn_cte_tx_params(const struct bt_df_conn_cte_tx_param *params)
473 {
474 if (!(params->cte_types & BT_DF_CTE_TYPE_ALL)) {
475 return false;
476 }
477
478 /* If AoD is not enabled, ant_ids are ignored by controller:
479 * BT Core spec 5.2 Vol 4, Part E sec. 7.8.84.
480 */
481 if ((params->cte_types & BT_DF_CTE_TYPE_AOD_1US ||
482 params->cte_types & BT_DF_CTE_TYPE_AOD_1US) &&
483 (params->num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
484 params->num_ant_ids > BT_HCI_LE_SWITCH_PATTERN_LEN_MAX || !params->ant_ids ||
485 !BT_FEAT_LE_ANT_SWITCH_TX_AOD(bt_dev.le.features))) {
486 return false;
487 }
488
489 return true;
490 }
491
prepare_conn_cte_tx_params_cmd(struct net_buf * buf,const struct bt_conn * conn,const struct bt_df_conn_cte_tx_param * params)492 static void prepare_conn_cte_tx_params_cmd(struct net_buf *buf, const struct bt_conn *conn,
493 const struct bt_df_conn_cte_tx_param *params)
494 {
495 struct bt_hci_cp_le_set_conn_cte_tx_params *cp;
496 uint8_t *ant_ids;
497
498 cp = net_buf_add(buf, sizeof(*cp));
499 (void)memset(cp, 0, sizeof(*cp));
500
501 cp->handle = sys_cpu_to_le16(conn->handle);
502 cp->cte_types = params->cte_types;
503
504 if (params->cte_types & (BT_DF_CTE_TYPE_AOD_1US | BT_DF_CTE_TYPE_AOD_2US)) {
505 cp->switch_pattern_len = params->num_ant_ids;
506
507 ant_ids = net_buf_add(buf, cp->switch_pattern_len);
508 (void)memcpy(ant_ids, params->ant_ids, cp->switch_pattern_len);
509 } else {
510 cp->switch_pattern_len = 0U;
511 }
512 }
513
514 /**
515 * @brief Function sets CTE parameters for connection object
516 *
517 * @param conn Connection object
518 * @param params CTE transmission parameters.
519 *
520 * @return Zero in case of success, other value in case of failure.
521 */
hci_df_set_conn_cte_tx_param(struct bt_conn * conn,const struct bt_df_conn_cte_tx_param * params)522 static int hci_df_set_conn_cte_tx_param(struct bt_conn *conn,
523 const struct bt_df_conn_cte_tx_param *params)
524 {
525 struct bt_hci_rp_le_set_conn_cte_tx_params *rp;
526 struct bt_hci_cmd_state_set state;
527 struct net_buf *buf, *rsp;
528 int err;
529
530 /* If AoD is not enabled, ant_ids are ignored by controller:
531 * BT Core spec 5.2 Vol 4, Part E sec. 7.8.84.
532 */
533 if (!valid_conn_cte_tx_params(params)) {
534 return -EINVAL;
535 }
536
537 buf = bt_hci_cmd_alloc(K_FOREVER);
538 if (!buf) {
539 return -ENOBUFS;
540 }
541
542 prepare_conn_cte_tx_params_cmd(buf, conn, params);
543
544 /* CTE transmission parameters must be set only once for connection lifetime, hence the
545 * flag BT_CONN_CTE_TX_PARAMS_SET is always set to true and never set to false.
546 */
547 bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_TX_PARAMS_SET, true);
548
549 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CONN_CTE_TX_PARAMS, buf, &rsp);
550 if (err) {
551 return err;
552 }
553
554 rp = (void *)rsp->data;
555 if (conn->handle != sys_le16_to_cpu(rp->handle)) {
556 err = -EIO;
557 }
558
559 net_buf_unref(rsp);
560
561 return err;
562 }
563 #endif /* CONFIG_BT_DF_CONNECTION_CTE_TX */
564
565 #if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
prepare_conn_cte_rx_enable_cmd_params(struct net_buf ** buf,struct bt_conn * conn,const struct bt_df_conn_cte_rx_param * params,bool enable)566 static int prepare_conn_cte_rx_enable_cmd_params(struct net_buf **buf, struct bt_conn *conn,
567 const struct bt_df_conn_cte_rx_param *params,
568 bool enable)
569 {
570 struct bt_hci_cp_le_set_conn_cte_rx_params *cp;
571 uint8_t switch_pattern_len;
572
573 if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
574 switch_pattern_len = params->num_ant_ids;
575 } else {
576 switch_pattern_len = ARRAY_SIZE(df_dummy_switch_pattern);
577 }
578
579 /* If CTE Rx is enabled, command parameters total length must include
580 * antenna ids, so command size if extended by num_and_ids.
581 */
582 *buf = bt_hci_cmd_alloc(K_FOREVER);
583 if (!(*buf)) {
584 return -ENOBUFS;
585 }
586
587 cp = net_buf_add(*buf, sizeof(*cp));
588 (void)memset(cp, 0, sizeof(*cp));
589
590 cp->handle = sys_cpu_to_le16(conn->handle);
591 cp->sampling_enable = enable ? 1 : 0;
592
593 if (enable) {
594 const uint8_t *ant_ids;
595 uint8_t *dest_ant_ids;
596
597 if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
598 cp->slot_durations = params->slot_durations;
599 ant_ids = params->ant_ids;
600 } else {
601 /* Those values are put here due to constraints from HCI command
602 * specification: Bluetooth Core Spec. 5.3 Vol 4,Part E, sec 7.8.85.
603 * There is no right way to successfully send the command to enable CTE
604 * receive for AoD mode (e.g. device equipped with single antenna).
605 * There is no CTE type in the parameters list, so controller is forced
606 * to check correctness of all parameters always.
607 */
608 cp->slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US;
609 ant_ids = &df_dummy_switch_pattern[0];
610 }
611
612 cp->switch_pattern_len = switch_pattern_len;
613 dest_ant_ids = net_buf_add(*buf, cp->switch_pattern_len);
614 (void)memcpy(dest_ant_ids, ant_ids, cp->switch_pattern_len);
615 }
616
617 return 0;
618 }
619
hci_df_set_conn_cte_rx_enable(struct bt_conn * conn,bool enable,const struct bt_df_conn_cte_rx_param * params)620 static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
621 const struct bt_df_conn_cte_rx_param *params)
622 {
623 struct bt_hci_rp_le_set_conn_cte_rx_params *rp;
624 struct bt_hci_cmd_state_set state;
625 struct net_buf *buf, *rsp;
626 int err;
627
628 if (enable) {
629 if (!valid_cte_rx_common_params(params->cte_types, params->slot_durations,
630 params->num_ant_ids, params->ant_ids)) {
631 return -EINVAL;
632 }
633 }
634
635 err = prepare_conn_cte_rx_enable_cmd_params(&buf, conn, params, enable);
636 if (err) {
637 return err;
638 }
639
640 bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_RX_ENABLED, enable);
641
642 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CONN_CTE_RX_PARAMS, buf, &rsp);
643 if (err) {
644 return err;
645 }
646
647 rp = (void *)rsp->data;
648 if (conn->handle != sys_le16_to_cpu(rp->handle)) {
649 err = -EIO;
650 } else {
651 conn->cte_types = (enable ? params->cte_types : 0);
652 /* This flag is set once for connection object. It is never cleared because CTE RX
653 * params must be set at least once for connection object to successfully execute
654 * CTE REQ procedure.
655 */
656 atomic_set_bit(conn->flags, BT_CONN_CTE_RX_PARAMS_SET);
657 }
658
659 net_buf_unref(rsp);
660
661 return err;
662 }
663
hci_df_prepare_connection_iq_report(struct net_buf * buf,struct bt_df_conn_iq_samples_report * report,struct bt_conn ** conn_to_report)664 int hci_df_prepare_connection_iq_report(struct net_buf *buf,
665 struct bt_df_conn_iq_samples_report *report,
666 struct bt_conn **conn_to_report)
667 {
668 struct bt_hci_evt_le_connection_iq_report *evt;
669 struct bt_conn *conn;
670
671 if (buf->len < sizeof(*evt)) {
672 LOG_ERR("Unexpected end of buffer");
673 return -EINVAL;
674 }
675
676 evt = net_buf_pull_mem(buf, sizeof(*evt));
677
678 conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE);
679 if (!conn) {
680 LOG_ERR("Unknown conn handle 0x%04X for iq samples report",
681 sys_le16_to_cpu(evt->conn_handle));
682 return -EINVAL;
683 }
684
685 if (!atomic_test_bit(conn->flags, BT_CONN_CTE_RX_ENABLED)) {
686 LOG_ERR("Received conn CTE report when CTE receive disabled");
687 bt_conn_unref(conn);
688 return -EINVAL;
689 }
690
691 if (!(conn->cte_types & BIT(evt->cte_type))) {
692 LOG_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
693 bt_conn_unref(conn);
694 return -EINVAL;
695 }
696
697 report->err = BT_DF_IQ_REPORT_ERR_SUCCESS;
698 report->chan_idx = evt->data_chan_idx;
699 report->rx_phy = evt->rx_phy;
700 report->chan_idx = evt->data_chan_idx;
701 report->rssi = evt->rssi;
702 report->rssi_ant_id = evt->rssi_ant_id;
703 report->cte_type = BIT(evt->cte_type);
704 report->packet_status = evt->packet_status;
705 report->slot_durations = evt->slot_durations;
706 report->conn_evt_counter = sys_le16_to_cpu(evt->conn_evt_counter);
707 report->sample_type = BT_DF_IQ_SAMPLE_8_BITS_INT;
708 report->sample_count = evt->sample_count;
709 report->sample = evt->sample;
710
711 *conn_to_report = conn;
712
713 return 0;
714 }
715
hci_df_vs_prepare_connection_iq_report(struct net_buf * buf,struct bt_df_conn_iq_samples_report * report,struct bt_conn ** conn_to_report)716 int hci_df_vs_prepare_connection_iq_report(struct net_buf *buf,
717 struct bt_df_conn_iq_samples_report *report,
718 struct bt_conn **conn_to_report)
719 {
720 struct bt_hci_evt_vs_le_connection_iq_report *evt;
721 struct bt_conn *conn;
722
723 if (buf->len < sizeof(*evt)) {
724 LOG_ERR("Unexpected end of buffer");
725 return -EINVAL;
726 }
727
728 evt = net_buf_pull_mem(buf, sizeof(*evt));
729
730 conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE);
731 if (!conn) {
732 LOG_ERR("Unknown conn handle 0x%04X for iq samples report",
733 sys_le16_to_cpu(evt->conn_handle));
734 return -EINVAL;
735 }
736
737 if (!atomic_test_bit(conn->flags, BT_CONN_CTE_RX_ENABLED)) {
738 LOG_ERR("Received conn CTE report when CTE receive disabled");
739 bt_conn_unref(conn);
740 return -EINVAL;
741 }
742
743 if (!(conn->cte_types & BIT(evt->cte_type))) {
744 LOG_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
745 bt_conn_unref(conn);
746 return -EINVAL;
747 }
748
749 report->err = BT_DF_IQ_REPORT_ERR_SUCCESS;
750 report->chan_idx = evt->data_chan_idx;
751 report->rx_phy = evt->rx_phy;
752 report->chan_idx = evt->data_chan_idx;
753 report->rssi = evt->rssi;
754 report->rssi_ant_id = evt->rssi_ant_id;
755 report->cte_type = BIT(evt->cte_type);
756 report->packet_status = evt->packet_status;
757 report->slot_durations = evt->slot_durations;
758 report->conn_evt_counter = sys_le16_to_cpu(evt->conn_evt_counter);
759 report->sample_type = BT_DF_IQ_SAMPLE_16_BITS_INT;
760 report->sample_count = evt->sample_count;
761 report->sample16 = evt->sample;
762
763 *conn_to_report = conn;
764
765 return 0;
766 }
767
768 #endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
769
770 #if defined(CONFIG_BT_DF_CONNECTION_CTE_REQ)
valid_cte_req_params(const struct bt_conn * conn,uint8_t cte_type,uint8_t cte_length)771 static bool valid_cte_req_params(const struct bt_conn *conn, uint8_t cte_type,
772 uint8_t cte_length)
773 {
774 if (!(conn->cte_types & cte_type)) {
775 return false;
776 }
777
778 if (cte_length < BT_HCI_LE_CTE_LEN_MIN || cte_length > BT_HCI_LE_CTE_LEN_MAX) {
779 return false;
780 }
781
782 return true;
783 }
784
prepare_conn_cte_req_enable_cmd_params(struct net_buf * buf,const struct bt_conn * conn,const struct bt_df_conn_cte_req_params * params,bool enable)785 static void prepare_conn_cte_req_enable_cmd_params(struct net_buf *buf, const struct bt_conn *conn,
786 const struct bt_df_conn_cte_req_params *params,
787 bool enable)
788 {
789 struct bt_hci_cp_le_conn_cte_req_enable *cp;
790
791 cp = net_buf_add(buf, sizeof(*cp));
792 (void)memset(cp, 0, sizeof(*cp));
793
794 cp->handle = sys_cpu_to_le16(conn->handle);
795 cp->enable = enable ? 1 : 0;
796
797 if (enable) {
798 cp->cte_request_interval = params->interval;
799 cp->requested_cte_length = sys_cpu_to_le16(params->cte_length);
800 cp->requested_cte_type = get_hci_cte_type(params->cte_type);
801 }
802 }
803
hci_df_set_conn_cte_req_enable(struct bt_conn * conn,bool enable,const struct bt_df_conn_cte_req_params * params)804 static int hci_df_set_conn_cte_req_enable(struct bt_conn *conn, bool enable,
805 const struct bt_df_conn_cte_req_params *params)
806 {
807 struct bt_hci_cp_le_conn_cte_req_enable *rp;
808 struct bt_hci_cmd_state_set state;
809 struct net_buf *buf, *rsp;
810 int err;
811
812 if (enable && !valid_cte_req_params(conn, params->cte_type, params->cte_length)) {
813 return -EINVAL;
814 }
815
816 buf = bt_hci_cmd_alloc(K_FOREVER);
817 if (!buf) {
818 return -ENOBUFS;
819 }
820
821 prepare_conn_cte_req_enable_cmd_params(buf, conn, params, enable);
822
823 bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_REQ_ENABLED, enable);
824
825 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CONN_CTE_REQ_ENABLE, buf, &rsp);
826 if (err) {
827 return err;
828 }
829
830 rp = (void *)rsp->data;
831 if (conn->handle != sys_le16_to_cpu(rp->handle)) {
832 err = -EIO;
833 }
834
835 net_buf_unref(rsp);
836
837 return err;
838 }
839
hci_df_prepare_conn_cte_req_failed(struct net_buf * buf,struct bt_df_conn_iq_samples_report * report,struct bt_conn ** conn_to_report)840 int hci_df_prepare_conn_cte_req_failed(struct net_buf *buf,
841 struct bt_df_conn_iq_samples_report *report,
842 struct bt_conn **conn_to_report)
843 {
844 struct bt_hci_evt_le_cte_req_failed *evt;
845 struct bt_conn *conn;
846
847 if (buf->len < sizeof(*evt)) {
848 LOG_ERR("Unexpected end of buffer");
849 return -EINVAL;
850 }
851
852 evt = net_buf_pull_mem(buf, sizeof(*evt));
853
854 conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE);
855 if (!conn) {
856 LOG_ERR("Unknown conn handle 0x%04X for iq samples report",
857 sys_le16_to_cpu(evt->conn_handle));
858 return -EINVAL;
859 }
860
861 if (!atomic_test_bit(conn->flags, BT_CONN_CTE_REQ_ENABLED)) {
862 LOG_ERR("Received conn CTE request notification when CTE REQ disabled");
863 bt_conn_unref(conn);
864 return -EINVAL;
865 }
866
867 (void)memset(report, 0U, sizeof(*report));
868
869 if (evt->status == BT_HCI_CTE_REQ_STATUS_RSP_WITHOUT_CTE) {
870 report->err = BT_DF_IQ_REPORT_ERR_NO_CTE;
871 } else {
872 report->err = BT_DF_IQ_REPORT_ERR_PEER_REJECTED;
873 }
874
875 *conn_to_report = conn;
876
877 return 0;
878 }
879 #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */
880
881 #if defined(CONFIG_BT_DF_CONNECTION_CTE_RSP)
prepare_conn_cte_rsp_enable_cmd_params(struct net_buf * buf,const struct bt_conn * conn,bool enable)882 static void prepare_conn_cte_rsp_enable_cmd_params(struct net_buf *buf, const struct bt_conn *conn,
883 bool enable)
884 {
885 struct bt_hci_cp_le_conn_cte_rsp_enable *cp;
886
887 cp = net_buf_add(buf, sizeof(*cp));
888 (void)memset(cp, 0, sizeof(*cp));
889
890 cp->handle = sys_cpu_to_le16(conn->handle);
891 cp->enable = enable ? 1U : 0U;
892 }
893
hci_df_set_conn_cte_rsp_enable(struct bt_conn * conn,bool enable)894 static int hci_df_set_conn_cte_rsp_enable(struct bt_conn *conn, bool enable)
895 {
896 struct bt_hci_rp_le_conn_cte_rsp_enable *rp;
897 struct bt_hci_cmd_state_set state;
898 struct net_buf *buf, *rsp;
899 int err;
900
901 buf = bt_hci_cmd_alloc(K_FOREVER);
902 if (!buf) {
903 return -ENOBUFS;
904 }
905
906 prepare_conn_cte_rsp_enable_cmd_params(buf, conn, enable);
907
908 bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_RSP_ENABLED, enable);
909
910 err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CONN_CTE_RSP_ENABLE, buf, &rsp);
911 if (err) {
912 return err;
913 }
914
915 rp = (void *)rsp->data;
916 if (conn->handle != sys_le16_to_cpu(rp->handle)) {
917 err = -EIO;
918 }
919
920 net_buf_unref(rsp);
921
922 return err;
923 }
924 #endif /* CONFIG_BT_DF_CONNECTION_CTE_RSP */
925
926 /* @brief Function initializes Direction Finding in Host
927 *
928 * @return Zero in case of success, other value in case of failure.
929 */
le_df_init(void)930 int le_df_init(void)
931 {
932 uint8_t max_switch_pattern_len;
933 uint8_t switch_sample_rates;
934 uint8_t max_cte_len;
935 uint8_t num_ant;
936 int err;
937
938 err = hci_df_read_ant_info(&switch_sample_rates, &num_ant,
939 &max_switch_pattern_len, &max_cte_len);
940 if (err) {
941 return err;
942 }
943
944 df_ant_info.max_switch_pattern_len = max_switch_pattern_len;
945 df_ant_info.switch_sample_rates = switch_sample_rates;
946 df_ant_info.max_cte_len = max_cte_len;
947 df_ant_info.num_ant = num_ant;
948
949 LOG_DBG("DF initialized.");
950 return 0;
951 }
952
bt_df_set_adv_cte_tx_param(struct bt_le_ext_adv * adv,const struct bt_df_adv_cte_tx_param * params)953 int bt_df_set_adv_cte_tx_param(struct bt_le_ext_adv *adv,
954 const struct bt_df_adv_cte_tx_param *params)
955 {
956 __ASSERT_NO_MSG(adv);
957 __ASSERT_NO_MSG(params);
958
959 int err;
960
961 if (!BT_FEAT_LE_CONNECTIONLESS_CTE_TX(bt_dev.le.features)) {
962 return -ENOTSUP;
963 }
964
965 /* Check if BT_ADV_PARAMS_SET is set, because it implies the set
966 * has already been created.
967 */
968 if (!atomic_test_bit(adv->flags, BT_ADV_PARAMS_SET)) {
969 return -EINVAL;
970 }
971
972 if (atomic_test_bit(adv->flags, BT_PER_ADV_CTE_ENABLED)) {
973 return -EINVAL;
974 }
975
976 err = hci_df_set_cl_cte_tx_params(adv, params);
977 if (err) {
978 return err;
979 }
980
981 atomic_set_bit(adv->flags, BT_PER_ADV_CTE_PARAMS_SET);
982
983 return 0;
984 }
985
bt_df_set_adv_cte_tx_enabled(struct bt_le_ext_adv * adv,bool enable)986 static int bt_df_set_adv_cte_tx_enabled(struct bt_le_ext_adv *adv, bool enable)
987 {
988 if (!atomic_test_bit(adv->flags, BT_PER_ADV_PARAMS_SET)) {
989 return -EINVAL;
990 }
991
992 if (!atomic_test_bit(adv->flags, BT_PER_ADV_CTE_PARAMS_SET)) {
993 return -EINVAL;
994 }
995
996 if (enable == atomic_test_bit(adv->flags, BT_PER_ADV_CTE_ENABLED)) {
997 return -EALREADY;
998 }
999
1000 return hci_df_set_adv_cte_tx_enable(adv, enable);
1001 }
1002
bt_df_adv_cte_tx_enable(struct bt_le_ext_adv * adv)1003 int bt_df_adv_cte_tx_enable(struct bt_le_ext_adv *adv)
1004 {
1005 __ASSERT_NO_MSG(adv);
1006 return bt_df_set_adv_cte_tx_enabled(adv, true);
1007 }
1008
bt_df_adv_cte_tx_disable(struct bt_le_ext_adv * adv)1009 int bt_df_adv_cte_tx_disable(struct bt_le_ext_adv *adv)
1010 {
1011 __ASSERT_NO_MSG(adv);
1012 return bt_df_set_adv_cte_tx_enabled(adv, false);
1013 }
1014
1015 #if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
1016 static int
bt_df_set_per_adv_sync_cte_rx_enable(struct bt_le_per_adv_sync * sync,bool enable,const struct bt_df_per_adv_sync_cte_rx_param * params)1017 bt_df_set_per_adv_sync_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool enable,
1018 const struct bt_df_per_adv_sync_cte_rx_param *params)
1019 {
1020 if (!BT_FEAT_LE_CONNECTIONLESS_CTE_RX(bt_dev.le.features)) {
1021 return -ENOTSUP;
1022 }
1023
1024 if (!atomic_test_bit(sync->flags, BT_PER_ADV_SYNC_SYNCED)) {
1025 return -EINVAL;
1026 }
1027
1028 if (!enable &&
1029 !atomic_test_bit(sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED)) {
1030 return -EALREADY;
1031 }
1032
1033 return hci_df_set_cl_cte_rx_enable(sync, enable, params);
1034 }
1035
bt_df_per_adv_sync_cte_rx_enable(struct bt_le_per_adv_sync * sync,const struct bt_df_per_adv_sync_cte_rx_param * params)1036 int bt_df_per_adv_sync_cte_rx_enable(struct bt_le_per_adv_sync *sync,
1037 const struct bt_df_per_adv_sync_cte_rx_param *params)
1038 {
1039 CHECKIF(!sync) {
1040 return -EINVAL;
1041 }
1042 CHECKIF(!params) {
1043 return -EINVAL;
1044 }
1045
1046 return bt_df_set_per_adv_sync_cte_rx_enable(sync, true, params);
1047 }
1048
bt_df_per_adv_sync_cte_rx_disable(struct bt_le_per_adv_sync * sync)1049 int bt_df_per_adv_sync_cte_rx_disable(struct bt_le_per_adv_sync *sync)
1050 {
1051 CHECKIF(!sync) {
1052 return -EINVAL;
1053 }
1054
1055 return bt_df_set_per_adv_sync_cte_rx_enable(sync, false, NULL);
1056 }
1057 #endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
1058
1059 #if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
bt_df_set_conn_cte_rx_enable(struct bt_conn * conn,bool enable,const struct bt_df_conn_cte_rx_param * params)1060 static int bt_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
1061 const struct bt_df_conn_cte_rx_param *params)
1062 {
1063 if (!BT_FEAT_LE_RX_CTE(bt_dev.le.features)) {
1064 LOG_WRN("Receiving Constant Tone Extensions is not supported");
1065 return -ENOTSUP;
1066 }
1067
1068 if (conn->state != BT_CONN_CONNECTED) {
1069 LOG_ERR("not connected!");
1070 return -ENOTCONN;
1071 }
1072
1073 return hci_df_set_conn_cte_rx_enable(conn, enable, params);
1074 }
1075
bt_df_conn_cte_rx_enable(struct bt_conn * conn,const struct bt_df_conn_cte_rx_param * params)1076 int bt_df_conn_cte_rx_enable(struct bt_conn *conn, const struct bt_df_conn_cte_rx_param *params)
1077 {
1078 CHECKIF(!conn) {
1079 return -EINVAL;
1080 }
1081
1082 CHECKIF(!params) {
1083 return -EINVAL;
1084 }
1085
1086 return bt_df_set_conn_cte_rx_enable(conn, true, params);
1087 }
1088
bt_df_conn_cte_rx_disable(struct bt_conn * conn)1089 int bt_df_conn_cte_rx_disable(struct bt_conn *conn)
1090 {
1091 CHECKIF(!conn) {
1092 return -EINVAL;
1093 }
1094
1095 return bt_df_set_conn_cte_rx_enable(conn, false, NULL);
1096 }
1097 #endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
1098
1099 #if defined(CONFIG_BT_DF_CONNECTION_CTE_TX)
bt_df_set_conn_cte_tx_param(struct bt_conn * conn,const struct bt_df_conn_cte_tx_param * params)1100 int bt_df_set_conn_cte_tx_param(struct bt_conn *conn, const struct bt_df_conn_cte_tx_param *params)
1101 {
1102 CHECKIF(!conn) {
1103 return -EINVAL;
1104 }
1105
1106 CHECKIF(!params) {
1107 return -EINVAL;
1108 }
1109
1110 if (conn->state != BT_CONN_CONNECTED) {
1111 LOG_ERR("not connected!");
1112 return -ENOTCONN;
1113 }
1114
1115 if (atomic_test_bit(conn->flags, BT_CONN_CTE_RSP_ENABLED)) {
1116 LOG_WRN("CTE response procedure is enabled");
1117 return -EINVAL;
1118 }
1119
1120 return hci_df_set_conn_cte_tx_param(conn, params);
1121 }
1122
1123 #endif /* CONFIG_BT_DF_CONNECTION_CTE_TX */
1124
1125 #if defined(CONFIG_BT_DF_CONNECTION_CTE_REQ)
bt_df_set_conn_cte_req_enable(struct bt_conn * conn,bool enable,const struct bt_df_conn_cte_req_params * params)1126 static int bt_df_set_conn_cte_req_enable(struct bt_conn *conn, bool enable,
1127 const struct bt_df_conn_cte_req_params *params)
1128 {
1129 if (!BT_FEAT_LE_CONNECTION_CTE_REQ(bt_dev.le.features)) {
1130 LOG_WRN("Constant Tone Extensions request procedure is not supported");
1131 return -ENOTSUP;
1132 }
1133
1134 if (conn->state != BT_CONN_CONNECTED) {
1135 LOG_ERR("not connected!");
1136 return -ENOTCONN;
1137 }
1138
1139 if (!atomic_test_bit(conn->flags, BT_CONN_CTE_RX_PARAMS_SET)) {
1140 LOG_ERR("Can't start CTE request procedure before CTE RX params setup");
1141 return -EINVAL;
1142 }
1143
1144 return hci_df_set_conn_cte_req_enable(conn, enable, params);
1145 }
1146
bt_df_conn_cte_req_enable(struct bt_conn * conn,const struct bt_df_conn_cte_req_params * params)1147 int bt_df_conn_cte_req_enable(struct bt_conn *conn, const struct bt_df_conn_cte_req_params *params)
1148 {
1149 CHECKIF(!conn) {
1150 return -EINVAL;
1151 }
1152
1153 CHECKIF(!params) {
1154 return -EINVAL;
1155 }
1156
1157 return bt_df_set_conn_cte_req_enable(conn, true, params);
1158 }
1159
bt_df_conn_cte_req_disable(struct bt_conn * conn)1160 int bt_df_conn_cte_req_disable(struct bt_conn *conn)
1161 {
1162 CHECKIF(!conn) {
1163 return -EINVAL;
1164 }
1165
1166 return bt_df_set_conn_cte_req_enable(conn, false, NULL);
1167 }
1168 #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */
1169
1170 #if defined(CONFIG_BT_DF_CONNECTION_CTE_RSP)
bt_df_set_conn_cte_rsp_enable(struct bt_conn * conn,bool enable)1171 static int bt_df_set_conn_cte_rsp_enable(struct bt_conn *conn, bool enable)
1172 {
1173 CHECKIF(!conn) {
1174 return -EINVAL;
1175 }
1176
1177 if (!BT_FEAT_LE_CONNECTION_CTE_RESP(bt_dev.le.features)) {
1178 LOG_WRN("CTE response procedure is not supported");
1179 return -ENOTSUP;
1180 }
1181
1182 if (conn->state != BT_CONN_CONNECTED) {
1183 LOG_ERR("not connected");
1184 return -ENOTCONN;
1185 }
1186
1187 if (!atomic_test_bit(conn->flags, BT_CONN_CTE_TX_PARAMS_SET)) {
1188 LOG_ERR("Can't start CTE response procedure before CTE TX params setup");
1189 return -EINVAL;
1190 }
1191
1192 return hci_df_set_conn_cte_rsp_enable(conn, enable);
1193 }
1194
bt_df_conn_cte_rsp_enable(struct bt_conn * conn)1195 int bt_df_conn_cte_rsp_enable(struct bt_conn *conn)
1196 {
1197 return bt_df_set_conn_cte_rsp_enable(conn, true);
1198 }
1199
bt_df_conn_cte_rsp_disable(struct bt_conn * conn)1200 int bt_df_conn_cte_rsp_disable(struct bt_conn *conn)
1201 {
1202 return bt_df_set_conn_cte_rsp_enable(conn, false);
1203 }
1204 #endif /* CONFIG_BT_DF_CONNECTION_CTE_RSP */
1205