Bluetooh: host: Add CTE RX and sample enable for conn mode
Add enable of CTE reception and sampling in connected mode. The implementation allows an application to decide what type of CTE is expected to be reported. Bluetooth Core specification does not provide such functionality, so it is provided as part of host implementation. Host will filter out all reports for not enabled CTE types. Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
e9b74593b8
commit
f18637fe30
4 changed files with 231 additions and 37 deletions
|
@ -109,6 +109,17 @@ struct bt_df_per_adv_sync_iq_samples_report {
|
||||||
struct bt_hci_le_iq_sample const *sample;
|
struct bt_hci_le_iq_sample const *sample;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bt_df_conn_cte_rx_param {
|
||||||
|
/* Bitmap with allowed CTE types (@ref bt_df_cte_type). */
|
||||||
|
uint8_t cte_type;
|
||||||
|
/** Antenna switching slots (@ref bt_df_antenna_switching_slot). */
|
||||||
|
uint8_t slot_durations;
|
||||||
|
/** Length of antenna switch pattern. */
|
||||||
|
uint8_t num_ant_ids;
|
||||||
|
/** Antenna switch pattern. */
|
||||||
|
const uint8_t *ant_ids;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set or update the Constant Tone Extension parameters for periodic advertising set.
|
* @brief Set or update the Constant Tone Extension parameters for periodic advertising set.
|
||||||
*
|
*
|
||||||
|
@ -165,4 +176,23 @@ int bt_df_per_adv_sync_cte_rx_enable(struct bt_le_per_adv_sync *sync,
|
||||||
*/
|
*/
|
||||||
int bt_df_per_adv_sync_cte_rx_disable(struct bt_le_per_adv_sync *sync);
|
int bt_df_per_adv_sync_cte_rx_disable(struct bt_le_per_adv_sync *sync);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable receive and sampling of Constant Tone Extension for the connection object.
|
||||||
|
*
|
||||||
|
* @param conn Connection object.
|
||||||
|
* @param params CTE receive and sampling parameters.
|
||||||
|
*
|
||||||
|
* @return Zero in case of success, other value in case of failure.
|
||||||
|
*/
|
||||||
|
int bt_df_conn_cte_rx_enable(struct bt_conn *conn, const struct bt_df_conn_cte_rx_param *params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable receive and sampling of Constant Tone Extension for the connection object.
|
||||||
|
*
|
||||||
|
* @param conn Connection object.
|
||||||
|
*
|
||||||
|
* @return Zero in case of success, other value in case of failure.
|
||||||
|
*/
|
||||||
|
int bt_df_conn_cte_rx_disable(struct bt_conn *conn);
|
||||||
|
|
||||||
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_DF_H_ */
|
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_DF_H_ */
|
||||||
|
|
|
@ -43,6 +43,8 @@ enum {
|
||||||
* is only needed for controllers with BT_QUIRK_NO_AUTO_DLE. */
|
* is only needed for controllers with BT_QUIRK_NO_AUTO_DLE. */
|
||||||
BT_CONN_AUTO_DATA_LEN_COMPLETE,
|
BT_CONN_AUTO_DATA_LEN_COMPLETE,
|
||||||
|
|
||||||
|
BT_CONN_CTE_RX_ENABLED, /* CTE receive and sampling is enabled */
|
||||||
|
|
||||||
/* Total number of flags - must be at the end of the enum */
|
/* Total number of flags - must be at the end of the enum */
|
||||||
BT_CONN_NUM_FLAGS,
|
BT_CONN_NUM_FLAGS,
|
||||||
};
|
};
|
||||||
|
@ -162,6 +164,11 @@ struct bt_conn {
|
||||||
uint8_t encrypt;
|
uint8_t encrypt;
|
||||||
#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */
|
#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||||
|
/** Accepted CTE type */
|
||||||
|
uint8_t cte_type;
|
||||||
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
||||||
/* Connection error or reason for disconnect */
|
/* Connection error or reason for disconnect */
|
||||||
uint8_t err;
|
uint8_t err;
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@ struct bt_le_df_ant_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct bt_le_df_ant_info df_ant_info;
|
static struct bt_le_df_ant_info df_ant_info;
|
||||||
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
|
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||||
const static uint8_t df_dummy_switch_pattern[BT_HCI_LE_SWITCH_PATTERN_LEN_MIN] = { 0, 0 };
|
const static uint8_t df_dummy_switch_pattern[BT_HCI_LE_SWITCH_PATTERN_LEN_MIN] = { 0, 0 };
|
||||||
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
|
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
||||||
#define DF_AOD_TX_1US_SUPPORT(supp) (supp & BT_HCI_LE_1US_AOD_TX)
|
#define DF_AOD_TX_1US_SUPPORT(supp) (supp & BT_HCI_LE_1US_AOD_TX)
|
||||||
#define DF_AOD_RX_1US_SUPPORT(supp) (supp & BT_HCI_LE_1US_AOD_RX)
|
#define DF_AOD_RX_1US_SUPPORT(supp) (supp & BT_HCI_LE_1US_AOD_RX)
|
||||||
|
@ -46,15 +46,29 @@ const static uint8_t df_dummy_switch_pattern[BT_HCI_LE_SWITCH_PATTERN_LEN_MIN] =
|
||||||
|
|
||||||
#define DF_SAMPLING_ANTENNA_NUMBER_MIN 0x2
|
#define DF_SAMPLING_ANTENNA_NUMBER_MIN 0x2
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||||
|
static bool validate_cte_rx_common_params(uint8_t cte_type, uint8_t slot_durations,
|
||||||
|
uint8_t num_ant_ids, const uint8_t *ant_ids);
|
||||||
|
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
|
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
|
||||||
static int validate_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params);
|
static bool validate_cl_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params);
|
||||||
static void prepare_cte_rx_enable_cmd_params(struct net_buf *buf, struct bt_le_per_adv_sync *sync,
|
static void
|
||||||
const struct bt_df_per_adv_sync_cte_rx_param *params,
|
prepare_cl_cte_rx_enable_cmd_params(struct net_buf *buf, struct bt_le_per_adv_sync *sync,
|
||||||
bool enable);
|
const struct bt_df_per_adv_sync_cte_rx_param *params,
|
||||||
|
bool enable);
|
||||||
static int hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool enable,
|
static int 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);
|
const struct bt_df_per_adv_sync_cte_rx_param *params);
|
||||||
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
|
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||||
|
static void 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);
|
||||||
|
static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
|
||||||
|
const struct bt_df_conn_cte_rx_param *params);
|
||||||
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
||||||
static int hci_df_set_cl_cte_tx_params(const struct bt_le_ext_adv *adv,
|
static int hci_df_set_cl_cte_tx_params(const struct bt_le_ext_adv *adv,
|
||||||
const struct bt_df_adv_cte_tx_param *params)
|
const struct bt_df_adv_cte_tx_param *params)
|
||||||
{
|
{
|
||||||
|
@ -200,38 +214,55 @@ static int hci_df_set_adv_cte_tx_enable(struct bt_le_ext_adv *adv,
|
||||||
buf, NULL);
|
buf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
|
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||||
static int validate_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params)
|
static bool validate_cte_rx_common_params(uint8_t cte_type, uint8_t slot_durations,
|
||||||
|
uint8_t num_ant_ids, const uint8_t *ant_ids)
|
||||||
{
|
{
|
||||||
if (!(params->cte_type &
|
if (!(cte_type & (BT_DF_CTE_TYPE_AOA | BT_DF_CTE_TYPE_AOD_1US | BT_DF_CTE_TYPE_AOD_2US))) {
|
||||||
(BT_DF_CTE_TYPE_AOA | BT_DF_CTE_TYPE_AOD_1US | BT_DF_CTE_TYPE_AOD_2US))) {
|
return false;
|
||||||
return -EINVAL;
|
}
|
||||||
|
|
||||||
|
if (cte_type & BT_DF_CTE_TYPE_AOA) {
|
||||||
|
if (df_ant_info.num_ant < DF_SAMPLING_ANTENNA_NUMBER_MIN ||
|
||||||
|
!BT_FEAT_LE_ANT_SWITCH_RX_AOA(bt_dev.le.features)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US ||
|
||||||
|
(slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US &&
|
||||||
|
DF_AOA_RX_1US_SUPPORT(df_ant_info.switch_sample_rates)))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
|
||||||
|
num_ant_ids > df_ant_info.max_switch_pattern_len || !ant_ids) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
|
||||||
|
static bool validate_cl_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params)
|
||||||
|
{
|
||||||
|
if (params->max_cte_count > BT_HCI_LE_SAMPLE_CTE_COUNT_MAX) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->cte_type & BT_DF_CTE_TYPE_AOA) {
|
if (params->cte_type & BT_DF_CTE_TYPE_AOA) {
|
||||||
if (df_ant_info.num_ant < DF_SAMPLING_ANTENNA_NUMBER_MIN ||
|
return validate_cte_rx_common_params(params->cte_type, params->slot_durations,
|
||||||
!BT_FEAT_LE_ANT_SWITCH_RX_AOA(bt_dev.le.features)) {
|
params->num_ant_ids, params->ant_ids);
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(params->slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US ||
|
|
||||||
(params->slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US &&
|
|
||||||
DF_AOA_RX_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 > df_ant_info.max_switch_pattern_len || !params->ant_ids) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_cte_rx_enable_cmd_params(struct net_buf *buf, struct bt_le_per_adv_sync *sync,
|
static void
|
||||||
const struct bt_df_per_adv_sync_cte_rx_param *params,
|
prepare_cl_cte_rx_enable_cmd_params(struct net_buf *buf, struct bt_le_per_adv_sync *sync,
|
||||||
bool enable)
|
const struct bt_df_per_adv_sync_cte_rx_param *params,
|
||||||
|
bool enable)
|
||||||
{
|
{
|
||||||
struct bt_hci_cp_le_set_cl_cte_sampling_enable *cp;
|
struct bt_hci_cp_le_set_cl_cte_sampling_enable *cp;
|
||||||
const uint8_t *ant_ids;
|
const uint8_t *ant_ids;
|
||||||
|
@ -253,7 +284,7 @@ static void prepare_cte_rx_enable_cmd_params(struct net_buf *buf, struct bt_le_p
|
||||||
ant_ids = params->ant_ids;
|
ant_ids = params->ant_ids;
|
||||||
} else {
|
} else {
|
||||||
/* Those values are put here due to constraints from HCI command
|
/* Those values are put here due to constraints from HCI command
|
||||||
* specification: Bluetooth Core Spec. Vol 4,Part E, sec 7.8.82.
|
* specification: Bluetooth Core Spec. 5.3 Vol 4,Part E, sec 7.8.82.
|
||||||
* There is no right way to successfully send the command to enable CTE
|
* There is no right way to successfully send the command to enable CTE
|
||||||
* receive for AoD mode (e.g. device equipped with single antenna).
|
* receive for AoD mode (e.g. device equipped with single antenna).
|
||||||
*/
|
*/
|
||||||
|
@ -263,7 +294,7 @@ static void prepare_cte_rx_enable_cmd_params(struct net_buf *buf, struct bt_le_p
|
||||||
}
|
}
|
||||||
|
|
||||||
dest_ant_ids = net_buf_add(buf, params->num_ant_ids);
|
dest_ant_ids = net_buf_add(buf, params->num_ant_ids);
|
||||||
memcpy(dest_ant_ids, params->ant_ids, params->num_ant_ids);
|
memcpy(dest_ant_ids, ant_ids, cp->switch_pattern_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,9 +307,8 @@ static int hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool ena
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
err = validate_cte_rx_params(params);
|
if (!validate_cl_cte_rx_params(params)) {
|
||||||
if (err != 0) {
|
return -EINVAL;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +322,7 @@ static int hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool ena
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_cte_rx_enable_cmd_params(buf, sync, params, enable);
|
prepare_cl_cte_rx_enable_cmd_params(buf, sync, params, enable);
|
||||||
|
|
||||||
bt_hci_cmd_state_set_init(buf, &state, sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED, enable);
|
bt_hci_cmd_state_set_init(buf, &state, sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED, enable);
|
||||||
|
|
||||||
|
@ -430,6 +460,90 @@ static int hci_df_set_conn_cte_tx_param(struct bt_conn *conn, uint8_t cte_types,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||||
|
static void 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)
|
||||||
|
{
|
||||||
|
struct bt_hci_cp_le_set_conn_cte_rx_params *cp;
|
||||||
|
const uint8_t *ant_ids;
|
||||||
|
|
||||||
|
cp = net_buf_add(buf, sizeof(*cp));
|
||||||
|
(void)memset(cp, 0, sizeof(*cp));
|
||||||
|
|
||||||
|
cp->handle = sys_cpu_to_le16(conn->handle);
|
||||||
|
cp->sampling_enable = enable ? 1 : 0;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
uint8_t *dest_ant_ids;
|
||||||
|
|
||||||
|
if (params->cte_type & BT_DF_CTE_TYPE_AOA) {
|
||||||
|
cp->slot_durations = params->slot_durations;
|
||||||
|
cp->switch_pattern_len = params->num_ant_ids;
|
||||||
|
ant_ids = params->ant_ids;
|
||||||
|
} else {
|
||||||
|
/* Those values are put here due to constraints from HCI command
|
||||||
|
* specification: Bluetooth Core Spec. 5.3 Vol 4,Part E, sec 7.8.85.
|
||||||
|
* There is no right way to successfully send the command to enable CTE
|
||||||
|
* receive for AoD mode (e.g. device equipped with single antenna).
|
||||||
|
*/
|
||||||
|
cp->slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US;
|
||||||
|
cp->switch_pattern_len = ARRAY_SIZE(df_dummy_switch_pattern);
|
||||||
|
ant_ids = &df_dummy_switch_pattern[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
dest_ant_ids = net_buf_add(buf, params->num_ant_ids);
|
||||||
|
(void)memcpy(dest_ant_ids, ant_ids, cp->switch_pattern_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
|
||||||
|
const struct bt_df_conn_cte_rx_param *params)
|
||||||
|
{
|
||||||
|
struct bt_hci_rp_le_set_conn_cte_rx_params *rp;
|
||||||
|
struct bt_hci_cmd_state_set state;
|
||||||
|
struct net_buf *buf, *rsp;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
if (!validate_cte_rx_common_params(params->cte_type, params->slot_durations,
|
||||||
|
params->num_ant_ids, params->ant_ids)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If CTE Rx is enabled, command parameters total length must include
|
||||||
|
* antenna ids, so command size if extended by num_and_ids.
|
||||||
|
*/
|
||||||
|
buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_CONN_CTE_RX_PARAMS,
|
||||||
|
(sizeof(struct bt_hci_rp_le_set_conn_cte_rx_params) +
|
||||||
|
(enable ? params->num_ant_ids : 0)));
|
||||||
|
if (!buf) {
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_conn_cte_rx_enable_cmd_params(buf, conn, params, enable);
|
||||||
|
|
||||||
|
bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_RX_ENABLED, enable);
|
||||||
|
|
||||||
|
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CONN_CTE_RX_PARAMS, buf, &rsp);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp = (void *)rsp->data;
|
||||||
|
if (conn->handle != sys_le16_to_cpu(rp->handle)) {
|
||||||
|
err = -EIO;
|
||||||
|
} else {
|
||||||
|
conn->cte_type = (enable ? params->cte_type : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
net_buf_unref(rsp);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
||||||
/* @brief Function initializes Direction Finding in Host
|
/* @brief Function initializes Direction Finding in Host
|
||||||
*
|
*
|
||||||
* @return Zero in case of success, other value in case of failure.
|
* @return Zero in case of success, other value in case of failure.
|
||||||
|
@ -562,3 +676,45 @@ int bt_df_per_adv_sync_cte_rx_disable(struct bt_le_per_adv_sync *sync)
|
||||||
return bt_df_set_per_adv_sync_cte_rx_enable(sync, false, NULL);
|
return bt_df_set_per_adv_sync_cte_rx_enable(sync, false, NULL);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
|
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||||
|
static int bt_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
|
||||||
|
const struct bt_df_conn_cte_rx_param *params)
|
||||||
|
{
|
||||||
|
if (!BT_FEAT_LE_RX_CTE(bt_dev.le.features)) {
|
||||||
|
BT_WARN("Receiving Constant Tone Extensions is not supported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->state != BT_CONN_CONNECTED) {
|
||||||
|
BT_ERR("not connected!");
|
||||||
|
return -ENOTCONN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hci_df_set_conn_cte_rx_enable(conn, enable, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_df_conn_cte_rx_enable(struct bt_conn *conn, const struct bt_df_conn_cte_rx_param *params)
|
||||||
|
{
|
||||||
|
CHECKIF(!conn)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
CHECKIF(!params)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bt_df_set_conn_cte_rx_enable(conn, true, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_df_conn_cte_rx_disable(struct bt_conn *conn)
|
||||||
|
{
|
||||||
|
CHECKIF(!conn)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bt_df_set_conn_cte_rx_enable(conn, false, NULL);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
|
@ -2964,7 +2964,8 @@ static int le_init(void)
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_BT_DF)
|
#if IS_ENABLED(CONFIG_BT_DF)
|
||||||
if (BT_FEAT_LE_CONNECTIONLESS_CTE_TX(bt_dev.le.features) ||
|
if (BT_FEAT_LE_CONNECTIONLESS_CTE_TX(bt_dev.le.features) ||
|
||||||
BT_FEAT_LE_CONNECTIONLESS_CTE_RX(bt_dev.le.features)) {
|
BT_FEAT_LE_CONNECTIONLESS_CTE_RX(bt_dev.le.features) ||
|
||||||
|
BT_FEAT_LE_RX_CTE(bt_dev.le.features)) {
|
||||||
err = le_df_init();
|
err = le_df_init();
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue