bluetooth: host: CS support for CS Test

Adds HCI support for the LE CS Test command.

Signed-off-by: Olivier Lesage <olivier.lesage@nordicsemi.no>
This commit is contained in:
Olivier Lesage 2024-09-15 23:59:47 +02:00 committed by Fabio Baltieri
parent 947a294d36
commit fb9a8eb316
4 changed files with 782 additions and 0 deletions

View file

@ -60,6 +60,451 @@ struct bt_cs_set_default_settings_param {
int8_t max_tx_power;
};
/** CS Test Main Mode */
enum bt_cs_test_main_mode {
/** CS Test Mode-1 */
BT_CS_TEST_MAIN_MODE_1 = BT_HCI_OP_LE_CS_MAIN_MODE_1,
/** CS Test Mode-2 */
BT_CS_TEST_MAIN_MODE_2 = BT_HCI_OP_LE_CS_MAIN_MODE_2,
/** CS Test Mode-3 */
BT_CS_TEST_MAIN_MODE_3 = BT_HCI_OP_LE_CS_MAIN_MODE_3,
};
/** CS Test Sub-Mode */
enum bt_cs_test_sub_mode {
/** CS Test sub-mode-1 */
BT_CS_TEST_SUB_MODE_1 = BT_HCI_OP_LE_CS_SUB_MODE_1,
/** CS Test sub-mode-2 */
BT_CS_TEST_SUB_MODE_2 = BT_HCI_OP_LE_CS_SUB_MODE_2,
/** CS Test sub-mode-3 */
BT_CS_TEST_SUB_MODE_3 = BT_HCI_OP_LE_CS_SUB_MODE_3,
/** No CS Test sub-mode. */
BT_CS_TEST_SUB_MODE_UNUSED = BT_HCI_OP_LE_CS_SUB_MODE_UNUSED,
};
/** CS Test Role */
enum bt_cs_test_role {
BT_CS_TEST_ROLE_INITIATOR = BT_HCI_OP_LE_CS_INITIATOR_ROLE,
BT_CS_TEST_ROLE_REFLECTOR = BT_HCI_OP_LE_CS_REFLECTOR_ROLE,
};
/** CS Test RTT type */
enum bt_cs_test_rtt_type {
/** RTT AA Only */
BT_CS_TEST_RTT_AA_ONLY = BT_HCI_OP_LE_CS_RTT_TYPE_AA_ONLY,
/** RTT with 32-bit sounding sequence */
BT_CS_TEST_RTT_32_BIT_SOUNDING = BT_HCI_OP_LE_CS_RTT_TYPE_32BIT_SOUND,
/** RTT with 96-bit sounding sequence */
BT_CS_TEST_RTT_96_BIT_SOUNDING = BT_HCI_OP_LE_CS_RTT_TYPE_96BIT_SOUND,
/** RTT with 32-bit random sequence */
BT_CS_TEST_RTT_32_BIT_RANDOM = BT_HCI_OP_LE_CS_RTT_TYPE_32BIT_RAND,
/** RTT with 64-bit random sequence */
BT_CS_TEST_RTT_64_BIT_RANDOM = BT_HCI_OP_LE_CS_RTT_TYPE_64BIT_RAND,
/** RTT with 96-bit random sequence */
BT_CS_TEST_RTT_96_BIT_RANDOM = BT_HCI_OP_LE_CS_RTT_TYPE_96BIT_RAND,
/** RTT with 128-bit random sequence */
BT_CS_TEST_RTT_128_BIT_RANDOM = BT_HCI_OP_LE_CS_RTT_TYPE_128BIT_RAND,
};
/** CS Test CS_SYNC PHY */
enum bt_cs_test_cs_sync_phy {
BT_CS_TEST_CS_SYNC_LE_1M_PHY = BT_HCI_OP_LE_CS_CS_SYNC_1M,
BT_CS_TEST_CS_SYNC_LE_2M_PHY = BT_HCI_OP_LE_CS_CS_SYNC_2M,
BT_CS_TEST_CS_SYNC_LE_2M_2BT_PHY = BT_HCI_OP_LE_CS_CS_SYNC_2M_2BT,
};
/** CS Test CS_SYNC Antenna Identifier */
enum bt_cs_test_cs_sync_antenna_selection {
BT_CS_TEST_CS_SYNC_ANTENNA_SELECTION_ONE = BT_HCI_OP_LE_CS_ANTENNA_SEL_ONE,
BT_CS_TEST_CS_SYNC_ANTENNA_SELECTION_TWO = BT_HCI_OP_LE_CS_ANTENNA_SEL_TWO,
BT_CS_TEST_CS_SYNC_ANTENNA_SELECTION_THREE = BT_HCI_OP_LE_CS_ANTENNA_SEL_THREE,
BT_CS_TEST_CS_SYNC_ANTENNA_SELECTION_FOUR = BT_HCI_OP_LE_CS_ANTENNA_SEL_FOUR,
};
/** CS Test Tone Antennna Config Selection.
*
* These enum values are indices in the following table, where N_AP is the maximum
* number of antenna paths (in the range [1, 4]).
*
* +--------------+-------------+-------------------+-------------------+--------+
* | Config Index | Total Paths | Dev A: # Antennas | Dev B: # Antennas | Config |
* +--------------+-------------+-------------------+-------------------+--------+
* | 0 | 1 | 1 | 1 | 1:1 |
* | 1 | 2 | 2 | 1 | N_AP:1 |
* | 2 | 3 | 3 | 1 | N_AP:1 |
* | 3 | 4 | 4 | 1 | N_AP:1 |
* | 4 | 2 | 1 | 2 | 1:N_AP |
* | 5 | 3 | 1 | 3 | 1:N_AP |
* | 6 | 4 | 1 | 4 | 1:N_AP |
* | 7 | 4 | 2 | 2 | 2:2 |
* +--------------+-------------+-------------------+-------------------+--------+
*
* There are therefore four groups of possible antenna configurations:
*
* - 1:1 configuration, where both A and B support 1 antenna each
* - 1:N_AP configuration, where A supports 1 antenna, B supports N_AP antennas, and
* N_AP is a value in the range [2, 4]
* - N_AP:1 configuration, where A supports N_AP antennas, B supports 1 antenna, and
* N_AP is a value in the range [2, 4]
* - 2:2 configuration, where both A and B support 2 antennas and N_AP = 4
*/
enum bt_cs_test_tone_antenna_config_selection {
BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_ONE = BT_HCI_OP_LE_CS_TEST_ACI_0,
BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_TWO = BT_HCI_OP_LE_CS_TEST_ACI_1,
BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_THREE = BT_HCI_OP_LE_CS_TEST_ACI_2,
BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_FOUR = BT_HCI_OP_LE_CS_TEST_ACI_3,
BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_FIVE = BT_HCI_OP_LE_CS_TEST_ACI_4,
BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_SIX = BT_HCI_OP_LE_CS_TEST_ACI_5,
BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_SEVEN = BT_HCI_OP_LE_CS_TEST_ACI_6,
BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_EIGHT = BT_HCI_OP_LE_CS_TEST_ACI_7,
};
/** CS Test Initiator SNR control options */
enum bt_cs_test_initiator_snr_control {
BT_CS_TEST_INITIATOR_SNR_CONTROL_18dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_18,
BT_CS_TEST_INITIATOR_SNR_CONTROL_21dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_21,
BT_CS_TEST_INITIATOR_SNR_CONTROL_24dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_24,
BT_CS_TEST_INITIATOR_SNR_CONTROL_27dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_27,
BT_CS_TEST_INITIATOR_SNR_CONTROL_30dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_30,
BT_CS_TEST_INITIATOR_SNR_CONTROL_NOT_USED = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_NOT_USED,
};
/** CS Test Reflector SNR control options */
enum bt_cs_test_reflector_snr_control {
BT_CS_TEST_REFLECTOR_SNR_CONTROL_18dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_18,
BT_CS_TEST_REFLECTOR_SNR_CONTROL_21dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_21,
BT_CS_TEST_REFLECTOR_SNR_CONTROL_24dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_24,
BT_CS_TEST_REFLECTOR_SNR_CONTROL_27dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_27,
BT_CS_TEST_REFLECTOR_SNR_CONTROL_30dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_30,
BT_CS_TEST_REFLECTOR_SNR_CONTROL_NOT_USED = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_NOT_USED,
};
/** CS Test Override 0 channel selection algorithm selection */
enum bt_cs_test_override_0_chsel_alg {
BT_CS_TEST_OVERRIDE_0_CHSEL_ALG_3B = BT_HCI_OP_LE_CS_TEST_CHSEL_TYPE_3B,
BT_CS_TEST_OVERRIDE_0_CHSEL_ALG_3C = BT_HCI_OP_LE_CS_TEST_CHSEL_TYPE_3C,
};
/** CS Test Override 0 chsel #3c shape */
enum bt_cs_test_override_0_ch3c_shape {
BT_CS_TEST_OVERRIDE_0_CHSEL_ALG_3C_HAT_SHAPE = BT_HCI_OP_LE_CS_TEST_CH3C_SHAPE_HAT,
BT_CS_TEST_OVERRIDE_0_CHSEL_ALG_3C_X_SHAPE = BT_HCI_OP_LE_CS_TEST_CH3C_SHAPE_X,
};
/** CS Test Override 3 T_PM Tone Extension */
enum bt_cs_test_override_3_pm_tone_ext {
/** Initiator and reflector tones sent without tone extension */
BT_CS_TEST_OVERRIDE_3_NO_TONE_EXT = BT_HCI_OP_LE_CS_TEST_TONE_EXT_NONE,
/** Initiator tone sent with extension, reflector tone sent without tone extension */
BT_CS_TEST_OVERRIDE_3_INITIATOR_TONE_EXT_ONLY = BT_HCI_OP_LE_CS_TEST_TONE_EXT_INIT,
/** Initiator tone sent without extension, reflector tone sent with tone extension */
BT_CS_TEST_OVERRIDE_3_REFLECTOR_TONE_EXT_ONLY = BT_HCI_OP_LE_CS_TEST_TONE_EXT_REFL,
/** Initiator and reflector tones sent with tone extension */
BT_CS_TEST_OVERRIDE_3_INITIATOR_AND_REFLECTOR_TONE_EXT = BT_HCI_OP_LE_CS_TEST_TONE_EXT_BOTH,
/** Applicable for mode-2 and mode-3 only:
*
* Loop through:
* - @ref BT_CS_TEST_OVERRIDE_3_NO_TONE_EXT
* - @ref BT_CS_TEST_OVERRIDE_3_INITIATOR_TONE_EXT_ONLY
* - @ref BT_CS_TEST_OVERRIDE_3_REFLECTOR_TONE_EXT_ONLY
* - @ref BT_CS_TEST_OVERRIDE_3_INITIATOR_AND_REFLECTOR_TONE_EXT
*/
BT_CS_TEST_OVERRIDE_3_REPETITIVE_TONE_EXT = BT_HCI_OP_LE_CS_TEST_TONE_EXT_REPEAT,
};
/** CS Test Override 4 Tone Antenna Permutation.
*
* These values represent indices in an antenna path permutation table.
*
* Which table is applicable (and which indices are valid)
* depends on the maximum number of antenna paths (N_AP).
*
* If N_AP = 2, the permutation table is:
*
* +--------------------------------+------------------------------------------+
* | Antenna Path Permutation Index | Antenna Path Positions After Permutation |
* +--------------------------------+------------------------------------------+
* | 0 | A1 A2 |
* | 1 | A2 A1 |
* +--------------------------------+------------------------------------------+
*
* If N_AP = 3, the permutation table is:
*
* +--------------------------------+------------------------------------------+
* | Antenna Path Permutation Index | Antenna Path Positions After Permutation |
* +--------------------------------+------------------------------------------+
* | 0 | A1 A2 A3 |
* | 1 | A2 A1 A3 |
* | 2 | A1 A3 A2 |
* | 3 | A3 A1 A2 |
* | 4 | A3 A2 A1 |
* | 5 | A2 A3 A1 |
* +--------------------------------+------------------------------------------+
*
* If N_AP = 4, the permutation table is:
*
* +--------------------------------+------------------------------------------+
* | Antenna Path Permutation Index | Antenna Path Positions After Permutation |
* +--------------------------------+------------------------------------------+
* | 0 | A1 A2 A3 A4 |
* | 1 | A2 A1 A3 A4 |
* | 2 | A1 A3 A2 A4 |
* | 3 | A3 A1 A2 A4 |
* | 4 | A3 A2 A1 A4 |
* | 5 | A2 A3 A1 A4 |
* | 6 | A1 A2 A4 A3 |
* | 7 | A2 A1 A4 A3 |
* | 8 | A1 A4 A2 A3 |
* | 9 | A4 A1 A2 A3 |
* | 10 | A4 A2 A1 A3 |
* | 11 | A2 A4 A1 A3 |
* | 12 | A1 A4 A3 A2 |
* | 13 | A4 A1 A3 A2 |
* | 14 | A1 A3 A4 A2 |
* | 15 | A3 A1 A4 A2 |
* | 16 | A3 A4 A1 A2 |
* | 17 | A4 A3 A1 A2 |
* | 18 | A4 A2 A3 A1 |
* | 19 | A2 A4 A3 A1 |
* | 20 | A4 A3 A2 A1 |
* | 21 | A3 A4 A2 A1 |
* | 22 | A3 A2 A4 A1 |
* | 23 | A2 A3 A4 A1 |
* +--------------------------------+------------------------------------------+
*/
enum bt_cs_test_override_4_tone_antenna_permutation {
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_00 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_00,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_01 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_01,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_02 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_02,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_03 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_03,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_04 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_04,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_05 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_05,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_06 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_06,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_07 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_07,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_08 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_08,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_09 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_09,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_10 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_10,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_11 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_11,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_12 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_12,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_13 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_13,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_14 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_14,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_15 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_15,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_16 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_16,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_17 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_17,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_18 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_18,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_19 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_19,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_20 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_20,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_21 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_21,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_22 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_22,
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_23 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_23,
/** Loop through all valid Antenna Permuation Indices starting
* from the lowest index.
*/
BT_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_LOOP = BT_HCI_OP_LE_CS_TEST_AP_INDEX_LOOP,
};
/** CS Test Override 7 Sounding Sequence Marker Value */
enum bt_cs_test_override_7_ss_marker_value {
BT_CS_TEST_OVERRIDE_7_SS_MARKER_VAL_0011 = BT_HCI_OP_LE_CS_TEST_SS_MARKER_VAL_0011,
BT_CS_TEST_OVERRIDE_7_SS_MARKER_VAL_1100 = BT_HCI_OP_LE_CS_TEST_SS_MARKER_VAL_1100,
/** Loop through pattern '0011' and '1100' (in transmission order) */
BT_CS_TEST_OVERRIDE_7_SS_MARKER_VAL_LOOP = BT_HCI_OP_LE_CS_TEST_SS_MARKER_VAL_LOOP,
};
/** CS Test Override 8 CS_SYNC Payload Pattern */
enum bt_cs_test_override_8_cs_sync_payload_pattern {
/** PRBS9 payload sequence. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_PRBS9 = BT_HCI_OP_LE_CS_TEST_PAYLOAD_PRBS9,
/** Repeated '11110000' payload sequence. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_11110000 = BT_HCI_OP_LE_CS_TEST_PAYLOAD_11110000,
/** Repeated '10101010' payload sequence. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_10101010 = BT_HCI_OP_LE_CS_TEST_PAYLOAD_10101010,
/** PRBS15 payload sequence. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_PRBS15 = BT_HCI_OP_LE_CS_TEST_PAYLOAD_PRBS15,
/** Repeated '11111111' payload sequence. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_11111111 = BT_HCI_OP_LE_CS_TEST_PAYLOAD_11111111,
/** Repeated '00000000' payload sequence. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_00000000 = BT_HCI_OP_LE_CS_TEST_PAYLOAD_00000000,
/** Repeated '00001111' payload sequence. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_00001111 = BT_HCI_OP_LE_CS_TEST_PAYLOAD_00001111,
/** Repeated '01010101' payload sequence. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_01010101 = BT_HCI_OP_LE_CS_TEST_PAYLOAD_01010101,
/** Custom payload provided by the user. */
BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_USER = BT_HCI_OP_LE_CS_TEST_PAYLOAD_USER,
};
/** CS Test parameters */
struct bt_cs_test_param {
/** CS mode to be used during the CS procedure. */
enum bt_cs_test_main_mode main_mode;
/** CS sub-mode to be used during the CS procedure. */
enum bt_cs_test_sub_mode sub_mode;
/** Number of main mode steps taken from the end of the last CS subevent
* to be repeated at the beginning of the current CS subevent directly
* after the last mode-0 step of that event.
*/
uint8_t main_mode_repetition;
/** Number of CS mode-0 steps at the beginning of the test CS subevent. */
uint8_t mode_0_steps;
/** CS Test role */
enum bt_cs_test_role role;
/** RTT variant */
enum bt_cs_test_rtt_type rtt_type;
/** CS_SYNC PHY */
enum bt_cs_test_cs_sync_phy cs_sync_phy;
/** Antenna identifier to be used for CS_SYNC packets. */
enum bt_cs_test_cs_sync_antenna_selection cs_sync_antenna_selection;
/** CS subevent length in microseconds.
*
* Range: 1250us to 4s
*/
uint32_t subevent_len;
/** Gap between the start of two consecutive CS subevents (N * 0.625 ms)
*
* A value of 0 means that there is only one CS subevent.
*/
uint16_t subevent_interval;
/** Maximum allowed number of subevents in the procedure.
*
* A value of 0 means that this parameter is ignored.
*/
uint8_t max_num_subevents;
/** Desired TX power level for the CS procedure.
*
* Value range is @ref BT_HCI_OP_LE_CS_MIN_MAX_TX_POWER to
* @ref BT_HCI_OP_LE_CS_MAX_MAX_TX_POWER.
*
* Special values:
* - @ref BT_HCI_OP_LE_CS_TEST_MAXIMIZE_TX_POWER tells the controller
* it should use as high a transmit power as possible
* - @ref BT_HCI_OP_LE_CS_TEST_MINIMIZE_TX_POWER tells the controller
* it should use as low a transmit power as possible
*/
uint8_t transmit_power_level;
/** Interlude time in microseconds between the RTT packets. */
uint8_t t_ip1_time;
/** Interlude time in microseconds between the CS tones. */
uint8_t t_ip2_time;
/** Time in microseconds for frequency changes. */
uint8_t t_fcs_time;
/** Time in microseconds for the phase measurement period of the CS tones. */
uint8_t t_pm_time;
/** Time in microseconds for the antenna switch period of the CS tones. */
uint8_t t_sw_time;
/** Antenna Configuration Index used during antenna switching during
* the tone phases of CS steps.
*/
enum bt_cs_test_tone_antenna_config_selection tone_antenna_config_selection;
/** Initiator SNR control options */
enum bt_cs_test_initiator_snr_control initiator_snr_control;
/** Reflector SNR control options */
enum bt_cs_test_reflector_snr_control reflector_snr_control;
/** Determines octets 14 and 15 of the initial value of the DRBG nonce. */
uint16_t drbg_nonce;
/** Override configuration.
*
* This parameter is used to override CS parameters from the DRBG.
* Each bit configures a different set of parameters.
*
* All overrides are optional, except for those configured by bit 0.
*
* These are:
* - Bit 0 set: Override using list of channels
* - Bit 0 not set: Override using channel map
* - Bit 2 set: Override main mode steps
* - Bit 3 set: Override T_PM_Tone_Ext
* - Bit 4 set: Override tone antenna permutation
* - Bit 5 set: Override CS_SYNC AA
* - Bit 6 set: Override SS marker positions
* - Bit 7 set: Override SS marker value
* - Bit 8 set: Override CS_SYNC payload pattern and user payload
* - Bit 10 set: Procedure is replaced with a stable phase test
*/
uint16_t override_config;
/** override config bit 0. */
struct {
/** Number of times the channels indicated by the channel map or channel field
* are cycled through for non-mode-0 steps within a CS procedure.
*/
uint8_t channel_map_repetition;
union {
struct {
uint8_t num_channels;
uint8_t *channels;
} set;
struct {
uint8_t channel_map[10];
enum bt_cs_test_override_0_chsel_alg channel_selection_type;
enum bt_cs_test_override_0_ch3c_shape ch3c_shape;
uint8_t ch3c_jump;
} not_set;
};
} override_config_0;
/** Override config bit 2. These parameters are ignored if the bit is not set. */
struct {
uint8_t main_mode_steps;
} override_config_2;
/** Override config bit 3. These parameters are ignored if the bit is not set. */
struct {
enum bt_cs_test_override_3_pm_tone_ext t_pm_tone_ext;
} override_config_3;
/** Override config bit 4. These parameters are ignored if the bit is not set. */
struct {
enum bt_cs_test_override_4_tone_antenna_permutation tone_antenna_permutation;
} override_config_4;
/** Override config bit 5. These parameters are ignored if the bit is not set. */
struct {
/** Access Address used in CS_SYNC packets sent by the initiator. */
uint32_t cs_sync_aa_initiator;
/** Access Address used in CS_SYNC packets sent by the reflector. */
uint32_t cs_sync_aa_reflector;
} override_config_5;
/** Override config bit 6. These parameters are ignored if the bit is not set. */
struct {
/** Bit number where the first marker in the channel sounding sequence starts.
*
* Must be between 0 and 28 when using @ref BT_CS_TEST_RTT_32_BIT_SOUNDING.
*/
uint8_t ss_marker1_position;
/** Bit number where the second marker in the channel sounding sequence starts.
*
* Must be between 67 and 92 when using @ref BT_CS_TEST_RTT_96_BIT_SOUNDING.
*
* A value of @ref BT_HCI_OP_LE_CS_TEST_SS_MARKER_2_POSITION_NOT_PRESENT
* indicates that this sounding sequence or marker is not present.
*/
uint8_t ss_marker2_position;
} override_config_6;
/** Override config bit 7. These parameters are ignored if the bit is not set. */
struct {
/** Value of the Sounding Sequence marker. */
enum bt_cs_test_override_7_ss_marker_value ss_marker_value;
} override_config_7;
/** Override config bit 8. These parameters are ignored if the bit is not set. */
struct {
/** CS_SYNC payload pattern selection. */
enum bt_cs_test_override_8_cs_sync_payload_pattern cs_sync_payload_pattern;
/** User payload for CS_SYNC packets.
*
* This parameter is only used when using
* @ref BT_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_USER
*
* The least significant bit corresponds to the most significant bit
* of the CS payload. When the sequence is less than 16 octets,
* the least significant octets shall be padded with zeros.
*/
uint8_t cs_sync_user_payload[16];
} override_config_8;
};
/** @brief Read Remote Supported Capabilities
*
@ -102,6 +547,28 @@ int bt_cs_set_default_settings(struct bt_conn *conn,
*/
int bt_cs_read_remote_fae_table(struct bt_conn *conn);
/** @brief Start a CS test
*
* This command is used to start a CS test where the IUT is placed in the role
* of either the initiator or reflector.
*
* The first mode-0 channel in the list is used as the starting channel for
* the test. At the beginning of any test, the IUT in the flector role shall
* listen on the first mode-0 channel until it receives the first transmission
* from the initiator. Similarly, with the IUT in the initiator role, the tester
* will start by listening on the first mode-0 channel and the IUT shall transmit
* on that channel for the first half of the first CS step. Thereafter, the
* parameters of this command describe the required transmit and receive behavior
* for the CS test.
*
* @note To use this API @kconfig{CONFIG_BT_CHANNEL_SOUNDING} must be set.
*
* @param params CS Test parameters
*
* @return Zero on success or (negative) error code on failure.
*/
int bt_cs_start_test(const struct bt_cs_test_param *params);
#ifdef __cplusplus
}
#endif

View file

@ -2436,6 +2436,152 @@ struct bt_hci_cp_le_read_remote_fae_table {
uint16_t handle;
} __packed;
#define BT_HCI_OP_LE_CS_TEST BT_OP(BT_OGF_LE, 0x0095) /* 0x2095 */
#define BT_HCI_OP_LE_CS_MAIN_MODE_1 0x1
#define BT_HCI_OP_LE_CS_MAIN_MODE_2 0x2
#define BT_HCI_OP_LE_CS_MAIN_MODE_3 0x3
#define BT_HCI_OP_LE_CS_SUB_MODE_1 0x1
#define BT_HCI_OP_LE_CS_SUB_MODE_2 0x2
#define BT_HCI_OP_LE_CS_SUB_MODE_3 0x3
#define BT_HCI_OP_LE_CS_SUB_MODE_UNUSED 0xFF
#define BT_HCI_OP_LE_CS_INITIATOR_ROLE 0x0
#define BT_HCI_OP_LE_CS_REFLECTOR_ROLE 0x1
#define BT_HCI_OP_LE_CS_RTT_TYPE_AA_ONLY 0x0
#define BT_HCI_OP_LE_CS_RTT_TYPE_32BIT_SOUND 0x1
#define BT_HCI_OP_LE_CS_RTT_TYPE_96BIT_SOUND 0x2
#define BT_HCI_OP_LE_CS_RTT_TYPE_32BIT_RAND 0x3
#define BT_HCI_OP_LE_CS_RTT_TYPE_64BIT_RAND 0x4
#define BT_HCI_OP_LE_CS_RTT_TYPE_96BIT_RAND 0x5
#define BT_HCI_OP_LE_CS_RTT_TYPE_128BIT_RAND 0x6
#define BT_HCI_OP_LE_CS_CS_SYNC_1M 0x1
#define BT_HCI_OP_LE_CS_CS_SYNC_2M 0x2
#define BT_HCI_OP_LE_CS_CS_SYNC_2M_2BT 0x3
#define BT_HCI_OP_LE_CS_TEST_MAXIMIZE_TX_POWER 0x7E
#define BT_HCI_OP_LE_CS_TEST_MINIMIZE_TX_POWER 0x7F
#define BT_HCI_OP_LE_CS_TEST_ACI_0 0x0
#define BT_HCI_OP_LE_CS_TEST_ACI_1 0x1
#define BT_HCI_OP_LE_CS_TEST_ACI_2 0x2
#define BT_HCI_OP_LE_CS_TEST_ACI_3 0x3
#define BT_HCI_OP_LE_CS_TEST_ACI_4 0x4
#define BT_HCI_OP_LE_CS_TEST_ACI_5 0x5
#define BT_HCI_OP_LE_CS_TEST_ACI_6 0x6
#define BT_HCI_OP_LE_CS_TEST_ACI_7 0x7
#define BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_18 0x0
#define BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_21 0x1
#define BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_24 0x2
#define BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_27 0x3
#define BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_30 0x4
#define BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_NOT_USED 0xFF
#define BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_18 0x0
#define BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_21 0x1
#define BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_24 0x2
#define BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_27 0x3
#define BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_30 0x4
#define BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_NOT_USED 0xFF
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_0_MASK BIT(0)
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_2_MASK BIT(2)
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_3_MASK BIT(3)
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_4_MASK BIT(4)
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_5_MASK BIT(5)
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_6_MASK BIT(6)
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_7_MASK BIT(7)
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_8_MASK BIT(8)
#define BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_10_MASK BIT(10)
#define BT_HCI_OP_LE_CS_TEST_CHSEL_TYPE_3B 0x0
#define BT_HCI_OP_LE_CS_TEST_CHSEL_TYPE_3C 0x1
#define BT_HCI_OP_LE_CS_TEST_CH3C_SHAPE_HAT 0x0
#define BT_HCI_OP_LE_CS_TEST_CH3C_SHAPE_X 0x1
#define BT_HCI_OP_LE_CS_TEST_TONE_EXT_NONE 0x0
#define BT_HCI_OP_LE_CS_TEST_TONE_EXT_INIT 0x1
#define BT_HCI_OP_LE_CS_TEST_TONE_EXT_REFL 0x2
#define BT_HCI_OP_LE_CS_TEST_TONE_EXT_BOTH 0x3
#define BT_HCI_OP_LE_CS_TEST_TONE_EXT_REPEAT 0x4
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_00 0x0
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_01 0x1
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_02 0x2
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_03 0x3
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_04 0x4
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_05 0x5
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_06 0x6
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_07 0x7
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_08 0x8
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_09 0x9
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_10 0xA
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_11 0xB
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_12 0xC
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_13 0xD
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_14 0xE
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_15 0xF
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_16 0x10
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_17 0x11
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_18 0x12
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_19 0x13
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_20 0x14
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_21 0x15
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_22 0x16
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_23 0x17
#define BT_HCI_OP_LE_CS_TEST_AP_INDEX_LOOP 0xFF
#define BT_HCI_OP_LE_CS_TEST_SS_MARKER_2_POSITION_NOT_PRESENT 0xFF
#define BT_HCI_OP_LE_CS_TEST_SS_MARKER_VAL_0011 0x0
#define BT_HCI_OP_LE_CS_TEST_SS_MARKER_VAL_1100 0x1
#define BT_HCI_OP_LE_CS_TEST_SS_MARKER_VAL_LOOP 0x2
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_PRBS9 0x00
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_11110000 0x01
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_10101010 0x02
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_PRBS15 0x03
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_11111111 0x04
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_00000000 0x05
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_00001111 0x06
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_01010101 0x07
#define BT_HCI_OP_LE_CS_TEST_PAYLOAD_USER 0x80
struct bt_hci_op_le_cs_test {
uint8_t main_mode_type;
uint8_t sub_mode_type;
uint8_t main_mode_repetition;
uint8_t mode_0_steps;
uint8_t role;
uint8_t rtt_type;
uint8_t cs_sync_phy;
uint8_t cs_sync_antenna_selection;
uint8_t subevent_len[3];
uint16_t subevent_interval;
uint8_t max_num_subevents;
uint8_t transmit_power_level;
uint8_t t_ip1_time;
uint8_t t_ip2_time;
uint8_t t_fcs_time;
uint8_t t_pm_time;
uint8_t t_sw_time;
uint8_t tone_antenna_config_selection;
uint8_t reserved;
uint8_t snr_control_initiator;
uint8_t snr_control_reflector;
uint16_t drbg_nonce;
uint8_t channel_map_repetition;
uint16_t override_config;
uint8_t override_parameters_length;
uint8_t override_parameters_data[];
} __packed;
/* Event definitions */
#define BT_HCI_EVT_UNKNOWN 0x00

