Bluetooth: host: Add API to HCI CTE conn request enable procedure
There were no implementation for HCI_LE_Connection_CTE_Request_Enable command from BT 5.3 Core specification. The PR adds implementation and API to be used by applications. Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
1bb7aa21b8
commit
b76b5750ee
4 changed files with 196 additions and 4 deletions
|
@ -13,11 +13,15 @@ enum bt_df_cte_type {
|
||||||
BT_DF_CTE_TYPE_NONE = 0,
|
BT_DF_CTE_TYPE_NONE = 0,
|
||||||
/** Angle of Arrival mode. Antenna switching done on receiver site. */
|
/** Angle of Arrival mode. Antenna switching done on receiver site. */
|
||||||
BT_DF_CTE_TYPE_AOA = BIT(0),
|
BT_DF_CTE_TYPE_AOA = BIT(0),
|
||||||
/** Angle of Departure mode with 1 us antenna switching slots.
|
/**
|
||||||
|
* @brief Angle of Departure mode with 1 us antenna switching slots.
|
||||||
|
*
|
||||||
* Antenna switching done on transmitter site.
|
* Antenna switching done on transmitter site.
|
||||||
*/
|
*/
|
||||||
BT_DF_CTE_TYPE_AOD_1US = BIT(1),
|
BT_DF_CTE_TYPE_AOD_1US = BIT(1),
|
||||||
/** Angle of Departure mode with 2 us antenna switching slots.
|
/**
|
||||||
|
* @brief Angle of Departure mode with 2 us antenna switching slots.
|
||||||
|
*
|
||||||
* Antenna switching done on transmitter site.
|
* Antenna switching done on transmitter site.
|
||||||
*/
|
*/
|
||||||
BT_DF_CTE_TYPE_AOD_2US = BIT(2),
|
BT_DF_CTE_TYPE_AOD_2US = BIT(2),
|
||||||
|
@ -155,6 +159,25 @@ struct bt_df_conn_cte_tx_param {
|
||||||
const uint8_t *ant_ids;
|
const uint8_t *ant_ids;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bt_df_conn_cte_req_params {
|
||||||
|
/**
|
||||||
|
* @brief Requested interval for initiating the CTE Request procedure.
|
||||||
|
*
|
||||||
|
* Value 0x0 means, run the procedure once. Other values are intervals in number of
|
||||||
|
* connection events, to run the command periodically.
|
||||||
|
*/
|
||||||
|
uint8_t interval;
|
||||||
|
/** Requested length of the CTE in 8 us units. */
|
||||||
|
uint8_t cte_length;
|
||||||
|
/**
|
||||||
|
* @brief Requested type of the CTE.
|
||||||
|
*
|
||||||
|
* Allowed values are defined by @ref bt_df_cte_type, except BT_DF_CTE_TYPE_NONE and
|
||||||
|
* BT_DF_CTE_TYPE_ALL.
|
||||||
|
*/
|
||||||
|
uint8_t cte_type;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
*
|
*
|
||||||
|
@ -246,6 +269,29 @@ int bt_df_conn_cte_rx_disable(struct bt_conn *conn);
|
||||||
*/
|
*/
|
||||||
int bt_df_set_conn_cte_tx_param(struct bt_conn *conn, const struct bt_df_conn_cte_tx_param *params);
|
int bt_df_set_conn_cte_tx_param(struct bt_conn *conn, const struct bt_df_conn_cte_tx_param *params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable Constant Tone Extension request procedure for a connection.
|
||||||
|
*
|
||||||
|
* The function is available if @kconfig{CONFIG_BT_DF_CONNECTION_CTE_REQ} is enabled.
|
||||||
|
*
|
||||||
|
* @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_req_enable(struct bt_conn *conn, const struct bt_df_conn_cte_req_params *params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable Constant Tone Extension request procedure for a connection.
|
||||||
|
*
|
||||||
|
* The function is available if @kconfig{CONFIG_BT_DF_CONNECTION_CTE_REQ} is enabled.
|
||||||
|
*
|
||||||
|
* @param conn Connection object.
|
||||||
|
*
|
||||||
|
* @return Zero in case of success, other value in case of failure.
|
||||||
|
*/
|
||||||
|
int bt_df_conn_cte_req_disable(struct bt_conn *conn);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable Constant Tone Extension response procedure for a connection.
|
* @brief Enable Constant Tone Extension response procedure for a connection.
|
||||||
*
|
*
|
||||||
|
|
|
@ -566,6 +566,13 @@ config BT_DF_CONNECTION_CTE_TX
|
||||||
Enable support for transmission of Constant Tone Extension in
|
Enable support for transmission of Constant Tone Extension in
|
||||||
connection mode.
|
connection mode.
|
||||||
|
|
||||||
|
config BT_DF_CONNECTION_CTE_REQ
|
||||||
|
bool "Enable support for CTE request procedure in connection mode"
|
||||||
|
depends on BT_DF_CONNECTION_CTE_RX
|
||||||
|
help
|
||||||
|
Enable support for request of Constant Tone Extension in connection
|
||||||
|
mode.
|
||||||
|
|
||||||
config BT_DF_CONNECTION_CTE_RSP
|
config BT_DF_CONNECTION_CTE_RSP
|
||||||
bool "Enable support for CTE request procedure in connection mode"
|
bool "Enable support for CTE request procedure in connection mode"
|
||||||
depends on BT_DF_CONNECTION_CTE_TX
|
depends on BT_DF_CONNECTION_CTE_TX
|
||||||
|
|
|
@ -44,7 +44,9 @@ enum {
|
||||||
BT_CONN_AUTO_DATA_LEN_COMPLETE,
|
BT_CONN_AUTO_DATA_LEN_COMPLETE,
|
||||||
|
|
||||||
BT_CONN_CTE_RX_ENABLED, /* CTE receive and sampling is enabled */
|
BT_CONN_CTE_RX_ENABLED, /* CTE receive and sampling is enabled */
|
||||||
|
BT_CONN_CTE_RX_PARAMS_SET, /* CTE parameters are set */
|
||||||
BT_CONN_CTE_TX_PARAMS_SET, /* CTE transmission parameters are set */
|
BT_CONN_CTE_TX_PARAMS_SET, /* CTE transmission parameters are set */
|
||||||
|
BT_CONN_CTE_REQ_ENABLED, /* CTE request procedure is enabled */
|
||||||
BT_CONN_CTE_RSP_ENABLED, /* CTE response procedure is enabled */
|
BT_CONN_CTE_RSP_ENABLED, /* CTE response procedure 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 */
|
||||||
|
|
|
@ -69,6 +69,21 @@ static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
|
||||||
const struct bt_df_conn_cte_rx_param *params);
|
const struct bt_df_conn_cte_rx_param *params);
|
||||||
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
||||||
|
static uint8_t get_hci_cte_type(enum bt_df_cte_type type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case BT_DF_CTE_TYPE_AOA:
|
||||||
|
return BT_HCI_LE_AOA_CTE;
|
||||||
|
case BT_DF_CTE_TYPE_AOD_1US:
|
||||||
|
return BT_HCI_LE_AOD_CTE_1US;
|
||||||
|
case BT_DF_CTE_TYPE_AOD_2US:
|
||||||
|
return BT_HCI_LE_AOD_CTE_2US;
|
||||||
|
default:
|
||||||
|
BT_ERR("Wrong CTE type");
|
||||||
|
return BT_HCI_LE_NO_CTE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -564,6 +579,11 @@ static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
} else {
|
} else {
|
||||||
conn->cte_type = (enable ? params->cte_type : 0);
|
conn->cte_type = (enable ? params->cte_type : 0);
|
||||||
|
/* This flag is set once for connection object. It is never cleared because CTE RX
|
||||||
|
* params must be set at least once for connection object to successfully execute
|
||||||
|
* CTE REQ procedure.
|
||||||
|
*/
|
||||||
|
atomic_set_bit(conn->flags, BT_CONN_CTE_RX_PARAMS_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
net_buf_unref(rsp);
|
net_buf_unref(rsp);
|
||||||
|
@ -621,6 +641,78 @@ int hci_df_prepare_connection_iq_report(struct net_buf *buf,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DF_CONNECTION_CTE_REQ)
|
||||||
|
static bool valid_cte_req_params(const struct bt_conn *conn, uint8_t cte_type,
|
||||||
|
uint8_t cte_length)
|
||||||
|
{
|
||||||
|
if (!(conn->cte_type & cte_type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cte_length < BT_HCI_LE_CTE_LEN_MIN || cte_length > BT_HCI_LE_CTE_LEN_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void 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)
|
||||||
|
{
|
||||||
|
struct bt_hci_cp_le_conn_cte_req_enable *cp;
|
||||||
|
|
||||||
|
cp = net_buf_add(buf, sizeof(*cp));
|
||||||
|
(void)memset(cp, 0, sizeof(*cp));
|
||||||
|
|
||||||
|
cp->handle = sys_cpu_to_le16(conn->handle);
|
||||||
|
cp->enable = enable ? 1 : 0;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
cp->cte_request_interval = params->interval;
|
||||||
|
cp->requested_cte_length = params->cte_length;
|
||||||
|
cp->requested_cte_type = get_hci_cte_type(params->cte_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hci_df_set_conn_cte_req_enable(struct bt_conn *conn, bool enable,
|
||||||
|
const struct bt_df_conn_cte_req_params *params)
|
||||||
|
{
|
||||||
|
struct bt_hci_cp_le_conn_cte_req_enable *rp;
|
||||||
|
struct bt_hci_cmd_state_set state;
|
||||||
|
struct net_buf *buf, *rsp;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (enable && !valid_cte_req_params(conn, params->cte_length, params->cte_type)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_CTE_REQ_ENABLE,
|
||||||
|
sizeof(struct bt_hci_cp_le_conn_cte_req_enable));
|
||||||
|
if (!buf) {
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_conn_cte_req_enable_cmd_params(buf, conn, params, enable);
|
||||||
|
|
||||||
|
bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_REQ_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_buf_unref(rsp);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RSP)
|
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RSP)
|
||||||
static void prepare_conn_cte_rsp_enable_cmd_params(struct net_buf *buf, const struct bt_conn *conn,
|
static void prepare_conn_cte_rsp_enable_cmd_params(struct net_buf *buf, const struct bt_conn *conn,
|
||||||
bool enable)
|
bool enable)
|
||||||
|
@ -866,6 +958,51 @@ int bt_df_set_conn_cte_tx_param(struct bt_conn *conn, const struct bt_df_conn_ct
|
||||||
|
|
||||||
#endif /* CONFIG_BT_DF_CONNECTION_CTE_TX */
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_TX */
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_DF_CONNECTION_CTE_REQ)
|
||||||
|
static int bt_df_set_conn_cte_req_enable(struct bt_conn *conn, bool enable,
|
||||||
|
const struct bt_df_conn_cte_req_params *params)
|
||||||
|
{
|
||||||
|
if (!BT_FEAT_LE_CONNECTION_CTE_REQ(bt_dev.le.features)) {
|
||||||
|
BT_WARN("Constant Tone Extensions request procedure is not supported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->state != BT_CONN_CONNECTED) {
|
||||||
|
BT_ERR("not connected!");
|
||||||
|
return -ENOTCONN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!atomic_test_bit(conn->flags, BT_CONN_CTE_RX_PARAMS_SET)) {
|
||||||
|
BT_ERR("Can't start CTE requres procedure before CTE RX params setup");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hci_df_set_conn_cte_req_enable(conn, enable, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_df_conn_cte_req_enable(struct bt_conn *conn, const struct bt_df_conn_cte_req_params *params)
|
||||||
|
{
|
||||||
|
CHECKIF(!conn) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECKIF(!params) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bt_df_set_conn_cte_req_enable(conn, true, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_df_conn_cte_req_disable(struct bt_conn *conn)
|
||||||
|
{
|
||||||
|
CHECKIF(!conn) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bt_df_set_conn_cte_req_enable(conn, false, NULL);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RSP)
|
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RSP)
|
||||||
static int bt_df_set_conn_cte_rsp_enable(struct bt_conn *conn, bool enable)
|
static int bt_df_set_conn_cte_rsp_enable(struct bt_conn *conn, bool enable)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue