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