View file

@ -222,4 +222,108 @@ void bt_hci_le_cs_read_remote_fae_table_complete(struct net_buf *buf)
bt_conn_unref(conn);
}
int bt_cs_start_test(const struct bt_cs_test_param *params)
{
struct bt_hci_op_le_cs_test *cp;
struct net_buf *buf;
buf = bt_hci_cmd_create(BT_HCI_OP_LE_CS_TEST, sizeof(*cp));
if (!buf) {
return -ENOBUFS;
}
cp = net_buf_add(buf, sizeof(*cp));
cp->main_mode_type = params->main_mode;
cp->sub_mode_type = params->sub_mode;
cp->main_mode_repetition = params->main_mode_repetition;
cp->mode_0_steps = params->mode_0_steps;
cp->role = params->role;
cp->rtt_type = params->rtt_type;
cp->cs_sync_phy = params->cs_sync_phy;
cp->cs_sync_antenna_selection = params->cs_sync_antenna_selection;
sys_put_le24(params->subevent_len, cp->subevent_len);
cp->subevent_interval = sys_cpu_to_le16(params->subevent_interval);
cp->max_num_subevents = params->max_num_subevents;
cp->transmit_power_level = params->transmit_power_level;
cp->t_ip1_time = params->t_ip1_time;
cp->t_ip2_time = params->t_ip2_time;
cp->t_fcs_time = params->t_fcs_time;
cp->t_pm_time = params->t_pm_time;
cp->t_sw_time = params->t_sw_time;
cp->tone_antenna_config_selection = params->tone_antenna_config_selection;
cp->reserved = 0;
cp->snr_control_initiator = params->initiator_snr_control;
cp->snr_control_reflector = params->reflector_snr_control;
cp->drbg_nonce = sys_cpu_to_le16(params->drbg_nonce);
cp->channel_map_repetition = params->override_config_0.channel_map_repetition;
cp->override_config = sys_cpu_to_le16(params->override_config);
uint8_t override_parameters_length = 0;
if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_0_MASK) {
const uint8_t num_channels = params->override_config_0.set.num_channels;
net_buf_add_u8(buf, num_channels);
override_parameters_length++;
net_buf_add_mem(buf, params->override_config_0.set.channels, num_channels);
override_parameters_length += num_channels;
} else {
net_buf_add_mem(buf, params->override_config_0.not_set.channel_map,
sizeof(params->override_config_0.not_set.channel_map));
net_buf_add_u8(buf, params->override_config_0.not_set.channel_selection_type);
net_buf_add_u8(buf, params->override_config_0.not_set.ch3c_shape);
net_buf_add_u8(buf, params->override_config_0.not_set.ch3c_jump);
override_parameters_length +=
(sizeof(params->override_config_0.not_set.channel_map) +
sizeof(params->override_config_0.not_set.channel_selection_type) +
sizeof(params->override_config_0.not_set.ch3c_shape) +
sizeof(params->override_config_0.not_set.ch3c_jump));
}
if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_2_MASK) {
net_buf_add_mem(buf, &params->override_config_2, sizeof(params->override_config_2));
override_parameters_length += sizeof(params->override_config_2);
}
if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_3_MASK) {
net_buf_add_mem(buf, &params->override_config_3, sizeof(params->override_config_3));
override_parameters_length += sizeof(params->override_config_3);
}
if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_4_MASK) {
net_buf_add_mem(buf, &params->override_config_4, sizeof(params->override_config_4));
override_parameters_length += sizeof(params->override_config_4);
}
if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_5_MASK) {
net_buf_add_le32(buf, params->override_config_5.cs_sync_aa_initiator);
net_buf_add_le32(buf, params->override_config_5.cs_sync_aa_reflector);
override_parameters_length += sizeof(params->override_config_5);
}
if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_6_MASK) {
net_buf_add_mem(buf, &params->override_config_6, sizeof(params->override_config_6));
override_parameters_length += sizeof(params->override_config_6);
}
if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_7_MASK) {
net_buf_add_mem(buf, &params->override_config_7, sizeof(params->override_config_7));
override_parameters_length += sizeof(params->override_config_7);
}
if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_8_MASK) {
net_buf_add_mem(buf, &params->override_config_8, sizeof(params->override_config_8));
override_parameters_length += sizeof(params->override_config_8);
}
cp->override_parameters_length = override_parameters_length;
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_TEST, buf, NULL);
}
#endif /* CONFIG_BT_CHANNEL_SOUNDING */

