diff --git a/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts b/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts index 43ca4460f25..cd8b95be664 100644 --- a/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts +++ b/boards/native/nrf_bsim/nrf54l15bsim_nrf54l15_cpuapp.dts @@ -97,8 +97,9 @@ &radio { status = "okay"; - /* This feature is not yet supported by the RADIO model */ + /* These features are not yet supported by the RADIO model */ /delete-property/ dfe-supported; + /delete-property/ cs-supported; }; &clock { diff --git a/dts/bindings/net/wireless/nordic,nrf-radio.yaml b/dts/bindings/net/wireless/nordic,nrf-radio.yaml index 9814e5f5fb7..8c73d652662 100644 --- a/dts/bindings/net/wireless/nordic,nrf-radio.yaml +++ b/dts/bindings/net/wireless/nordic,nrf-radio.yaml @@ -227,3 +227,10 @@ properties: description: | If set, indicates that the radio hardware supports high TX power settings. + + cs-supported: + type: boolean + description: | + If set, the radio hardware supports the BLE Channel Sounding feature. + This property should be treated as read-only and should not be overridden; + the correct value is provided for your target's SoC already. diff --git a/dts/common/nordic/nrf54h20.dtsi b/dts/common/nordic/nrf54h20.dtsi index c84e88646e3..dc1312b99e8 100644 --- a/dts/common/nordic/nrf54h20.dtsi +++ b/dts/common/nordic/nrf54h20.dtsi @@ -400,6 +400,7 @@ status = "disabled"; ble-2mbps-supported; ble-coded-phy-supported; + cs-supported; dfe-supported; ieee802154-supported; interrupts = <44 NRF_DEFAULT_IRQ_PRIORITY>; diff --git a/dts/common/nordic/nrf54l15.dtsi b/dts/common/nordic/nrf54l15.dtsi index 0e9b3435b1c..bdc4f59c9fa 100644 --- a/dts/common/nordic/nrf54l15.dtsi +++ b/dts/common/nordic/nrf54l15.dtsi @@ -211,6 +211,7 @@ ieee802154-supported; ble-2mbps-supported; ble-coded-phy-supported; + cs-supported; ieee802154: ieee802154 { compatible = "nordic,nrf-ieee802154"; diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 6ddc9835ceb..55bb48c6934 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -413,6 +413,237 @@ struct bt_conn_le_cs_fae_table { uint8_t *remote_fae_table; }; +/** Channel sounding main mode */ +enum bt_conn_le_cs_main_mode { + /** Mode-1 (RTT) */ + BT_CONN_LE_CS_MAIN_MODE_1 = BT_HCI_OP_LE_CS_MAIN_MODE_1, + /** Mode-2 (PBR) */ + BT_CONN_LE_CS_MAIN_MODE_2 = BT_HCI_OP_LE_CS_MAIN_MODE_2, + /** Mode-3 (RTT and PBR) */ + BT_CONN_LE_CS_MAIN_MODE_3 = BT_HCI_OP_LE_CS_MAIN_MODE_3, +}; + +/** Channel sounding sub mode */ +enum bt_conn_le_cs_sub_mode { + /** Unused */ + BT_CONN_LE_CS_SUB_MODE_UNUSED = BT_HCI_OP_LE_CS_SUB_MODE_UNUSED, + /** Mode-1 (RTT) */ + BT_CONN_LE_CS_SUB_MODE_1 = BT_HCI_OP_LE_CS_SUB_MODE_1, + /** Mode-2 (PBR) */ + BT_CONN_LE_CS_SUB_MODE_2 = BT_HCI_OP_LE_CS_SUB_MODE_2, + /** Mode-3 (RTT and PBR) */ + BT_CONN_LE_CS_SUB_MODE_3 = BT_HCI_OP_LE_CS_SUB_MODE_3, +}; + +/** Channel sounding role */ +enum bt_conn_le_cs_role { + /** CS initiator role */ + BT_CONN_LE_CS_ROLE_INITIATOR, + /** CS reflector role */ + BT_CONN_LE_CS_ROLE_REFLECTOR, +}; + +/** Channel sounding RTT type */ +enum bt_conn_le_cs_rtt_type { + /** RTT AA only */ + BT_CONN_LE_CS_RTT_TYPE_AA_ONLY = BT_HCI_OP_LE_CS_RTT_TYPE_AA_ONLY, + /** RTT with 32-bit sounding sequence */ + BT_CONN_LE_CS_RTT_TYPE_32_BIT_SOUNDING = BT_HCI_OP_LE_CS_RTT_TYPE_32BIT_SOUND, + /** RTT with 96-bit sounding sequence */ + BT_CONN_LE_CS_RTT_TYPE_96_BIT_SOUNDING = BT_HCI_OP_LE_CS_RTT_TYPE_96BIT_SOUND, + /** RTT with 32-bit random sequence */ + BT_CONN_LE_CS_RTT_TYPE_32_BIT_RANDOM = BT_HCI_OP_LE_CS_RTT_TYPE_32BIT_RAND, + /** RTT with 64-bit random sequence */ + BT_CONN_LE_CS_RTT_TYPE_64_BIT_RANDOM = BT_HCI_OP_LE_CS_RTT_TYPE_64BIT_RAND, + /** RTT with 96-bit random sequence */ + BT_CONN_LE_CS_RTT_TYPE_96_BIT_RANDOM = BT_HCI_OP_LE_CS_RTT_TYPE_96BIT_RAND, + /** RTT with 128-bit random sequence */ + BT_CONN_LE_CS_RTT_TYPE_128_BIT_RANDOM = BT_HCI_OP_LE_CS_RTT_TYPE_128BIT_RAND, +}; + +/** Channel sounding PHY used for CS sync */ +enum bt_conn_le_cs_sync_phy { + /** LE 1M PHY */ + BT_CONN_LE_CS_SYNC_1M_PHY = BT_HCI_OP_LE_CS_CS_SYNC_1M, + /** LE 2M PHY */ + BT_CONN_LE_CS_SYNC_2M_PHY = BT_HCI_OP_LE_CS_CS_SYNC_2M, + /** LE 2M 2BT PHY */ + BT_CONN_LE_CS_SYNC_2M_2BT_PHY = BT_HCI_OP_LE_CS_CS_SYNC_2M_2BT, +}; + +/** Channel sounding channel selection type */ +enum bt_conn_le_cs_chsel_type { + /** Use Channel Selection Algorithm #3b for non-mode-0 CS steps */ + BT_CONN_LE_CS_CHSEL_TYPE_3B = BT_HCI_OP_LE_CS_TEST_CHSEL_TYPE_3B, + /** Use Channel Selection Algorithm #3c for non-mode-0 CS steps */ + BT_CONN_LE_CS_CHSEL_TYPE_3C = BT_HCI_OP_LE_CS_TEST_CHSEL_TYPE_3C, +}; + +/** Channel sounding channel sequence shape */ +enum bt_conn_le_cs_ch3c_shape { + /** Use Hat shape for user-specified channel sequence */ + BT_CONN_LE_CS_CH3C_SHAPE_HAT = BT_HCI_OP_LE_CS_TEST_CH3C_SHAPE_HAT, + /** Use X shape for user-specified channel sequence */ + BT_CONN_LE_CS_CH3C_SHAPE_X = BT_HCI_OP_LE_CS_TEST_CH3C_SHAPE_X, +}; + +/** Channel sounding configuration */ +struct bt_conn_le_cs_config { + /** CS configuration ID */ + uint8_t id; + /** Main CS mode type */ + enum bt_conn_le_cs_main_mode main_mode_type; + /** Sub CS mode type */ + enum bt_conn_le_cs_sub_mode sub_mode_type; + /** Minimum number of CS main mode steps to be executed before a submode step is executed */ + uint8_t min_main_mode_steps; + /** Maximum number of CS main mode steps to be executed before a submode step is executed */ + uint8_t max_main_mode_steps; + /** 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 to be included at the beginning of each CS subevent */ + uint8_t mode_0_steps; + /** CS role */ + enum bt_conn_le_cs_role role; + /** RTT type */ + enum bt_conn_le_cs_rtt_type rtt_type; + /** CS Sync PHY */ + enum bt_conn_le_cs_sync_phy cs_sync_phy; + /** The number of times the Channel_Map field will be cycled through for non-mode-0 steps + * within a CS procedure + */ + uint8_t channel_map_repetition; + /** Channel selection type */ + enum bt_conn_le_cs_chsel_type channel_selection_type; + /** User-specified channel sequence shape */ + enum bt_conn_le_cs_ch3c_shape ch3c_shape; + /** Number of channels skipped in each rising and falling sequence */ + uint8_t ch3c_jump; + /** Interlude time in microseconds between the RTT packets */ + uint8_t t_ip1_time_us; + /** Interlude time in microseconds between the CS tones */ + uint8_t t_ip2_time_us; + /** Time in microseconds for frequency changes */ + uint8_t t_fcs_time_us; + /** Time in microseconds for the phase measurement period of the CS tones */ + uint8_t t_pm_time_us; + /** Channel map used for CS procedure + * Channels n = 0, 1, 23, 24, 25, 77, and 78 are not allowed and shall be set to zero. + * Channel 79 is reserved for future use and shall be set to zero. + * At least 15 channels shall be enabled. + */ + uint8_t channel_map[10]; +}; + +/** Procedure done status */ +enum bt_conn_le_cs_procedure_done_status { + BT_CONN_LE_CS_PROCEDURE_COMPLETE = BT_HCI_LE_CS_PROCEDURE_DONE_STATUS_COMPLETE, + BT_CONN_LE_CS_PROCEDURE_INCOMPLETE = BT_HCI_LE_CS_PROCEDURE_DONE_STATUS_PARTIAL, + BT_CONN_LE_CS_PROCEDURE_ABORTED = BT_HCI_LE_CS_PROCEDURE_DONE_STATUS_ABORTED, +}; + +/** Subevent done status */ +enum bt_conn_le_cs_subevent_done_status { + BT_CONN_LE_CS_SUBEVENT_COMPLETE = BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_COMPLETE, + BT_CONN_LE_CS_SUBEVENT_INCOMPLETE = BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL, + BT_CONN_LE_CS_SUBEVENT_ABORTED = BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_ABORTED, +}; + +/** Procedure abort reason */ +enum bt_conn_le_cs_procedure_abort_reason { + BT_CONN_LE_CS_PROCEDURE_NOT_ABORTED = BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_NO_ABORT, + BT_CONN_LE_CS_PROCEDURE_ABORT_REQUESTED = + BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_LOCAL_HOST_OR_REMOTE_REQUEST, + BT_CONN_LE_CS_PROCEDURE_ABORT_TOO_FEW_CHANNELS = + BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_TOO_FEW_CHANNELS, + BT_CONN_LE_CS_PROCEDURE_ABORT_CHMAP_INSTANT_PASSED = + BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_CHMAP_INSTANT_PASSED, + BT_CONN_LE_CS_PROCEDURE_ABORT_UNSPECIFIED = BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_UNSPECIFIED, +}; + +/** Subevent abort reason */ +enum bt_conn_le_cs_subevent_abort_reason { + BT_CONN_LE_CS_SUBEVENT_NOT_ABORTED = BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_NO_ABORT, + BT_CONN_LE_CS_SUBEVENT_ABORT_REQUESTED = + BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_LOCAL_HOST_OR_REMOTE_REQUEST, + BT_CONN_LE_CS_SUBEVENT_ABORT_NO_CS_SYNC = + BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_NO_CS_SYNC_RECEIVED, + BT_CONN_LE_CS_SUBEVENT_ABORT_SCHED_CONFLICT = + BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_SCHED_CONFLICT, + BT_CONN_LE_CS_SUBEVENT_ABORT_UNSPECIFIED = BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_UNSPECIFIED, +}; + +/** Subevent data for LE connections supporting CS */ +struct bt_conn_le_cs_subevent_result { + struct { + /** CS configuration identifier. + * + * Range: 0 to 3 + * + * If these results were generated by a CS Test, + * this value will be set to 0 and has no meaning. + */ + uint8_t config_id; + /** Starting ACL connection event counter. + * + * If these results were generated by a CS Test, + * this value will be set to 0 and has no meaning. + */ + uint16_t start_acl_conn_event; + /** CS procedure count associated with these results. + * + * This is the CS procedure count since the completion of + * the Channel Sounding Security Start procedure. + */ + uint16_t procedure_counter; + /** Frequency compensation value in units of 0.01 ppm. + * + * This is a 15-bit signed integer in the range [-100, 100] ppm. + * + * A value of @ref BT_HCI_LE_CS_SUBEVENT_RESULT_FREQ_COMPENSATION_NOT_AVAILABLE + * indicates that the role is not the initiator, or that the + * frequency compensation value is unavailable. + */ + uint16_t frequency_compensation; + /** Reference power level in dBm. + * + * Range: -127 to 20 + * + * A value of @ref BT_HCI_LE_CS_REF_POWER_LEVEL_UNAVAILABLE indicates + * that the reference power level was not available during a subevent. + */ + int8_t reference_power_level; + /** Procedure status. */ + enum bt_conn_le_cs_procedure_done_status procedure_done_status; + /** Subevent status. */ + enum bt_conn_le_cs_subevent_done_status subevent_done_status; + /** Abort reason. + * + * If the procedure status is + * @ref BT_CONN_LE_CS_PROCEDURE_ABORTED, this field will + * specify the reason for the abortion. + */ + enum bt_conn_le_cs_procedure_abort_reason procedure_abort_reason; + /** Abort reason. + * + * If the subevent status is + * @ref BT_CONN_LE_CS_SUBEVENT_ABORTED, this field will + * specify the reason for the abortion. + */ + enum bt_conn_le_cs_subevent_abort_reason subevent_abort_reason; + /** Number of antenna paths used during the phase measurement stage. + */ + uint8_t num_antenna_paths; + /** Number of CS steps in the subevent. + */ + uint8_t num_steps_reported; + } header; + struct net_buf_simple *step_data_buf; +}; + /** @brief Increment a connection's reference count. * * Increment the reference count of a connection object. @@ -1519,8 +1750,8 @@ struct bt_conn_cb { * @param conn Connection object. * @param remote_cs_capabilities Remote Channel Sounding Capabilities. */ - void (*remote_cs_capabilities_available)(struct bt_conn *conn, - struct bt_conn_le_cs_capabilities *params); + void (*le_cs_remote_capabilities_available)(struct bt_conn *conn, + struct bt_conn_le_cs_capabilities *params); /** @brief LE CS Read Remote FAE Table Complete event. * @@ -1530,8 +1761,39 @@ struct bt_conn_cb { * @param conn Connection object. * @param params FAE Table. */ - void (*remote_cs_fae_table_available)(struct bt_conn *conn, - struct bt_conn_le_cs_fae_table *params); + void (*le_cs_remote_fae_table_available)(struct bt_conn *conn, + struct bt_conn_le_cs_fae_table *params); + + /** @brief LE CS Config created. + * + * This callback notifies the application that a Channel Sounding + * Configuration procedure has completed and a new CS config is created + * + * @param conn Connection object. + * @param config CS configuration. + */ + void (*le_cs_config_created)(struct bt_conn *conn, struct bt_conn_le_cs_config *config); + + /** @brief LE CS Config removed. + * + * This callback notifies the application that a Channel Sounding + * Configuration procedure has completed and a CS config is removed + * + * @param conn Connection object. + * @param config_id ID of the CS configuration that was removed. + */ + void (*le_cs_config_removed)(struct bt_conn *conn, uint8_t config_id); + + /** @brief Subevent Results from a CS procedure are available. + * + * This callback notifies the user that CS subevent results are + * available for the given connection object. + * + * @param conn Connection objects. + * @param result Subevent results + */ + void (*le_cs_subevent_data_available)(struct bt_conn *conn, + struct bt_conn_le_cs_subevent_result *result); #endif /** @internal Internally used field for list handling */ diff --git a/include/zephyr/bluetooth/cs.h b/include/zephyr/bluetooth/cs.h index 17331290e32..fa362083180 100644 --- a/include/zephyr/bluetooth/cs.h +++ b/include/zephyr/bluetooth/cs.h @@ -11,8 +11,8 @@ #define ZEPHYR_INCLUDE_BLUETOOTH_CS_H_ /** - * @brief Channel Sounding (CS) - * @defgroup bt_cs Channel Sounding (CS) + * @brief LE Channel Sounding (CS) + * @defgroup bt_le_cs Channel Sounding (CS) * @ingroup bluetooth * @{ */ @@ -27,30 +27,50 @@ extern "C" { #endif -enum bt_cs_sync_antenna_selection_opt { +/** + * @brief Macro for getting a specific channel bit in CS channel map + * + * @param[in] chmap Channel map array + * @param[in] bit Bit number to be accessed + * + * @return Bit value, either 1 or 0 + */ +#define BT_LE_CS_CHANNEL_BIT_GET(chmap, bit) (((chmap)[(bit) / 8] >> ((bit) % 8)) & 1) + +/** + * @brief Macro for setting a specific channel bit value in CS channel map + * + * @param[in] chmap Channel map array + * @param[in] bit Bit number to be accessed + * @param[in] val Bit value to be set, either 1 or 0 + */ +#define BT_LE_CS_CHANNEL_BIT_SET_VAL(chmap, bit, val) \ + ((chmap)[(bit) / 8] = ((chmap)[(bit) / 8] & ~BIT((bit) % 8)) | ((val) << ((bit) % 8))) + +enum bt_le_cs_sync_antenna_selection_opt { /** Use antenna identifier 1 for CS_SYNC packets. */ - BT_CS_ANTENNA_SELECTION_OPT_ONE = BT_HCI_OP_LE_CS_ANTENNA_SEL_ONE, + BT_LE_CS_ANTENNA_SELECTION_OPT_ONE = BT_HCI_OP_LE_CS_ANTENNA_SEL_ONE, /** Use antenna identifier 2 for CS_SYNC packets. */ - BT_CS_ANTENNA_SELECTION_OPT_TWO = BT_HCI_OP_LE_CS_ANTENNA_SEL_TWO, + BT_LE_CS_ANTENNA_SELECTION_OPT_TWO = BT_HCI_OP_LE_CS_ANTENNA_SEL_TWO, /** Use antenna identifier 3 for CS_SYNC packets. */ - BT_CS_ANTENNA_SELECTION_OPT_THREE = BT_HCI_OP_LE_CS_ANTENNA_SEL_THREE, + BT_LE_CS_ANTENNA_SELECTION_OPT_THREE = BT_HCI_OP_LE_CS_ANTENNA_SEL_THREE, /** Use antenna identifier 4 for CS_SYNC packets. */ - BT_CS_ANTENNA_SELECTION_OPT_FOUR = BT_HCI_OP_LE_CS_ANTENNA_SEL_FOUR, + BT_LE_CS_ANTENNA_SELECTION_OPT_FOUR = BT_HCI_OP_LE_CS_ANTENNA_SEL_FOUR, /** Use antennas in repetitive order from 1 to 4 for CS_SYNC packets. */ - BT_CS_ANTENNA_SELECTION_OPT_REPETITIVE = BT_HCI_OP_LE_CS_ANTENNA_SEL_REP, + BT_LE_CS_ANTENNA_SELECTION_OPT_REPETITIVE = BT_HCI_OP_LE_CS_ANTENNA_SEL_REP, /** No recommendation for local controller antenna selection. */ - BT_CS_ANTENNA_SELECTION_OPT_NO_RECOMMENDATION = BT_HCI_OP_LE_CS_ANTENNA_SEL_NONE, + BT_LE_CS_ANTENNA_SELECTION_OPT_NO_RECOMMENDATION = BT_HCI_OP_LE_CS_ANTENNA_SEL_NONE, }; /** Default CS settings in the local Controller */ -struct bt_cs_set_default_settings_param { +struct bt_le_cs_set_default_settings_param { /** Enable CS initiator role. */ bool enable_initiator_role; /** Enable CS reflector role. */ bool enable_reflector_role; /** Antenna identifier to be used for CS_SYNC packets by the local controller. */ - enum bt_cs_sync_antenna_selection_opt cs_sync_antenna_selection; + enum bt_le_cs_sync_antenna_selection_opt cs_sync_antenna_selection; /** Maximum output power (Effective Isotropic Radiated Power) to be used * for all CS transmissions. * @@ -60,65 +80,12 @@ 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, +enum bt_le_cs_test_cs_sync_antenna_selection { + BT_LE_CS_TEST_CS_SYNC_ANTENNA_SELECTION_ONE = BT_HCI_OP_LE_CS_ANTENNA_SEL_ONE, + BT_LE_CS_TEST_CS_SYNC_ANTENNA_SELECTION_TWO = BT_HCI_OP_LE_CS_ANTENNA_SEL_TWO, + BT_LE_CS_TEST_CS_SYNC_ANTENNA_SELECTION_THREE = BT_HCI_OP_LE_CS_ANTENNA_SEL_THREE, + BT_LE_CS_TEST_CS_SYNC_ANTENNA_SELECTION_FOUR = BT_HCI_OP_LE_CS_ANTENNA_SEL_FOUR, }; /** CS Test Tone Antennna Config Selection. @@ -148,68 +115,57 @@ enum bt_cs_test_cs_sync_antenna_selection { * 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, +enum bt_le_cs_test_tone_antenna_config_selection { + BT_LE_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_ONE = BT_HCI_OP_LE_CS_TEST_ACI_0, + BT_LE_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_TWO = BT_HCI_OP_LE_CS_TEST_ACI_1, + BT_LE_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_THREE = BT_HCI_OP_LE_CS_TEST_ACI_2, + BT_LE_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_FOUR = BT_HCI_OP_LE_CS_TEST_ACI_3, + BT_LE_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_FIVE = BT_HCI_OP_LE_CS_TEST_ACI_4, + BT_LE_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_SIX = BT_HCI_OP_LE_CS_TEST_ACI_5, + BT_LE_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_SEVEN = BT_HCI_OP_LE_CS_TEST_ACI_6, + BT_LE_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, +enum bt_le_cs_test_initiator_snr_control { + BT_LE_CS_TEST_INITIATOR_SNR_CONTROL_18dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_18, + BT_LE_CS_TEST_INITIATOR_SNR_CONTROL_21dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_21, + BT_LE_CS_TEST_INITIATOR_SNR_CONTROL_24dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_24, + BT_LE_CS_TEST_INITIATOR_SNR_CONTROL_27dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_27, + BT_LE_CS_TEST_INITIATOR_SNR_CONTROL_30dB = BT_HCI_OP_LE_CS_TEST_INITIATOR_SNR_30, + BT_LE_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, +enum bt_le_cs_test_reflector_snr_control { + BT_LE_CS_TEST_REFLECTOR_SNR_CONTROL_18dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_18, + BT_LE_CS_TEST_REFLECTOR_SNR_CONTROL_21dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_21, + BT_LE_CS_TEST_REFLECTOR_SNR_CONTROL_24dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_24, + BT_LE_CS_TEST_REFLECTOR_SNR_CONTROL_27dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_27, + BT_LE_CS_TEST_REFLECTOR_SNR_CONTROL_30dB = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_30, + BT_LE_CS_TEST_REFLECTOR_SNR_CONTROL_NOT_USED = BT_HCI_OP_LE_CS_TEST_REFLECTOR_SNR_NOT_USED, }; /** CS Test Override 3 T_PM Tone Extension */ -enum bt_cs_test_override_3_pm_tone_ext { +enum bt_le_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, + BT_LE_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, + BT_LE_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, + BT_LE_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, + BT_LE_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 + * - @ref BT_LE_CS_TEST_OVERRIDE_3_NO_TONE_EXT + * - @ref BT_LE_CS_TEST_OVERRIDE_3_INITIATOR_TONE_EXT_ONLY + * - @ref BT_LE_CS_TEST_OVERRIDE_3_REFLECTOR_TONE_EXT_ONLY + * - @ref BT_LE_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, + BT_LE_CS_TEST_OVERRIDE_3_REPETITIVE_TONE_EXT = BT_HCI_OP_LE_CS_TEST_TONE_EXT_REPEAT, }; /** CS Test Override 4 Tone Antenna Permutation. @@ -272,73 +228,74 @@ enum bt_cs_test_override_3_pm_tone_ext { * | 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, +enum bt_le_cs_test_override_4_tone_antenna_permutation { + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_00 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_00, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_01 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_01, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_02 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_02, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_03 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_03, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_04 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_04, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_05 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_05, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_06 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_06, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_07 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_07, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_08 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_08, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_09 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_09, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_10 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_10, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_11 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_11, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_12 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_12, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_13 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_13, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_14 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_14, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_15 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_15, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_16 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_16, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_17 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_17, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_18 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_18, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_19 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_19, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_20 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_20, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_21 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_21, + BT_LE_CS_TEST_OVERRIDE_4_ANTENNA_PERMUTATION_INDEX_22 = BT_HCI_OP_LE_CS_TEST_AP_INDEX_22, + BT_LE_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, + BT_LE_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, +enum bt_le_cs_test_override_7_ss_marker_value { + BT_LE_CS_TEST_OVERRIDE_7_SS_MARKER_VAL_0011 = BT_HCI_OP_LE_CS_TEST_SS_MARKER_VAL_0011, + BT_LE_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, + BT_LE_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 { +enum bt_le_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, + BT_LE_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, + BT_LE_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, + BT_LE_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, + BT_LE_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, + BT_LE_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, + BT_LE_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, + BT_LE_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, + BT_LE_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, + BT_LE_CS_TEST_OVERRIDE_8_PAYLOAD_PATTERN_USER = BT_HCI_OP_LE_CS_TEST_PAYLOAD_USER, }; /** CS Test parameters */ -struct bt_cs_test_param { +struct bt_le_cs_test_param { /** CS mode to be used during the CS procedure. */ - enum bt_cs_test_main_mode main_mode; + enum bt_conn_le_cs_main_mode main_mode; /** CS sub-mode to be used during the CS procedure. */ - enum bt_cs_test_sub_mode sub_mode; + enum bt_conn_le_cs_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. @@ -347,13 +304,13 @@ struct bt_cs_test_param { /** 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; + enum bt_conn_le_cs_role role; /** RTT variant */ - enum bt_cs_test_rtt_type rtt_type; + enum bt_conn_le_cs_rtt_type rtt_type; /** CS_SYNC PHY */ - enum bt_cs_test_cs_sync_phy cs_sync_phy; + enum bt_conn_le_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; + enum bt_le_cs_test_cs_sync_antenna_selection cs_sync_antenna_selection; /** CS subevent length in microseconds. * * Range: 1250us to 4s @@ -394,11 +351,11 @@ struct bt_cs_test_param { /** 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; + enum bt_le_cs_test_tone_antenna_config_selection tone_antenna_config_selection; /** Initiator SNR control options */ - enum bt_cs_test_initiator_snr_control initiator_snr_control; + enum bt_le_cs_test_initiator_snr_control initiator_snr_control; /** Reflector SNR control options */ - enum bt_cs_test_reflector_snr_control reflector_snr_control; + enum bt_le_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; @@ -436,8 +393,8 @@ struct bt_cs_test_param { } 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; + enum bt_conn_le_cs_chsel_type channel_selection_type; + enum bt_conn_le_cs_ch3c_shape ch3c_shape; uint8_t ch3c_jump; } not_set; }; @@ -450,12 +407,12 @@ struct bt_cs_test_param { /** 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; + enum bt_le_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; + enum bt_le_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. */ @@ -470,12 +427,13 @@ struct bt_cs_test_param { 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. + * Must be between 0 and 28 when using @ref BT_CONN_LE_CS_RTT_TYPE_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. + * Must be between 67 and 92 when using @ref + * BT_CONN_LE_CS_RTT_TYPE_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. @@ -486,17 +444,17 @@ struct bt_cs_test_param { /** 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; + enum bt_le_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; + enum bt_le_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 + * @ref BT_LE_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, @@ -506,6 +464,91 @@ struct bt_cs_test_param { } override_config_8; }; +/** CS config creation context */ +enum bt_le_cs_create_config_context { + /** Write CS configuration in local Controller only */ + BT_LE_CS_CREATE_CONFIG_CONTEXT_LOCAL_ONLY, + /** Write CS configuration in both local and remote Controller using Channel Sounding + * Configuration procedure + */ + BT_LE_CS_CREATE_CONFIG_CONTEXT_LOCAL_AND_REMOTE +}; + +/** CS Create Config params */ +struct bt_le_cs_create_config_params { + /** CS configuration ID */ + uint8_t id; + /** Main CS mode type */ + enum bt_conn_le_cs_main_mode main_mode_type; + /** Sub CS mode type */ + enum bt_conn_le_cs_sub_mode sub_mode_type; + /** Minimum number of CS main mode steps to be executed before a submode step is executed */ + uint8_t min_main_mode_steps; + /** Maximum number of CS main mode steps to be executed before a submode step is executed */ + uint8_t max_main_mode_steps; + /** 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 to be included at the beginning of each CS subevent */ + uint8_t mode_0_steps; + /** CS role */ + enum bt_conn_le_cs_role role; + /** RTT type */ + enum bt_conn_le_cs_rtt_type rtt_type; + /** CS Sync PHY */ + enum bt_conn_le_cs_sync_phy cs_sync_phy; + /** The number of times the Channel_Map field will be cycled through for non-mode-0 steps + * within a CS procedure + */ + uint8_t channel_map_repetition; + /** Channel selection type */ + enum bt_conn_le_cs_chsel_type channel_selection_type; + /** User-specified channel sequence shape */ + enum bt_conn_le_cs_ch3c_shape ch3c_shape; + /** Number of channels skipped in each rising and falling sequence */ + uint8_t ch3c_jump; + /** Channel map used for CS procedure + * Channels n = 0, 1, 23, 24, 25, 77, and 78 are not allowed and shall be set to zero. + * Channel 79 is reserved for future use and shall be set to zero. + * At least 15 channels shall be enabled. + */ + uint8_t channel_map[10]; +}; + +/** Callbacks for CS Test */ +struct bt_le_cs_test_cb { + /**@brief CS Test Subevent data. + * + * @param[in] Subevent results. + */ + void (*le_cs_test_subevent_data_available)(struct bt_conn_le_cs_subevent_result *data); + /**@brief CS Test End Complete. */ + void (*le_cs_test_end_complete)(void); +}; + +/** Subevent result step */ +struct bt_le_cs_subevent_step { + /** CS step mode. */ + uint8_t mode; + /** CS step channel index. */ + uint8_t channel; + /** Length of role- and mode-specific information being reported. */ + uint8_t data_len; + /** Pointer to role- and mode-specific information. */ + const uint8_t *data; +}; + +/** @brief Set all valid channel map bits + * + * This command is used to enable all valid channels in a + * given CS channel map + * + * @param channel_map Chanel map + */ +void bt_le_cs_set_valid_chmap_bits(uint8_t channel_map[10]); + /** @brief Read Remote Supported Capabilities * * This command is used to query the CS capabilities that are supported @@ -517,7 +560,7 @@ struct bt_cs_test_param { * * @return Zero on success or (negative) error code on failure. */ -int bt_cs_read_remote_supported_capabilities(struct bt_conn *conn); +int bt_le_cs_read_remote_supported_capabilities(struct bt_conn *conn); /** @brief Set Channel Sounding default settings. * @@ -531,8 +574,8 @@ int bt_cs_read_remote_supported_capabilities(struct bt_conn *conn); * * @return Zero on success or (negative) error code on failure. */ -int bt_cs_set_default_settings(struct bt_conn *conn, - const struct bt_cs_set_default_settings_param *params); +int bt_le_cs_set_default_settings(struct bt_conn *conn, + const struct bt_le_cs_set_default_settings_param *params); /** @brief Read Remote FAE Table * @@ -545,7 +588,20 @@ int bt_cs_set_default_settings(struct bt_conn *conn, * * @return Zero on success or (negative) error code on failure. */ -int bt_cs_read_remote_fae_table(struct bt_conn *conn); +int bt_le_cs_read_remote_fae_table(struct bt_conn *conn); + +/** @brief Register callbacks for the CS Test mode. + * + * Existing callbacks can be unregistered by providing NULL function + * pointers. + * + * @note To use this API @kconfig{CONFIG_BT_CHANNEL_SOUNDING_TEST} must be set. + * + * @param cs_test_cb Set of callbacks to be used with CS Test + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_le_cs_test_cb_register(struct bt_le_cs_test_cb cs_test_cb); /** @brief Start a CS test * @@ -561,13 +617,75 @@ int bt_cs_read_remote_fae_table(struct bt_conn *conn); * 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. + * @note To use this API @kconfig{CONFIG_BT_CHANNEL_SOUNDING_TEST} 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); +int bt_le_cs_start_test(const struct bt_le_cs_test_param *params); + +/** @brief Create CS configuration + * + * This command is used to create a new CS configuration or update an + * existing one with the config id specified. + * + * @note To use this API @kconfig{CONFIG_BT_CHANNEL_SOUNDING} must be set. + * + * @param conn Connection Object. + * @param params CS Create Config parameters + * @param context Controls whether the configuration is written to the local controller or + * both the local and the remote controller + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_le_cs_create_config(struct bt_conn *conn, struct bt_le_cs_create_config_params *params, + enum bt_le_cs_create_config_context context); + +/** @brief Create CS configuration + * + * This command is used to remove a CS configuration from the local controller + * identified by the config_id + * + * @note To use this API @kconfig{CONFIG_BT_CHANNEL_SOUNDING} must be set. + * + * @param conn Connection Object. + * @param config_id CS Config ID + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_le_cs_remove_config(struct bt_conn *conn, uint8_t config_id); + +/** @brief Stop ongoing CS Test + * + * This command is used to stop any CS test that is in progress. + * + * The controller is expected to finish reporting any subevent results + * before completing this termination. + * + * @note To use this API @kconfig{CONFIG_BT_CHANNEL_SOUNDING_TEST} must be set. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_le_cs_stop_test(void); + +/** @brief Parse CS Test Subevent Results + * + * A helper for parsing HCI-formatted step data found in channel sounding subevent results. + * + * A typical use-case is filtering out data which does not meet certain packet quality or NADM + * requirements. + * + * @warning This function will consume the data when parsing. + * + * @param step_data_buf Pointer to a buffer containing the step data. + * @param func Callback function which will be called for each step data found. + * The callback should return true to continue parsing, or false to stop. + * @param user_data User data to be passed to the callback. + */ +void bt_le_cs_step_data_parse(struct net_buf_simple *step_data_buf, + bool (*func)(struct bt_le_cs_subevent_step *step, void *user_data), + void *user_data); #ifdef __cplusplus } diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 31b30bbcf96..131b81134c1 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -2582,6 +2582,38 @@ struct bt_hci_op_le_cs_test { uint8_t override_parameters_data[]; } __packed; +#define BT_HCI_OP_LE_CS_CREATE_CONFIG BT_OP(BT_OGF_LE, 0x0090) /* 0x2090 */ + +struct bt_hci_cp_le_cs_create_config { + uint16_t handle; + uint8_t config_id; + uint8_t create_context; + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t min_main_mode_steps; + uint8_t max_main_mode_steps; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t channel_map[10]; + uint8_t channel_map_repetition; + uint8_t channel_selection_type; + uint8_t ch3c_shape; + uint8_t ch3c_jump; + uint8_t reserved; +} __packed; + +#define BT_HCI_OP_LE_CS_REMOVE_CONFIG BT_OP(BT_OGF_LE, 0x0091) /* 0x2091 */ + +struct bt_hci_cp_le_cs_remove_config { + uint16_t handle; + uint8_t config_id; +} __packed; + +#define BT_HCI_OP_LE_CS_TEST_END BT_OP(BT_OGF_LE, 0x0096) /* 0x2096 */ + /* Event definitions */ #define BT_HCI_EVT_UNKNOWN 0x00 @@ -3403,6 +3435,212 @@ struct bt_hci_evt_le_cs_read_remote_fae_table_complete { uint8_t remote_fae_table[72]; } __packed; +#define BT_HCI_LE_CS_CONFIG_ACTION_REMOVED 0x00 +#define BT_HCI_LE_CS_CONFIG_ACTION_CREATED 0x01 + +#define BT_HCI_EVT_LE_CS_CONFIG_COMPLETE 0x2F +struct bt_hci_evt_le_cs_config_complete { + uint8_t status; + uint16_t handle; + uint8_t config_id; + uint8_t action; + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t min_main_mode_steps; + uint8_t max_main_mode_steps; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t channel_map[10]; + uint8_t channel_map_repetition; + uint8_t channel_selection_type; + uint8_t ch3c_shape; + uint8_t ch3c_jump; + uint8_t reserved; + uint8_t t_ip1_time; + uint8_t t_ip2_time; + uint8_t t_fcs_time; + uint8_t t_pm_time; +} __packed; + +#define BT_HCI_LE_CS_TEST_CONN_HANDLE 0x0FFF + +#define BT_HCI_LE_CS_PROCEDURE_DONE_STATUS_COMPLETE 0x0 +#define BT_HCI_LE_CS_PROCEDURE_DONE_STATUS_PARTIAL 0x1 +#define BT_HCI_LE_CS_PROCEDURE_DONE_STATUS_ABORTED 0xF + +#define BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_COMPLETE 0x0 +#define BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL 0x1 +#define BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_ABORTED 0xF + +#define BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_NO_ABORT 0x0 +#define BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_LOCAL_HOST_OR_REMOTE_REQUEST 0x1 +#define BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_TOO_FEW_CHANNELS 0x2 +#define BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_CHMAP_INSTANT_PASSED 0x3 +#define BT_HCI_LE_CS_PROCEDURE_ABORT_REASON_UNSPECIFIED 0xF + +#define BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_NO_ABORT 0x0 +#define BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_LOCAL_HOST_OR_REMOTE_REQUEST 0x1 +#define BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_NO_CS_SYNC_RECEIVED 0x2 +#define BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_SCHED_CONFLICT 0x3 +#define BT_HCI_LE_CS_SUBEVENT_ABORT_REASON_UNSPECIFIED 0xF + +#define BT_HCI_LE_CS_SUBEVENT_RESULT_N_AP_IGNORED 0x00 +#define BT_HCI_LE_CS_SUBEVENT_RESULT_N_AP_1 0x01 +#define BT_HCI_LE_CS_SUBEVENT_RESULT_N_AP_2 0x02 +#define BT_HCI_LE_CS_SUBEVENT_RESULT_N_AP_3 0x03 +#define BT_HCI_LE_CS_SUBEVENT_RESULT_N_AP_4 0x04 + +#define BT_HCI_LE_CS_SUBEVENT_RESULT_FREQ_COMPENSATION_NOT_AVAILABLE 0xC000 + +#define BT_HCI_LE_CS_SUBEVENT_RESULT_PCT_NOT_AVAILABLE 0xFFFFFFFF + +#define BT_HCI_LE_CS_REF_POWER_LEVEL_UNAVAILABLE 0x7F + +#define BT_HCI_LE_CS_PCT_MASK 0xFFF + +#define BT_HCI_LE_CS_TONE_QUALITY_HIGH 0x0 +#define BT_HCI_LE_CS_TONE_QUALITY_MED 0x1 +#define BT_HCI_LE_CS_TONE_QUALITY_LOW 0x2 +#define BT_HCI_LE_CS_TONE_QUALITY_UNAVAILABLE 0x3 + +#define BT_HCI_LE_CS_NOT_TONE_EXT_SLOT 0x0 +#define BT_HCI_LE_CS_TONE_EXT_SLOT_EXT_NOT_EXPECTED 0x1 +#define BT_HCI_LE_CS_TONE_EXT_SLOT_EXT_EXPECTED 0x2 + +#define BT_HCI_LE_CS_TIME_DIFFERENCE_NOT_AVAILABLE 0x8000 + +#define BT_HCI_LE_CS_PACKET_NADM_ATTACK_EXT_UNLIKELY 0x00 +#define BT_HCI_LE_CS_PACKET_NADM_ATTACK_VERY_UNLIKELY 0x01 +#define BT_HCI_LE_CS_PACKET_NADM_ATTACK_UNLIKELY 0x02 +#define BT_HCI_LE_CS_PACKET_NADM_ATTACK_POSSIBLE 0x03 +#define BT_HCI_LE_CS_PACKET_NADM_ATTACK_LIKELY 0x04 +#define BT_HCI_LE_CS_PACKET_NADM_ATTACK_VERY_LIKELY 0x05 +#define BT_HCI_LE_CS_PACKET_NADM_ATTACK_EXT_LIKELY 0x06 +#define BT_HCI_LE_CS_PACKET_NADM_UNKNOWN 0xFF + +#define BT_HCI_EVT_LE_CS_SUBEVENT_RESULT 0x31 +/** Subevent result step data format: Mode 0 Initiator */ +struct bt_hci_le_cs_step_data_mode_0_initiator { + uint8_t packet_quality_aa_check: 4; + uint8_t packet_quality_bit_errors: 4; + uint8_t packet_rssi; + uint8_t packet_antenna; + uint16_t measured_freq_offset; +} __packed; + +/** Subevent result step data format: Mode 0 Reflector */ +struct bt_hci_le_cs_step_data_mode_0_reflector { + uint8_t packet_quality_aa_check: 4; + uint8_t packet_quality_bit_errors: 4; + uint8_t packet_rssi; + uint8_t packet_antenna; +} __packed; + +/** Subevent result step data format: Mode 1 */ +struct bt_hci_le_cs_step_data_mode_1 { + uint8_t packet_quality_aa_check: 4; + uint8_t packet_quality_bit_errors: 4; + uint8_t packet_nadm; + uint8_t packet_rssi; + union { + uint16_t toa_tod_initiator; + uint16_t tod_toa_reflector; + }; + uint8_t packet_antenna; +} __packed; + +/** Subevent result step data format: Mode 1 with sounding sequence RTT support */ +struct bt_hci_le_cs_step_data_mode_1_ss_rtt { + uint8_t packet_quality_aa_check: 4; + uint8_t packet_quality_bit_errors: 4; + uint8_t packet_nadm; + uint8_t packet_rssi; + union { + uint16_t toa_tod_initiator; + uint16_t tod_toa_reflector; + }; + uint8_t packet_antenna; + uint8_t packet_pct1[4]; + uint8_t packet_pct2[4]; +} __packed; + + +/** Format for per-antenna path step data in modes 2 and 3 */ +struct bt_hci_le_cs_step_data_tone_info { + uint8_t phase_correction_term[3]; + uint8_t quality_indicator: 4; + uint8_t extension_indicator: 4; +} __packed; + +/** Subevent result step data format: Mode 2 */ +struct bt_hci_le_cs_step_data_mode_2 { + uint8_t antenna_permutation_index; + struct bt_hci_le_cs_step_data_tone_info tone_info[]; +} __packed; + +/** Subevent result step data format: Mode 3 */ +struct bt_hci_le_cs_step_data_mode_3 { + uint8_t packet_quality_aa_check: 4; + uint8_t packet_quality_bit_errors: 4; + uint8_t packet_nadm; + uint8_t packet_rssi; + union { + uint16_t toa_tod_initiator; + uint16_t tod_toa_reflector; + }; + uint8_t packet_antenna; + uint8_t antenna_permutation_index; + struct bt_hci_le_cs_step_data_tone_info tone_info[]; +} __packed; + +/** Subevent result step data format: Mode 3 with sounding sequence RTT support */ +struct bt_hci_le_cs_step_data_mode_3_ss_rtt { + uint8_t packet_quality_aa_check: 4; + uint8_t packet_quality_bit_errors: 4; + uint8_t packet_nadm; + uint8_t packet_rssi; + union { + uint16_t toa_tod_initiator; + uint16_t tod_toa_reflector; + }; + uint8_t packet_antenna; + uint8_t packet_pct1[4]; + uint8_t packet_pct2[4]; + uint8_t antenna_permutation_index; + struct bt_hci_le_cs_step_data_tone_info tone_info[]; +} __packed; + +struct bt_hci_evt_le_cs_subevent_result_step { + uint8_t step_mode; + uint8_t step_channel; + uint8_t step_data_length; + uint8_t step_data[]; +} __packed; + +struct bt_hci_evt_le_cs_subevent_result { + uint16_t conn_handle; + uint8_t config_id; + uint16_t start_acl_conn_event_counter; + uint16_t procedure_counter; + uint16_t frequency_compensation; + uint8_t reference_power_level; + uint8_t procedure_done_status; + uint8_t subevent_done_status; + uint8_t procedure_abort_reason: 4; + uint8_t subevent_abort_reason: 4; + uint8_t num_antenna_paths; + uint8_t num_steps_reported; + uint8_t steps[]; +} __packed; + +#define BT_HCI_EVT_LE_CS_TEST_END_COMPLETE 0x33 +struct bt_hci_evt_le_cs_test_end_complete { + uint8_t status; +} __packed; + /* Event mask bits */ #define BT_EVT_BIT(n) (1ULL << (n)) @@ -3494,6 +3732,9 @@ struct bt_hci_evt_le_cs_read_remote_fae_table_complete { #define BT_EVT_MASK_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE BT_EVT_BIT(43) #define BT_EVT_MASK_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE BT_EVT_BIT(44) +#define BT_EVT_MASK_LE_CS_CONFIG_COMPLETE BT_EVT_BIT(46) +#define BT_EVT_MASK_LE_CS_SUBEVENT_RESULT BT_EVT_BIT(48) +#define BT_EVT_MASK_LE_CS_TEST_END_COMPLETE BT_EVT_BIT(50) /** HCI Error Codes, BT Core Spec v5.4 [Vol 1, Part F]. */ #define BT_HCI_ERR_SUCCESS 0x00 diff --git a/soc/nordic/common/Kconfig.peripherals b/soc/nordic/common/Kconfig.peripherals index 3443d514d16..dc06a1f7c96 100644 --- a/soc/nordic/common/Kconfig.peripherals +++ b/soc/nordic/common/Kconfig.peripherals @@ -200,6 +200,9 @@ config HAS_HW_NRF_RADIO_BLE_2M config HAS_HW_NRF_RADIO_BLE_CODED def_bool $(dt_nodelabel_bool_prop,radio,ble-coded-phy-supported) +config HAS_HW_NRF_RADIO_CS + def_bool $(dt_nodelabel_bool_prop,radio,cs-supported) + config HAS_HW_NRF_RADIO_DFE def_bool $(dt_nodelabel_bool_prop,radio,dfe-supported) diff --git a/subsys/bluetooth/Kconfig b/subsys/bluetooth/Kconfig index e8c7d9676d7..bf6feff37eb 100644 --- a/subsys/bluetooth/Kconfig +++ b/subsys/bluetooth/Kconfig @@ -190,12 +190,19 @@ config BT_SUBRATING Bluetooth Core specification, Version 5.4 | Vol 6, Part B, Section 4.6.35. config BT_CHANNEL_SOUNDING - bool "Channel Sounding support" + bool "Channel Sounding [EXPERIMENTAL]" select EXPERIMENTAL depends on !BT_CTLR || BT_CTLR_CHANNEL_SOUNDING_SUPPORT help Enable support for Bluetooth 6.0 Channel Sounding feature. +config BT_CHANNEL_SOUNDING_TEST + bool "Channel Sounding Test [EXPERIMENTAL]" + select EXPERIMENTAL + depends on BT_CHANNEL_SOUNDING + help + Enable support for Channel Sounding test mode. + endif # BT_CONN rsource "Kconfig.iso" diff --git a/subsys/bluetooth/common/Kconfig b/subsys/bluetooth/common/Kconfig index a34dbae692e..8bec5ba90d5 100644 --- a/subsys/bluetooth/common/Kconfig +++ b/subsys/bluetooth/common/Kconfig @@ -100,10 +100,11 @@ config BT_BUF_ACL_RX_COUNT config BT_BUF_EVT_RX_SIZE int "Maximum supported HCI Event buffer length" - default $(UINT8_MAX) if (BT_EXT_ADV && BT_OBSERVER) || BT_PER_ADV_SYNC || BT_DF_CONNECTION_CTE_RX || BT_CLASSIC + default $(UINT8_MAX) if (BT_EXT_ADV && BT_OBSERVER) || BT_PER_ADV_SYNC || BT_DF_CONNECTION_CTE_RX || BT_CLASSIC || BT_CHANNEL_SOUNDING # LE Read Supported Commands command complete event. default 68 range 68 $(UINT8_MAX) + range 78 $(UINT8_MAX) if BT_CHANNEL_SOUNDING help Maximum supported HCI event buffer size. This value does not include the HCI Event header. diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 9f9c0441dff..d7a110eb0c3 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -3336,14 +3336,14 @@ void notify_remote_cs_capabilities(struct bt_conn *conn, struct bt_conn_le_cs_ca struct bt_conn_cb *callback; SYS_SLIST_FOR_EACH_CONTAINER(&conn_cbs, callback, _node) { - if (callback->remote_cs_capabilities_available) { - callback->remote_cs_capabilities_available(conn, ¶ms); + if (callback->le_cs_remote_capabilities_available) { + callback->le_cs_remote_capabilities_available(conn, ¶ms); } } STRUCT_SECTION_FOREACH(bt_conn_cb, cb) { - if (cb->remote_cs_capabilities_available) { - cb->remote_cs_capabilities_available(conn, ¶ms); + if (cb->le_cs_remote_capabilities_available) { + cb->le_cs_remote_capabilities_available(conn, ¶ms); } } } @@ -3353,14 +3353,65 @@ void notify_remote_cs_fae_table(struct bt_conn *conn, struct bt_conn_le_cs_fae_t struct bt_conn_cb *callback; SYS_SLIST_FOR_EACH_CONTAINER(&conn_cbs, callback, _node) { - if (callback->remote_cs_fae_table_available) { - callback->remote_cs_fae_table_available(conn, ¶ms); + if (callback->le_cs_remote_fae_table_available) { + callback->le_cs_remote_fae_table_available(conn, ¶ms); } } STRUCT_SECTION_FOREACH(bt_conn_cb, cb) { - if (cb->remote_cs_fae_table_available) { - cb->remote_cs_fae_table_available(conn, ¶ms); + if (cb->le_cs_remote_fae_table_available) { + cb->le_cs_remote_fae_table_available(conn, ¶ms); + } + } +} + +void notify_cs_config_created(struct bt_conn *conn, struct bt_conn_le_cs_config *params) +{ + struct bt_conn_cb *callback; + + SYS_SLIST_FOR_EACH_CONTAINER(&conn_cbs, callback, _node) { + if (callback->le_cs_config_created) { + callback->le_cs_config_created(conn, params); + } + } + + STRUCT_SECTION_FOREACH(bt_conn_cb, cb) { + if (cb->le_cs_config_created) { + cb->le_cs_config_created(conn, params); + } + } +} + +void notify_cs_config_removed(struct bt_conn *conn, uint8_t config_id) +{ + struct bt_conn_cb *callback; + + SYS_SLIST_FOR_EACH_CONTAINER(&conn_cbs, callback, _node) { + if (callback->le_cs_config_removed) { + callback->le_cs_config_removed(conn, config_id); + } + } + + STRUCT_SECTION_FOREACH(bt_conn_cb, cb) { + if (cb->le_cs_config_removed) { + cb->le_cs_config_removed(conn, config_id); + } + } +} + +void notify_cs_subevent_result(struct bt_conn *conn, struct bt_conn_le_cs_subevent_result *result) +{ + struct bt_conn_cb *callback; + + SYS_SLIST_FOR_EACH_CONTAINER(&conn_cbs, callback, _node) { + if (callback->le_cs_subevent_data_available) { + callback->le_cs_subevent_data_available(conn, result); + } + } + + STRUCT_SECTION_FOREACH(bt_conn_cb, cb) { + if (cb->le_cs_subevent_data_available) { + cb->le_cs_subevent_data_available(conn, result); } } } diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 4cc4e70d858..37e49afa964 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -498,6 +498,12 @@ void notify_remote_cs_capabilities(struct bt_conn *conn, void notify_remote_cs_fae_table(struct bt_conn *conn, struct bt_conn_le_cs_fae_table params); +void notify_cs_config_created(struct bt_conn *conn, struct bt_conn_le_cs_config *params); + +void notify_cs_config_removed(struct bt_conn *conn, uint8_t config_id); + +void notify_cs_subevent_result(struct bt_conn *conn, struct bt_conn_le_cs_subevent_result *result); + #if defined(CONFIG_BT_SMP) /* If role specific LTK is present */ bool bt_conn_ltk_present(const struct bt_conn *conn); diff --git a/subsys/bluetooth/host/cs.c b/subsys/bluetooth/host/cs.c index 5a713ad2457..75d5f21cf2c 100644 --- a/subsys/bluetooth/host/cs.c +++ b/subsys/bluetooth/host/cs.c @@ -18,7 +18,28 @@ LOG_MODULE_REGISTER(bt_cs); #if defined(CONFIG_BT_CHANNEL_SOUNDING) -int bt_cs_read_remote_supported_capabilities(struct bt_conn *conn) +#if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST) +static struct bt_le_cs_test_cb cs_test_callbacks; +#endif + +void bt_le_cs_set_valid_chmap_bits(uint8_t channel_map[10]) +{ + memset(channel_map, 0xFF, 10); + + /** Channels n = 0, 1, 23, 24, 25, 77, and 78 are not allowed and shall be set to zero. + * Channel 79 is reserved for future use and shall be set to zero. + */ + BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 0, 0); + BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 1, 0); + BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 23, 0); + BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 24, 0); + BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 25, 0); + BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 77, 0); + BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 78, 0); + BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 79, 0); +} + +int bt_le_cs_read_remote_supported_capabilities(struct bt_conn *conn) { struct bt_hci_cp_le_read_remote_supported_capabilities *cp; struct net_buf *buf; @@ -150,8 +171,8 @@ void bt_hci_le_cs_read_remote_supported_capabilities_complete(struct net_buf *bu bt_conn_unref(conn); } -int bt_cs_set_default_settings(struct bt_conn *conn, - const struct bt_cs_set_default_settings_param *params) +int bt_le_cs_set_default_settings(struct bt_conn *conn, + const struct bt_le_cs_set_default_settings_param *params) { struct bt_hci_cp_le_cs_set_default_settings *cp; struct net_buf *buf; @@ -178,7 +199,7 @@ int bt_cs_set_default_settings(struct bt_conn *conn, return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_SET_DEFAULT_SETTINGS, buf, NULL); } -int bt_cs_read_remote_fae_table(struct bt_conn *conn) +int bt_le_cs_read_remote_fae_table(struct bt_conn *conn) { struct bt_hci_cp_le_read_remote_fae_table *cp; struct net_buf *buf; @@ -223,7 +244,14 @@ 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) +#if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST) +int bt_le_cs_test_cb_register(struct bt_le_cs_test_cb cb) +{ + cs_test_callbacks = cb; + return 0; +} + +int bt_le_cs_start_test(const struct bt_le_cs_test_param *params) { struct bt_hci_op_le_cs_test *cp; struct net_buf *buf; @@ -325,5 +353,249 @@ int bt_cs_start_test(const struct bt_cs_test_param *params) return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_TEST, buf, NULL); } +#endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */ + +void bt_hci_le_cs_subevent_result(struct net_buf *buf) +{ + struct bt_conn *conn = NULL; + struct bt_hci_evt_le_cs_subevent_result *evt; + struct bt_conn_le_cs_subevent_result result; + struct net_buf_simple step_data_buf; + + if (buf->len < sizeof(*evt)) { + LOG_ERR("Unexpected end of buffer"); + return; + } + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + + if (evt->subevent_done_status == BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL) { + LOG_WRN("Discarded incomplete CS subevent results."); + return; + } + +#if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST) + if (sys_le16_to_cpu(evt->conn_handle) == BT_HCI_LE_CS_TEST_CONN_HANDLE) { + if (!cs_test_callbacks.le_cs_test_subevent_data_available) { + LOG_WRN("No callback registered. Discarded subevent results from CS Test."); + return; + } + } else +#endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */ + { + conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE); + if (!conn) { + LOG_ERR("Unknown connection handle when processing subevent results"); + return; + } + } + + result.header.procedure_counter = sys_le16_to_cpu(evt->procedure_counter); + result.header.frequency_compensation = sys_le16_to_cpu(evt->frequency_compensation); + result.header.procedure_done_status = evt->procedure_done_status; + result.header.subevent_done_status = evt->subevent_done_status; + result.header.procedure_abort_reason = evt->procedure_abort_reason; + result.header.subevent_abort_reason = evt->subevent_abort_reason; + result.header.reference_power_level = evt->reference_power_level; + result.header.num_antenna_paths = evt->num_antenna_paths; + result.header.num_steps_reported = evt->num_steps_reported; + + if (evt->num_steps_reported) { + net_buf_simple_init_with_data(&step_data_buf, + evt->steps, + buf->len); + result.step_data_buf = &step_data_buf; + } else { + result.step_data_buf = NULL; + } + +#if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST) + if (sys_le16_to_cpu(evt->conn_handle) == BT_HCI_LE_CS_TEST_CONN_HANDLE) { + result.header.config_id = 0; + result.header.start_acl_conn_event = 0; + + cs_test_callbacks.le_cs_test_subevent_data_available(&result); + + } else +#endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */ + { + result.header.config_id = evt->config_id; + result.header.start_acl_conn_event = + sys_le16_to_cpu(evt->start_acl_conn_event_counter); + + notify_cs_subevent_result(conn, &result); + + bt_conn_unref(conn); + } +} + +void bt_hci_le_cs_config_complete_event(struct net_buf *buf) +{ + struct bt_hci_evt_le_cs_config_complete *evt; + struct bt_conn_le_cs_config config; + struct bt_conn *conn; + + if (buf->len < sizeof(*evt)) { + LOG_ERR("Unexpected end of buffer"); + return; + } + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + if (evt->status) { + LOG_INF("CS Config failed (status 0x%02X)", evt->status); + return; + } + + conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->handle), BT_CONN_TYPE_LE); + if (!conn) { + LOG_ERR("Could not lookup connection handle when reading CS configuration"); + return; + } + + if (evt->action == BT_HCI_LE_CS_CONFIG_ACTION_REMOVED) { + notify_cs_config_removed(conn, evt->config_id); + bt_conn_unref(conn); + return; + } + + config.id = evt->config_id; + config.main_mode_type = evt->main_mode_type; + config.sub_mode_type = evt->sub_mode_type; + config.min_main_mode_steps = evt->min_main_mode_steps; + config.max_main_mode_steps = evt->max_main_mode_steps; + config.main_mode_repetition = evt->main_mode_repetition; + config.mode_0_steps = evt->mode_0_steps; + config.role = evt->role; + config.rtt_type = evt->rtt_type; + config.cs_sync_phy = evt->cs_sync_phy; + config.channel_map_repetition = evt->channel_map_repetition; + config.channel_selection_type = evt->channel_selection_type; + config.ch3c_shape = evt->ch3c_shape; + config.ch3c_jump = evt->ch3c_jump; + config.t_ip1_time_us = evt->t_ip1_time; + config.t_ip2_time_us = evt->t_ip2_time; + config.t_fcs_time_us = evt->t_fcs_time; + config.t_pm_time_us = evt->t_pm_time; + memcpy(config.channel_map, evt->channel_map, ARRAY_SIZE(config.channel_map)); + + notify_cs_config_created(conn, &config); + bt_conn_unref(conn); +} + +int bt_le_cs_create_config(struct bt_conn *conn, struct bt_le_cs_create_config_params *params, + enum bt_le_cs_create_config_context context) +{ + struct bt_hci_cp_le_cs_create_config *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_CS_CREATE_CONFIG, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->config_id = params->id; + cp->create_context = context; + cp->main_mode_type = params->main_mode_type; + cp->sub_mode_type = params->sub_mode_type; + cp->min_main_mode_steps = params->min_main_mode_steps; + cp->max_main_mode_steps = params->max_main_mode_steps; + 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->channel_map_repetition = params->channel_map_repetition; + cp->channel_selection_type = params->channel_selection_type; + cp->ch3c_shape = params->ch3c_shape; + cp->ch3c_jump = params->ch3c_jump; + cp->reserved = 0; + memcpy(cp->channel_map, params->channel_map, ARRAY_SIZE(cp->channel_map)); + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_CREATE_CONFIG, buf, NULL); +} + +int bt_le_cs_remove_config(struct bt_conn *conn, uint8_t config_id) +{ + struct bt_hci_cp_le_cs_remove_config *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_CS_REMOVE_CONFIG, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->config_id = config_id; + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_REMOVE_CONFIG, buf, NULL); +} + +#if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST) +int bt_le_cs_stop_test(void) +{ + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_CS_TEST_END, 0); + if (!buf) { + return -ENOBUFS; + } + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_TEST_END, buf, NULL); +} + +void bt_hci_le_cs_test_end_complete(struct net_buf *buf) +{ + struct bt_hci_evt_le_cs_test_end_complete *evt; + + if (buf->len < sizeof(*evt)) { + LOG_ERR("Unexpected end of buffer"); + return; + } + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + if (evt->status) { + LOG_INF("CS Test End failed with status 0x%02X", evt->status); + return; + } + + if (cs_test_callbacks.le_cs_test_end_complete) { + cs_test_callbacks.le_cs_test_end_complete(); + } +} +#endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */ + +void bt_le_cs_step_data_parse(struct net_buf_simple *step_data_buf, + bool (*func)(struct bt_le_cs_subevent_step *step, void *user_data), + void *user_data) +{ + if (!step_data_buf) { + LOG_INF("Tried to parse empty step data."); + return; + } + + while (step_data_buf->len > 1) { + struct bt_le_cs_subevent_step step; + + step.mode = net_buf_simple_pull_u8(step_data_buf); + step.channel = net_buf_simple_pull_u8(step_data_buf); + step.data_len = net_buf_simple_pull_u8(step_data_buf); + + if (step.data_len == 0) { + LOG_WRN("Encountered zero-length step data."); + return; + } + + step.data = step_data_buf->data; + + if (!func(&step, user_data)) { + return; + } + + net_buf_simple_pull(step_data_buf, step.data_len); + } +} #endif /* CONFIG_BT_CHANNEL_SOUNDING */ diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index b1ab4fbb664..f2f6c10601a 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -2828,6 +2828,16 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE, bt_hci_le_cs_read_remote_fae_table_complete, sizeof(struct bt_hci_evt_le_cs_read_remote_fae_table_complete)), + EVENT_HANDLER(BT_HCI_EVT_LE_CS_CONFIG_COMPLETE, bt_hci_le_cs_config_complete_event, + sizeof(struct bt_hci_evt_le_cs_config_complete)), + EVENT_HANDLER(BT_HCI_EVT_LE_CS_SUBEVENT_RESULT, + bt_hci_le_cs_subevent_result, + sizeof(struct bt_hci_evt_le_cs_subevent_result)), +#if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST) + EVENT_HANDLER(BT_HCI_EVT_LE_CS_TEST_END_COMPLETE, + bt_hci_le_cs_test_end_complete, + sizeof(struct bt_hci_evt_le_cs_test_end_complete)), +#endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */ #endif /* CONFIG_BT_CHANNEL_SOUNDING */ }; @@ -3404,6 +3414,9 @@ static int le_set_event_mask(void) BT_FEAT_LE_CHANNEL_SOUNDING(bt_dev.le.features)) { mask |= BT_EVT_MASK_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE; mask |= BT_EVT_MASK_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE; + mask |= BT_EVT_MASK_LE_CS_CONFIG_COMPLETE; + mask |= BT_EVT_MASK_LE_CS_SUBEVENT_RESULT; + mask |= BT_EVT_MASK_LE_CS_TEST_END_COMPLETE; } sys_put_le64(mask, cp_mask->events); diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 590d85a6c49..27387c9c53f 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -541,6 +541,9 @@ void bt_hci_le_past_received_v2(struct net_buf *buf); /* CS HCI event handlers */ void bt_hci_le_cs_read_remote_supported_capabilities_complete(struct net_buf *buf); void bt_hci_le_cs_read_remote_fae_table_complete(struct net_buf *buf); +void bt_hci_le_cs_config_complete_event(struct net_buf *buf); +void bt_hci_le_cs_subevent_result(struct net_buf *buf); +void bt_hci_le_cs_test_end_complete(struct net_buf *buf); /* Adv HCI event handlers */ void bt_hci_le_adv_set_terminated(struct net_buf *buf); diff --git a/subsys/bluetooth/shell/bt.c b/subsys/bluetooth/shell/bt.c index 25841fd48d6..b08f67835e1 100644 --- a/subsys/bluetooth/shell/bt.c +++ b/subsys/bluetooth/shell/bt.c @@ -1052,6 +1052,64 @@ void print_remote_cs_fae_table(struct bt_conn *conn, struct bt_conn_le_cs_fae_ta shell_print(ctx_shell, "Received FAE Table: "); shell_hexdump(ctx_shell, params->remote_fae_table, 72); } + +static void le_cs_config_created(struct bt_conn *conn, struct bt_conn_le_cs_config *config) +{ + const char *mode_str[5] = {"Unused", "1 (RTT)", "2 (PBR)", "3 (RTT + PBR)", "Invalid"}; + const char *role_str[3] = {"Initiator", "Reflector", "Invalid"}; + const char *rtt_type_str[8] = {"AA only", "32-bit sounding", "96-bit sounding", + "32-bit random", "64-bit random", "96-bit random", + "128-bit random", "Invalid"}; + const char *phy_str[4] = {"Invalid", "LE 1M PHY", "LE 2M PHY", "LE 2M 2BT PHY"}; + const char *chsel_type_str[3] = {"Algorithm #3b", "Algorithm #3c", "Invalid"}; + const char *ch3c_shape_str[3] = {"Hat shape", "X shape", "Invalid"}; + + uint8_t main_mode_idx = config->main_mode_type > 0 && config->main_mode_type < 4 + ? config->main_mode_type + : 4; + uint8_t sub_mode_idx = config->sub_mode_type < 4 ? config->sub_mode_type : 0; + uint8_t role_idx = MIN(config->role, 2); + uint8_t rtt_type_idx = MIN(config->rtt_type, 7); + uint8_t phy_idx = + config->cs_sync_phy > 0 && config->cs_sync_phy < 4 ? config->cs_sync_phy : 0; + uint8_t chsel_type_idx = MIN(config->channel_selection_type, 2); + uint8_t ch3c_shape_idx = MIN(config->ch3c_shape, 2); + + shell_print(ctx_shell, + "New CS config created:\n" + "- ID: %d\n" + "- Role: %s\n" + "- Main mode: %s\n" + "- Sub mode: %s\n" + "- RTT type: %s\n" + "- Main mode steps: %d - %d\n" + "- Main mode repetition: %d\n" + "- Mode 0 steps: %d\n" + "- CS sync PHY: %s\n" + "- T_IP1 time: %d\n" + "- T_IP2 time: %d\n" + "- T_FCS time: %d\n" + "- T_PM time: %d\n" + "- Channel map: 0x%08X%08X%04X\n" + "- Channel map repetition: %d\n" + "- Channel selection type: %s\n" + "- Ch3c shape: %s\n" + "- Ch3c jump: %d\n", + config->id, role_str[role_idx], mode_str[main_mode_idx], mode_str[sub_mode_idx], + rtt_type_str[rtt_type_idx], config->min_main_mode_steps, + config->max_main_mode_steps, config->main_mode_repetition, config->mode_0_steps, + phy_str[phy_idx], config->t_ip1_time_us, config->t_ip2_time_us, + config->t_fcs_time_us, config->t_pm_time_us, + sys_get_le32(&config->channel_map[6]), sys_get_le32(&config->channel_map[2]), + sys_get_le16(&config->channel_map[0]), config->channel_map_repetition, + chsel_type_str[chsel_type_idx], ch3c_shape_str[ch3c_shape_idx], + config->ch3c_jump); +} + +static void le_cs_config_removed(struct bt_conn *conn, uint8_t config_id) +{ + shell_print(ctx_shell, "CS config %d is removed", config_id); +} #endif static struct bt_conn_cb conn_callbacks = { @@ -1084,8 +1142,10 @@ static struct bt_conn_cb conn_callbacks = { .subrate_changed = subrate_changed, #endif #if defined(CONFIG_BT_CHANNEL_SOUNDING) - .remote_cs_capabilities_available = print_remote_cs_capabilities, - .remote_cs_fae_table_available = print_remote_cs_fae_table, + .le_cs_remote_capabilities_available = print_remote_cs_capabilities, + .le_cs_remote_fae_table_available = print_remote_cs_fae_table, + .le_cs_config_created = le_cs_config_created, + .le_cs_config_removed = le_cs_config_removed, #endif }; #endif /* CONFIG_BT_CONN */ diff --git a/subsys/bluetooth/shell/cs.c b/subsys/bluetooth/shell/cs.c index b8f32be61be..fbc55623b14 100644 --- a/subsys/bluetooth/shell/cs.c +++ b/subsys/bluetooth/shell/cs.c @@ -28,11 +28,12 @@ static int check_cs_sync_antenna_selection_input(uint16_t input) { - if (input != BT_CS_ANTENNA_SELECTION_OPT_ONE && input != BT_CS_ANTENNA_SELECTION_OPT_TWO && - input != BT_CS_ANTENNA_SELECTION_OPT_THREE && - input != BT_CS_ANTENNA_SELECTION_OPT_FOUR && - input != BT_CS_ANTENNA_SELECTION_OPT_REPETITIVE && - input != BT_CS_ANTENNA_SELECTION_OPT_NO_RECOMMENDATION) { + if (input != BT_LE_CS_ANTENNA_SELECTION_OPT_ONE && + input != BT_LE_CS_ANTENNA_SELECTION_OPT_TWO && + input != BT_LE_CS_ANTENNA_SELECTION_OPT_THREE && + input != BT_LE_CS_ANTENNA_SELECTION_OPT_FOUR && + input != BT_LE_CS_ANTENNA_SELECTION_OPT_REPETITIVE && + input != BT_LE_CS_ANTENNA_SELECTION_OPT_NO_RECOMMENDATION) { return -EINVAL; } @@ -48,9 +49,10 @@ static int cmd_read_remote_supported_capabilities(const struct shell *sh, size_t return -ENOEXEC; } - err = bt_cs_read_remote_supported_capabilities(default_conn); + err = bt_le_cs_read_remote_supported_capabilities(default_conn); if (err) { - shell_error(sh, "bt_cs_read_remote_supported_capabilities returned error %d", err); + shell_error(sh, "bt_le_cs_read_remote_supported_capabilities returned error %d", + err); return -ENOEXEC; } @@ -60,7 +62,7 @@ static int cmd_read_remote_supported_capabilities(const struct shell *sh, size_t static int cmd_set_default_settings(const struct shell *sh, size_t argc, char *argv[]) { int err = 0; - struct bt_cs_set_default_settings_param params; + struct bt_le_cs_set_default_settings_param params; uint16_t antenna_input; int16_t tx_power_input; @@ -107,9 +109,9 @@ static int cmd_set_default_settings(const struct shell *sh, size_t argc, char *a params.cs_sync_antenna_selection = antenna_input; params.max_tx_power = tx_power_input; - err = bt_cs_set_default_settings(default_conn, ¶ms); + err = bt_le_cs_set_default_settings(default_conn, ¶ms); if (err) { - shell_error(sh, "bt_cs_set_default_settings returned error %d", err); + shell_error(sh, "bt_le_cs_set_default_settings returned error %d", err); return -ENOEXEC; } @@ -125,24 +127,70 @@ static int cmd_read_remote_fae_table(const struct shell *sh, size_t argc, char * return -ENOEXEC; } - err = bt_cs_read_remote_fae_table(default_conn); + err = bt_le_cs_read_remote_fae_table(default_conn); if (err) { - shell_error(sh, "bt_cs_read_remote_fae_table returned error %d", err); + shell_error(sh, "bt_le_cs_read_remote_fae_table returned error %d", err); return -ENOEXEC; } return 0; } +static bool process_step_data(struct bt_le_cs_subevent_step *step, void *user_data) +{ + shell_print(ctx_shell, "Subevent results contained step data: "); + shell_print(ctx_shell, "- Step mode %d\n" + "- Step channel %d\n" + "- Step data hexdump:", + step->mode, + step->channel); + shell_hexdump(ctx_shell, step->data, step->data_len); + + return true; +} + +static void cs_test_subevent_data_cb(struct bt_conn_le_cs_subevent_result *result) +{ + shell_print(ctx_shell, "Received subevent results."); + shell_print(ctx_shell, "Subevent Header:\n" + "- Procedure Counter: %d\n" + "- Frequency Compensation: 0x%04x\n" + "- Reference Power Level: %d\n" + "- Procedure Done Status: 0x%02x\n" + "- Subevent Done Status: 0x%02x\n" + "- Procedure Abort Reason: 0x%02x\n" + "- Subevent Abort Reason: 0x%02x\n" + "- Number of Antenna Paths: %d\n" + "- Number of Steps Reported: %d", + result->header.procedure_counter, + result->header.frequency_compensation, + result->header.reference_power_level, + result->header.procedure_done_status, + result->header.subevent_done_status, + result->header.procedure_abort_reason, + result->header.subevent_abort_reason, + result->header.num_antenna_paths, + result->header.num_steps_reported); + + if (result->step_data_buf) { + bt_le_cs_step_data_parse(result->step_data_buf, process_step_data, NULL); + } +} + +static void cs_test_end_complete_cb(void) +{ + shell_print(ctx_shell, "CS Test End Complete."); +} + static int cmd_cs_test_simple(const struct shell *sh, size_t argc, char *argv[]) { int err = 0; - struct bt_cs_test_param params; + struct bt_le_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 = BT_CONN_LE_CS_MAIN_MODE_1; + params.sub_mode = BT_CONN_LE_CS_SUB_MODE_UNUSED; params.main_mode_repetition = 0; - params.mode_0_steps = 0x1; + params.mode_0_steps = 2; params.role = shell_strtoul(argv[1], 16, &err); @@ -152,42 +200,242 @@ static int cmd_cs_test_simple(const struct shell *sh, size_t argc, char *argv[]) return SHELL_CMD_HELP_PRINTED; } - if (params.role != BT_CS_TEST_ROLE_INITIATOR && params.role != BT_CS_TEST_ROLE_REFLECTOR) { + if (params.role != BT_CONN_LE_CS_ROLE_INITIATOR && + params.role != BT_CONN_LE_CS_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.rtt_type = BT_CONN_LE_CS_RTT_TYPE_AA_ONLY; + params.cs_sync_phy = BT_CONN_LE_CS_SYNC_1M_PHY; + params.cs_sync_antenna_selection = BT_LE_CS_TEST_CS_SYNC_ANTENNA_SELECTION_ONE; + params.subevent_len = 3000; + params.subevent_interval = 1; + params.max_num_subevents = 1; 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.tone_antenna_config_selection = BT_LE_CS_TEST_TONE_ANTENNA_CONFIGURATION_INDEX_ONE; + params.initiator_snr_control = BT_LE_CS_TEST_INITIATOR_SNR_CONTROL_NOT_USED; + params.reflector_snr_control = BT_LE_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)); + 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.channel_map[7] = 0xFF; + params.override_config_0.not_set.channel_map[8] = 0xFF; + params.override_config_0.not_set.channel_selection_type = BT_CONN_LE_CS_CHSEL_TYPE_3B; + params.override_config_0.not_set.ch3c_shape = BT_CONN_LE_CS_CH3C_SHAPE_HAT; params.override_config_0.not_set.ch3c_jump = 0x2; - err = bt_cs_start_test(¶ms); + struct bt_le_cs_test_cb cs_test_cb = { + .le_cs_test_subevent_data_available = cs_test_subevent_data_cb, + .le_cs_test_end_complete = cs_test_end_complete_cb, + }; + + err = bt_le_cs_test_cb_register(cs_test_cb); if (err) { - shell_error(sh, "bt_cs_start_test returned error %d", err); + shell_error(sh, "bt_le_cs_test_cb_register returned error %d", err); + return -ENOEXEC; + } + + err = bt_le_cs_start_test(¶ms); + if (err) { + shell_error(sh, "bt_le_cs_start_test returned error %d", err); + return -ENOEXEC; + } + + return 0; +} + +static int cmd_remove_config(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + + if (default_conn == NULL) { + shell_error(sh, "Conn handle error, at least one connection is required."); + return -ENOEXEC; + } + + uint8_t config_id = strtoul(argv[1], NULL, 10); + + err = bt_le_cs_remove_config(default_conn, config_id); + if (err) { + shell_error(sh, "bt_le_cs_remove_config returned error %d", err); + return -ENOEXEC; + } + + return 0; +} + +static int cmd_create_config(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + enum bt_le_cs_create_config_context context; + struct bt_le_cs_create_config_params params; + + if (default_conn == NULL) { + shell_error(sh, "Conn handle error, at least one connection is required."); + return -ENOEXEC; + } + + params.id = strtoul(argv[1], NULL, 10); + if (!strcmp(argv[2], "local-only")) { + context = BT_LE_CS_CREATE_CONFIG_CONTEXT_LOCAL_ONLY; + } else if (!strcmp(argv[2], "local-only")) { + context = BT_LE_CS_CREATE_CONFIG_CONTEXT_LOCAL_AND_REMOTE; + } else { + shell_error(sh, "Invalid context: %s", argv[2]); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + if (!strcmp(argv[3], "initiator")) { + params.role = BT_CONN_LE_CS_ROLE_INITIATOR; + } else if (!strcmp(argv[3], "reflector")) { + params.role = BT_CONN_LE_CS_ROLE_REFLECTOR; + } else { + shell_error(sh, "Invalid role: %s", argv[3]); + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + /* Set the default values */ + params.main_mode_type = BT_CONN_LE_CS_MAIN_MODE_2; + params.sub_mode_type = BT_CONN_LE_CS_SUB_MODE_1; + params.min_main_mode_steps = 0x05; + params.max_main_mode_steps = 0x0A; + params.main_mode_repetition = 0; + params.mode_0_steps = 1; + params.rtt_type = BT_CONN_LE_CS_RTT_TYPE_AA_ONLY; + params.cs_sync_phy = BT_CONN_LE_CS_SYNC_2M_PHY; + params.channel_map_repetition = 1; + params.channel_selection_type = BT_CONN_LE_CS_CHSEL_TYPE_3B; + params.ch3c_shape = BT_CONN_LE_CS_CH3C_SHAPE_HAT; + params.ch3c_jump = 2; + + bt_le_cs_set_valid_chmap_bits(params.channel_map); + + for (int j = 4; j < argc; j++) { + if (!strcmp(argv[j], "rtt-none")) { + params.main_mode_type = BT_CONN_LE_CS_MAIN_MODE_1; + params.sub_mode_type = BT_CONN_LE_CS_SUB_MODE_UNUSED; + } else if (!strcmp(argv[j], "pbr-none")) { + params.main_mode_type = BT_CONN_LE_CS_MAIN_MODE_2; + params.sub_mode_type = BT_CONN_LE_CS_SUB_MODE_UNUSED; + } else if (!strcmp(argv[j], "both-none")) { + params.main_mode_type = BT_CONN_LE_CS_MAIN_MODE_3; + params.sub_mode_type = BT_CONN_LE_CS_SUB_MODE_UNUSED; + } else if (!strcmp(argv[j], "pbr-rtt")) { + params.main_mode_type = BT_CONN_LE_CS_MAIN_MODE_2; + params.sub_mode_type = BT_CONN_LE_CS_SUB_MODE_1; + } else if (!strcmp(argv[j], "pbr-both")) { + params.main_mode_type = BT_CONN_LE_CS_MAIN_MODE_2; + params.sub_mode_type = BT_CONN_LE_CS_SUB_MODE_3; + } else if (!strcmp(argv[j], "both-pbr")) { + params.main_mode_type = BT_CONN_LE_CS_MAIN_MODE_3; + params.sub_mode_type = BT_CONN_LE_CS_SUB_MODE_2; + } else if (!strcmp(argv[j], "steps")) { + if (++j == argc) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + params.min_main_mode_steps = strtoul(argv[j], NULL, 10); + if (++j == argc) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + params.max_main_mode_steps = strtoul(argv[j], NULL, 10); + if (++j == argc) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + params.mode_0_steps = strtoul(argv[j], NULL, 10); + } else if (!strcmp(argv[j], "aa-only")) { + params.rtt_type = BT_CONN_LE_CS_RTT_TYPE_AA_ONLY; + } else if (!strcmp(argv[j], "32b-sound")) { + params.rtt_type = BT_CONN_LE_CS_RTT_TYPE_32_BIT_SOUNDING; + } else if (!strcmp(argv[j], "96b-sound")) { + params.rtt_type = BT_CONN_LE_CS_RTT_TYPE_96_BIT_SOUNDING; + } else if (!strcmp(argv[j], "32b-rand")) { + params.rtt_type = BT_CONN_LE_CS_RTT_TYPE_32_BIT_RANDOM; + } else if (!strcmp(argv[j], "64b-rand")) { + params.rtt_type = BT_CONN_LE_CS_RTT_TYPE_64_BIT_RANDOM; + } else if (!strcmp(argv[j], "96b-rand")) { + params.rtt_type = BT_CONN_LE_CS_RTT_TYPE_96_BIT_RANDOM; + } else if (!strcmp(argv[j], "128b-rand")) { + params.rtt_type = BT_CONN_LE_CS_RTT_TYPE_128_BIT_RANDOM; + } else if (!strcmp(argv[j], "phy-1m")) { + params.cs_sync_phy = BT_CONN_LE_CS_SYNC_1M_PHY; + } else if (!strcmp(argv[j], "phy-2m")) { + params.cs_sync_phy = BT_CONN_LE_CS_SYNC_2M_PHY; + } else if (!strcmp(argv[j], "phy-2m-2b")) { + params.cs_sync_phy = BT_CONN_LE_CS_SYNC_2M_2BT_PHY; + } else if (!strcmp(argv[j], "chmap-rep")) { + if (++j == argc) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + params.channel_map_repetition = strtoul(argv[j], NULL, 10); + } else if (!strcmp(argv[j], "hat-shape")) { + params.ch3c_shape = BT_CONN_LE_CS_CH3C_SHAPE_HAT; + } else if (!strcmp(argv[j], "x-shape")) { + params.ch3c_shape = BT_CONN_LE_CS_CH3C_SHAPE_X; + } else if (!strcmp(argv[j], "chsel-3b")) { + params.channel_selection_type = BT_CONN_LE_CS_CHSEL_TYPE_3B; + } else if (!strcmp(argv[j], "chsel-3c")) { + params.channel_selection_type = BT_CONN_LE_CS_CHSEL_TYPE_3C; + } else if (!strcmp(argv[j], "ch3c-jump")) { + if (++j == argc) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + params.ch3c_jump = strtoul(argv[j], NULL, 10); + } else if (!strcmp(argv[j], "chmap")) { + if (++j == argc) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + if (hex2bin(argv[j], strlen(argv[j]), params.channel_map, 10) == 0) { + shell_error(sh, "Invalid channel map"); + return -ENOEXEC; + } + + sys_mem_swap(params.channel_map, 10); + } else { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + } + + err = bt_le_cs_create_config(default_conn, ¶ms, context); + if (err) { + shell_error(sh, "bt_le_cs_create_config returned error %d", err); + return -ENOEXEC; + } + + return 0; +} + +static int cmd_cs_stop_test(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + + err = bt_le_cs_stop_test(); + if (err) { + shell_error(sh, "bt_cs_stop_test returned error %d", err); return -ENOEXEC; } @@ -196,24 +444,26 @@ static int cmd_cs_test_simple(const struct shell *sh, size_t argc, char *argv[]) SHELL_STATIC_SUBCMD_SET_CREATE( cs_cmds, - SHELL_CMD_ARG( - read_remote_supported_capabilities, NULL, - "", - cmd_read_remote_supported_capabilities, 1, 0), + SHELL_CMD_ARG(read_remote_supported_capabilities, NULL, "", + cmd_read_remote_supported_capabilities, 1, 0), SHELL_CMD_ARG( set_default_settings, NULL, " " " ", cmd_set_default_settings, 5, 0), + SHELL_CMD_ARG(read_remote_fae_table, NULL, "", cmd_read_remote_fae_table, 1, 0), + SHELL_CMD_ARG(start_simple_cs_test, NULL, "", + cmd_cs_test_simple, 2, 0), + SHELL_CMD_ARG(stop_cs_test, NULL, "", cmd_cs_stop_test, 1, 0), SHELL_CMD_ARG( - read_remote_fae_table, NULL, - "", - cmd_read_remote_fae_table, 1, 0), - SHELL_CMD_ARG( - start_simple_cs_test, NULL, - "", - cmd_cs_test_simple, 2, 0), - SHELL_SUBCMD_SET_END); + create_config, NULL, + " " + "[rtt-none, pbr-none, both-none, pbr-rtt, pbr-both, both-pbr] [steps " + " ] [aa-only, 32b-sound, 96b-sound, 32b-rand, 64b-rand, 96b-rand, " + "128b-rand] [phy-1m, phy-2m, phy-2m-2b] [chmap-rep ] [hat-shape, x-shape] " + "[ch3c-jump ] [chmap ] (78-0) [chsel-3b, chsel-3c]", + cmd_create_config, 4, 15), + SHELL_CMD_ARG(remove_config, NULL, "", cmd_remove_config, 2, 0), SHELL_SUBCMD_SET_END); static int cmd_cs(const struct shell *sh, size_t argc, char **argv) { diff --git a/tests/bluetooth/shell/testcase.yaml b/tests/bluetooth/shell/testcase.yaml index a19dfa3f456..cec0a9d0046 100644 --- a/tests/bluetooth/shell/testcase.yaml +++ b/tests/bluetooth/shell/testcase.yaml @@ -46,6 +46,7 @@ tests: bluetooth.shell.channel_sounding: extra_configs: - CONFIG_BT_CHANNEL_SOUNDING=y + - CONFIG_BT_CHANNEL_SOUNDING_TEST=y - CONFIG_BT_CTLR=n platform_allow: - native_sim