Bluetooth: controller: complete DF TX params set in conn mode
HCI_LE_Set_Connection_CTE_Transmit_Parameters host command was not completely implemented in controller. There were missign storage of TX parameters in ll_conn instance. The commit adds missing part of the command handling. Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
f650fd99e0
commit
1ff9baf010
9 changed files with 81 additions and 26 deletions
|
@ -102,7 +102,7 @@ config BT_CTLR_DF_CONN_CTE_REQ
|
||||||
|
|
||||||
config BT_CTLR_DF_CONN_CTE_RSP
|
config BT_CTLR_DF_CONN_CTE_RSP
|
||||||
bool "Enable Connection CTE Response feature"
|
bool "Enable Connection CTE Response feature"
|
||||||
depends on BT_CTLR_DF_CTE_TX && BT_CONN
|
depends on BT_CTLR_DF_CONN_CTE_TX
|
||||||
help
|
help
|
||||||
Enable support for Bluetooth v5.1 Connection CTE Response feature
|
Enable support for Bluetooth v5.1 Connection CTE Response feature
|
||||||
in controller.
|
in controller.
|
||||||
|
@ -124,6 +124,14 @@ config BT_CTLR_DF_SCAN_CTE_RX
|
||||||
Enable support for Bluetooth v5.1 connectionless CTE reception
|
Enable support for Bluetooth v5.1 connectionless CTE reception
|
||||||
in controller.
|
in controller.
|
||||||
|
|
||||||
|
config BT_CTLR_DF_CONN_CTE_TX
|
||||||
|
bool "Enable Connection based CTE Transmitter"
|
||||||
|
depends on BT_CTLR_DF_CTE_TX && BT_CONN
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable transmission of Constant Tone Extension in
|
||||||
|
direction finding connected mode.
|
||||||
|
|
||||||
config BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC
|
config BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC
|
||||||
bool "Enable sampling of CTE for PDUs with bad CRC"
|
bool "Enable sampling of CTE for PDUs with bad CRC"
|
||||||
depends on BT_CTLR_DF_SCAN_CTE_RX
|
depends on BT_CTLR_DF_SCAN_CTE_RX
|
||||||
|
|
|
@ -2858,7 +2858,7 @@ static void le_df_connectionless_iq_report(struct pdu_data *pdu_rx,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
|
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_TX)
|
||||||
static void le_df_set_conn_cte_tx_params(struct net_buf *buf,
|
static void le_df_set_conn_cte_tx_params(struct net_buf *buf,
|
||||||
struct net_buf **evt)
|
struct net_buf **evt)
|
||||||
{
|
{
|
||||||
|
@ -2879,7 +2879,7 @@ static void le_df_set_conn_cte_tx_params(struct net_buf *buf,
|
||||||
rp->status = status;
|
rp->status = status;
|
||||||
rp->handle = handle_le16;
|
rp->handle = handle_le16;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
||||||
static void le_df_set_conn_cte_rx_params(struct net_buf *buf, struct net_buf **evt)
|
static void le_df_set_conn_cte_rx_params(struct net_buf *buf, struct net_buf **evt)
|
||||||
|
@ -4238,11 +4238,11 @@ static int controller_cmd_handle(uint16_t ocf, struct net_buf *cmd,
|
||||||
case BT_OCF(BT_HCI_OP_LE_READ_ANT_INFO):
|
case BT_OCF(BT_HCI_OP_LE_READ_ANT_INFO):
|
||||||
le_df_read_ant_inf(cmd, evt);
|
le_df_read_ant_inf(cmd, evt);
|
||||||
break;
|
break;
|
||||||
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_TX)
|
||||||
case BT_OCF(BT_HCI_OP_LE_SET_CONN_CTE_TX_PARAMS):
|
case BT_OCF(BT_HCI_OP_LE_SET_CONN_CTE_TX_PARAMS):
|
||||||
le_df_set_conn_cte_tx_params(cmd, evt);
|
le_df_set_conn_cte_tx_params(cmd, evt);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */
|
||||||
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
||||||
case BT_OCF(BT_HCI_OP_LE_SET_CONN_CTE_RX_PARAMS):
|
case BT_OCF(BT_HCI_OP_LE_SET_CONN_CTE_RX_PARAMS):
|
||||||
le_df_set_conn_cte_rx_params(cmd, evt);
|
le_df_set_conn_cte_rx_params(cmd, evt);
|
||||||
|
|
|
@ -297,8 +297,7 @@ uint8_t ll_df_set_cl_cte_tx_params(uint8_t adv_handle, uint8_t cte_len,
|
||||||
uint8_t ll_df_set_cl_cte_tx_enable(uint8_t adv_handle, uint8_t cte_enable);
|
uint8_t ll_df_set_cl_cte_tx_enable(uint8_t adv_handle, uint8_t cte_enable);
|
||||||
/* Provides information about antennae switching and sampling settings */
|
/* Provides information about antennae switching and sampling settings */
|
||||||
uint8_t ll_df_set_conn_cte_tx_params(uint16_t handle, uint8_t cte_types,
|
uint8_t ll_df_set_conn_cte_tx_params(uint16_t handle, uint8_t cte_types,
|
||||||
uint8_t switching_patterns_len,
|
uint8_t switching_patterns_len, const uint8_t *ant_id);
|
||||||
uint8_t *ant_id);
|
|
||||||
/* Enables or disables CTE sampling in direction fingin connected mode. */
|
/* Enables or disables CTE sampling in direction fingin connected mode. */
|
||||||
uint8_t ll_df_set_conn_cte_rx_params(uint16_t handle, uint8_t sampling_enable,
|
uint8_t ll_df_set_conn_cte_rx_params(uint16_t handle, uint8_t sampling_enable,
|
||||||
uint8_t slot_durations, uint8_t switch_pattern_len,
|
uint8_t slot_durations, uint8_t switch_pattern_len,
|
||||||
|
|
|
@ -151,6 +151,9 @@ struct lll_conn {
|
||||||
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
||||||
struct lll_df_conn_rx_params df_rx_params;
|
struct lll_df_conn_rx_params df_rx_params;
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
||||||
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_TX)
|
||||||
|
struct lll_df_conn_tx_cfg df_tx_cfg;
|
||||||
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */
|
||||||
};
|
};
|
||||||
|
|
||||||
int lll_conn_init(void);
|
int lll_conn_init(void);
|
||||||
|
|
|
@ -860,7 +860,7 @@ static void empty_tx_init(void)
|
||||||
|
|
||||||
p = (void *)radio_pkt_empty_get();
|
p = (void *)radio_pkt_empty_get();
|
||||||
p->ll_id = PDU_DATA_LLID_DATA_CONTINUE;
|
p->ll_id = PDU_DATA_LLID_DATA_CONTINUE;
|
||||||
p->cp = PDU_DATA_CTE_PRESENT_BIT_DISABLED;
|
p->cp = false;
|
||||||
#if !defined(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR)
|
#if !defined(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR)
|
||||||
p->resv = 0U;
|
p->resv = 0U;
|
||||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH_CLEAR */
|
#endif /* CONFIG_BT_CTLR_DATA_LENGTH_CLEAR */
|
||||||
|
|
|
@ -109,6 +109,11 @@ enum df_cte_sampling_state {
|
||||||
DF_CTE_SAMPLING_DISABLED,
|
DF_CTE_SAMPLING_DISABLED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Names for allowed states for CTE transmit parameters in connected mode */
|
||||||
|
enum df_cte_tx_state {
|
||||||
|
DF_CTE_CONN_TX_PARAMS_UNINITIALIZED,
|
||||||
|
DF_CTE_CONN_TX_PARAMS_SET,
|
||||||
|
};
|
||||||
/* Parameters for reception of Constant Tone Extension in connected mode */
|
/* Parameters for reception of Constant Tone Extension in connected mode */
|
||||||
struct lll_df_conn_rx_params {
|
struct lll_df_conn_rx_params {
|
||||||
uint8_t state : 2;
|
uint8_t state : 2;
|
||||||
|
@ -119,9 +124,6 @@ struct lll_df_conn_rx_params {
|
||||||
|
|
||||||
/* @brief Structure to store data required to prepare LE Connection IQ Report event or LE
|
/* @brief Structure to store data required to prepare LE Connection IQ Report event or LE
|
||||||
* Connectionless IQ Report event.
|
* Connectionless IQ Report event.
|
||||||
*
|
|
||||||
* TODO (ppryga): use struct cte_conn_iq_report in connected mode. Members are exactly the same as
|
|
||||||
* members of node_rx_iq_report except hdr.
|
|
||||||
*/
|
*/
|
||||||
struct cte_conn_iq_report {
|
struct cte_conn_iq_report {
|
||||||
struct pdu_cte_info cte_info;
|
struct pdu_cte_info cte_info;
|
||||||
|
@ -134,3 +136,14 @@ struct cte_conn_iq_report {
|
||||||
struct iq_sample sample[0];
|
struct iq_sample sample[0];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Configuration for transmission of Constant Tone Extension in connected mode */
|
||||||
|
struct lll_df_conn_tx_cfg {
|
||||||
|
uint8_t state:1;
|
||||||
|
uint8_t ant_sw_len:7;
|
||||||
|
uint8_t cte_type:2;
|
||||||
|
uint8_t cte_length:6; /* Length of CTE in 8us units */
|
||||||
|
uint8_t cte_rsp_en:1; /* CTE response is enabled */
|
||||||
|
uint8_t cte_types_allowed:3; /* Bitfield with allowed CTE types */
|
||||||
|
uint8_t ant_ids[BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN];
|
||||||
|
};
|
||||||
|
|
|
@ -34,9 +34,9 @@
|
||||||
#include "lll_adv.h"
|
#include "lll_adv.h"
|
||||||
#include "lll/lll_adv_pdu.h"
|
#include "lll/lll_adv_pdu.h"
|
||||||
#include "lll_scan.h"
|
#include "lll_scan.h"
|
||||||
|
#include "lll/lll_df_types.h"
|
||||||
#include "lll_conn.h"
|
#include "lll_conn.h"
|
||||||
#include "lll_filter.h"
|
#include "lll_filter.h"
|
||||||
#include "lll/lll_df_types.h"
|
|
||||||
|
|
||||||
#if !defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
#if !defined(CONFIG_BT_LL_SW_LLCP_LEGACY)
|
||||||
#include "ll_sw/ull_tx_queue.h"
|
#include "ll_sw/ull_tx_queue.h"
|
||||||
|
|
|
@ -2058,7 +2058,7 @@ void ull_pdu_data_init(struct pdu_data *pdu_tx)
|
||||||
{
|
{
|
||||||
LL_ASSERT(pdu_tx);
|
LL_ASSERT(pdu_tx);
|
||||||
|
|
||||||
pdu_tx->cp = PDU_DATA_CTE_PRESENT_BIT_DISABLED;
|
pdu_tx->cp = false;
|
||||||
pdu_tx->rfu = 0U;
|
pdu_tx->rfu = 0U;
|
||||||
#if !defined(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR)
|
#if !defined(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR)
|
||||||
pdu_tx->resv = 0U;
|
pdu_tx->resv = 0U;
|
||||||
|
|
|
@ -233,11 +233,9 @@ uint8_t ll_df_set_cl_cte_tx_params(uint8_t adv_handle, uint8_t cte_len,
|
||||||
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cte_type == BT_HCI_LE_AOD_CTE_1US ||
|
if ((cte_type == BT_HCI_LE_AOD_CTE_1US || cte_type == BT_HCI_LE_AOD_CTE_2US) &&
|
||||||
cte_type == BT_HCI_LE_AOD_CTE_2US) &&
|
(num_ant_ids < BT_HCI_LE_CTE_LEN_MIN ||
|
||||||
(num_ant_ids < LLL_DF_MIN_ANT_PATTERN_LEN ||
|
num_ant_ids > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN || !ant_ids)) {
|
||||||
num_ant_ids > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN ||
|
|
||||||
!ant_ids)) {
|
|
||||||
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -961,7 +959,7 @@ static uint8_t cte_info_clear(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
|
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
|
||||||
|
|
||||||
#if defined CONFIG_BT_CTLR_DF_CONN_CTE_RSP
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_TX)
|
||||||
/* @brief Function sets CTE transmission parameters for a connection.
|
/* @brief Function sets CTE transmission parameters for a connection.
|
||||||
*
|
*
|
||||||
* @param handle Connection handle.
|
* @param handle Connection handle.
|
||||||
|
@ -973,22 +971,56 @@ static uint8_t cte_info_clear(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_
|
||||||
* @return Status of command completion.
|
* @return Status of command completion.
|
||||||
*/
|
*/
|
||||||
uint8_t ll_df_set_conn_cte_tx_params(uint16_t handle, uint8_t cte_types, uint8_t switch_pattern_len,
|
uint8_t ll_df_set_conn_cte_tx_params(uint16_t handle, uint8_t cte_types, uint8_t switch_pattern_len,
|
||||||
uint8_t *ant_id)
|
const uint8_t *ant_ids)
|
||||||
{
|
{
|
||||||
if (cte_types & BT_HCI_LE_AOD_CTE_RSP_1US || cte_types & BT_HCI_LE_AOD_CTE_RSP_2US) {
|
struct lll_df_conn_tx_cfg *df_tx_cfg;
|
||||||
if (!IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX)) {
|
struct ll_conn *conn;
|
||||||
|
|
||||||
|
conn = ll_connected_get(handle);
|
||||||
|
if (!conn) {
|
||||||
|
return BT_HCI_ERR_UNKNOWN_CONN_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
df_tx_cfg = &conn->lll.df_tx_cfg;
|
||||||
|
|
||||||
|
if (df_tx_cfg->cte_rsp_en) {
|
||||||
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bits other than representing AoA, AoD 1us, AoD 2us are RFU */
|
||||||
|
if (cte_types == 0U ||
|
||||||
|
((cte_types & (~(uint8_t)(BT_HCI_LE_AOA_CTE_RSP | BT_HCI_LE_AOD_CTE_RSP_1US |
|
||||||
|
BT_HCI_LE_AOD_CTE_RSP_2US))) != 0U)) {
|
||||||
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX)) {
|
||||||
|
if (cte_types & BT_HCI_LE_AOD_CTE_RSP_2US) {
|
||||||
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
|
if ((cte_types & BT_HCI_LE_AOD_CTE_RSP_1US) &&
|
||||||
switch_pattern_len > BT_HCI_LE_SWITCH_PATTERN_LEN_MAX || !ant_id) {
|
!IS_ENABLED(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)) {
|
||||||
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
/* Check antenna switching pattern only whether CTE TX in AoD mode is allowed */
|
||||||
|
if (((cte_types & BT_HCI_LE_AOD_CTE_RSP_1US) || (cte_types & BT_HCI_LE_AOD_CTE_RSP_2US)) &&
|
||||||
|
(switch_pattern_len < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
|
||||||
|
switch_pattern_len > BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN || !ant_ids)) {
|
||||||
|
return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)memcpy(df_tx_cfg->ant_ids, ant_ids, switch_pattern_len);
|
||||||
|
df_tx_cfg->ant_sw_len = switch_pattern_len;
|
||||||
|
|
||||||
|
df_tx_cfg->cte_types_allowed = cte_types;
|
||||||
|
df_tx_cfg->state = DF_CTE_CONN_TX_PARAMS_SET;
|
||||||
|
|
||||||
|
return BT_HCI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RSP */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
||||||
/* @brief Function sets CTE reception parameters for a connection.
|
/* @brief Function sets CTE reception parameters for a connection.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue