diff --git a/include/bluetooth/hci.h b/include/bluetooth/hci.h index a9da06d9944..6db6cf12003 100644 --- a/include/bluetooth/hci.h +++ b/include/bluetooth/hci.h @@ -187,6 +187,8 @@ struct bt_hci_cmd_hdr { BT_LE_FEAT_BIT_PER_ADV) #define BT_FEAT_LE_CONNECTIONLESS_CTE_TX(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_CONNECTIONLESS_CTE_TX) +#define BT_FEAT_LE_ANT_SWITCH_TX_AOD(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_ANT_SWITCH_TX_AOD) #define BT_FEAT_LE_PAST_SEND(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_PAST_SEND) #define BT_FEAT_LE_PAST_RECV(feat) BT_LE_FEAT_TEST(feat, \ diff --git a/subsys/bluetooth/host/direction.c b/subsys/bluetooth/host/direction.c index b317b43015c..ae3884abbb4 100644 --- a/subsys/bluetooth/host/direction.c +++ b/subsys/bluetooth/host/direction.c @@ -11,7 +11,9 @@ #include #include +#include "hci_core.h" #include "conn_internal.h" +#include "direction.h" #include "direction_internal.h" #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_DF) @@ -41,6 +43,71 @@ static struct bt_le_df_ant_info df_ant_info; #define DF_AOA_RX_1US_SUPPORT(supp) (DF_SUPP_TEST(supp, \ BT_HCI_LE_1US_AOA_RX)) +static int hci_df_set_cl_cte_tx_params(const struct bt_le_ext_adv *adv, + const struct bt_le_df_adv_cte_tx_params *params) +{ + struct bt_hci_cp_le_set_cl_cte_tx_params *cp; + struct net_buf *buf; + + /* If AoD is not enabled, ant_ids are ignored by controller: + * BT Core spec 5.2 Vol 4, Part E sec. 7.8.80. + */ + if (params->cte_type == BT_HCI_LE_AOD_CTE_1US || + params->cte_type == BT_HCI_LE_AOD_CTE_2US) { + + if (!BT_FEAT_LE_ANT_SWITCH_TX_AOD(bt_dev.le.features)) { + return -EINVAL; + } + + if (params->cte_type == BT_HCI_LE_AOD_CTE_1US && + !DF_AOD_TX_1US_SUPPORT(df_ant_info.switch_sample_rates)) { + return -EINVAL; + } + + if (params->num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN || + params->num_ant_ids > BT_HCI_LE_SWITCH_PATTERN_LEN_MAX || + !params->ant_ids) { + return -EINVAL; + } + } else if (params->cte_type != BT_HCI_LE_AOA_CTE) { + return -EINVAL; + } + + if (params->cte_len < BT_HCI_LE_CTE_LEN_MIN || + params->cte_len > BT_HCI_LE_CTE_LEN_MAX) { + return -EINVAL; + } + + if (params->cte_count < BT_HCI_LE_CTE_COUNT_MIN || + params->cte_count > BT_HCI_LE_CTE_COUNT_MAX) { + return -EINVAL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_CL_CTE_TX_PARAMS, + sizeof(*cp) + params->num_ant_ids); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = adv->handle; + cp->cte_len = params->cte_len; + cp->cte_type = params->cte_type; + cp->cte_count = params->cte_count; + + if (params->num_ant_ids) { + uint8_t *dest_ant_ids = net_buf_add(buf, params->num_ant_ids); + + memcpy(dest_ant_ids, params->ant_ids, params->num_ant_ids); + cp->switch_pattern_len = params->num_ant_ids; + } else { + cp->switch_pattern_len = 0; + } + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CL_CTE_TX_PARAMS, + buf, NULL); +} + /* @brief Function provides information about DF antennae numer and * controller capabilities related with Constant Tone Extension. * diff --git a/subsys/bluetooth/host/direction.h b/subsys/bluetooth/host/direction.h new file mode 100644 index 00000000000..9637c417178 --- /dev/null +++ b/subsys/bluetooth/host/direction.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SUBSYS_BLUETOOTH_HOST_DF_H_ +#define ZEPHYR_SUBSYS_BLUETOOTH_HOST_DF_H_ + +/* @brief Optional switching and sampling rates for Angle of Departure + * and Angle or Arrival modes. + */ +enum bt_df_opt_swich_sample_rates { + /* Support Angle of Departure 1us switching TX */ + DF_AOD_1US_SWITCH_TX_SUPP = BIT(0), + /* Support Angle of departure 1us sampling RX */ + DF_AOD_1US_SAMPL_RX_SUPP = BIT(1), + /* Support Angle of Arrival 1us switching and sampling RX */ + DF_AOA_1US_SWITCH_SAMPL_RX_SUPP = BIT(2), +}; + +/* @brief Constant Tone Extension parameters for connectionless + * transmission. + * + * The structure holds information required to setup CTE transmission + * in periodic advertising. + */ +struct bt_le_df_adv_cte_tx_params { + /* Length of CTE in 8us units */ + uint8_t cte_len; + /* CTE Type: AoA, AoD 1us slots, AoD 2us slots */ + uint8_t cte_type; + /* Number of CTE to transmit in each periodic adv interval */ + uint8_t cte_count; + /* Number of Antenna IDs in the switch pattern */ + uint8_t num_ant_ids; + /* List of antenna IDs in the pattern */ + uint8_t *ant_ids; +}; +#endif /* ZEPHYR_SUBSYS_BLUETOOTH_HOST_DF_H_ */