View file

@ -133,6 +133,67 @@ static int cmd_read_remote_fae_table(const struct shell *sh, size_t argc, char *
return 0;
}
static int cmd_cs_test_simple(const struct shell *sh, size_t argc, char *argv[])
{
int err = 0;
struct bt_cs_test_param params;
params.main_mode = BT_CS_TEST_MAIN_MODE_1;
params.sub_mode = BT_CS_TEST_SUB_MODE_UNUSED;
params.main_mode_repetition = 0;
params.mode_0_steps = 0x1;
params.role = shell_strtoul(argv[1], 16, &err);
if (err) {
shell_help(sh);
shell_error(sh, "Could not parse input 1, Role selection");
return SHELL_CMD_HELP_PRINTED;
}
if (params.role != BT_CS_TEST_ROLE_INITIATOR && params.role != BT_CS_TEST_ROLE_REFLECTOR) {
shell_help(sh);
shell_error(sh, "Role selection input invalid");
return SHELL_CMD_HELP_PRINTED;
}
params.rtt_type = BT_CS_TEST_RTT_AA_ONLY;
params.cs_sync_phy = BT_CS_TEST_CS_SYNC_LE_1M_PHY;
params.cs_sync_antenna_selection = BT_CS_TEST_CS_SYNC_ANTENNA_SELECTION_ONE;
params.subevent_len = 10000;
params.subevent_interval = 0;
params.max_num_subevents = 0;
params.transmit_power_level = BT_HCI_OP_LE_CS_TEST_MAXIMIZE_TX_POWER;
params.t_ip1_time = 80;
params.t_ip2_time = 80;
params.t_fcs_time = 120;
params.t_pm_time = 20;
params.t_sw_time = 0;
params.tone_antenna_config_selection = BT_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_ONE;
params.initiator_snr_control = BT_CS_TEST_INITIATOR_SNR_CONTROL_NOT_USED;
params.reflector_snr_control = BT_CS_TEST_REFLECTOR_SNR_CONTROL_NOT_USED;
params.drbg_nonce = 0x1234;
params.override_config = 0;
params.override_config_0.channel_map_repetition = 1;
memset(params.override_config_0.not_set.channel_map, 0,
sizeof(params.override_config_0.not_set.channel_map));
params.override_config_0.not_set.channel_map[1] = 0xFF;
params.override_config_0.not_set.channel_selection_type =
BT_CS_TEST_OVERRIDE_0_CHSEL_ALG_3B;
params.override_config_0.not_set.ch3c_shape =
BT_CS_TEST_OVERRIDE_0_CHSEL_ALG_3C_HAT_SHAPE;
params.override_config_0.not_set.ch3c_jump = 0x2;
err = bt_cs_start_test(&params);
if (err) {
shell_error(sh, "bt_cs_start_test returned error %d", err);
return -ENOEXEC;
}
return 0;
}
SHELL_STATIC_SUBCMD_SET_CREATE(
cs_cmds,
SHELL_CMD_ARG(
@ -148,6 +209,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
read_remote_fae_table, NULL,
"<None>",
cmd_read_remote_fae_table, 1, 0),
SHELL_CMD_ARG(
start_simple_cs_test, NULL,
"<Role selection (initiator, reflector): 0, 1>",
cmd_cs_test_simple, 2, 0),
SHELL_SUBCMD_SET_END);
static int cmd_cs(const struct shell *sh, size_t argc, char **argv)