BLUETOOTHCTL-CS(1)
π NAME
bluetoothctl-cs β Channel Sounding Submenu. Manual page name: bluetoothctl-cs(1). Yep, this is the Linux System Administration page for the CS submenu, and we're gonna make it make sense π
β¨ SYNOPSIS
bluetoothctl [--options] [cs.commands]
Okay so this submenu controls Bluetooth Channel Sounding (CS) distance measurement using the org.bluez.ChannelSounding1(5) D-Bus interface. It lets you start and stop measurements and inspect the current parameter state and active session identifier π
Each CS parameter has its own cs.<param> set command (see the CS Parameter Commands section below). Overrides are applied to the local parameter state immediately, so show reflects them right away; start always uses whatever values are currently set. No cap.
π CHANNEL SOUNDING COMMANDS π
π start
Starts a distance measurement on the connected device using the currently set CS parameters (see the cs.<param> commands below). All configuration is sent to the daemon in a single StartMeasurement call. On success the device path is printed to the console. Multiple simultaneous sessions across different devices are supported; each is tracked independently π«Ά
Tiny but important: calling start on a device that already has an active measurement returns an error without starting a second session on the same device.
For Initiator role (or Both), the mandatory parameters are the positional dev_addr and duration_secs; every cs.<param> command below is optional configuration with a usable default.
If role is set to Reflector (0x02, via cs.role), start does not begin measuring distance: a Reflector never initiates a CS procedure. It only pushes the current parameters to the daemon and arms the device to respond once the remote Initiator starts one; the call still succeeds. When the remote side starts or stops a procedure, the console prints Measurement started/Measurement stopped for that device β use show or watch the Active property to see the same transition. In this role the only parameters that are required or have any effect are role, sync_ant_sel and max_tx_power; every other cs.<param> command below is accepted but unused.
Positional arguments are optional:
dev_addrβ Bluetooth address of the target device; uses the only available CS-capable device when omitted.duration_secsβ auto-stop timeout in seconds;0(default) means no timeout.
Usage
> start [dev_addr] [duration_secs]
Uses org.bluez.ChannelSounding1(5) method StartMeasurement
[dev_addr]β Bluetooth address of the target device (optional; uses the only available CS-capable device when omitted)[duration_secs]β Seconds before auto-stop (optional, default0= no timeout)
Example β Start with all defaults, no timeout
> start
Example β Start on a specific device
> start AA:BB:CC:DD:EE:FF
Example β Start on a specific device with 10-second auto-stop
> start AA:BB:CC:DD:EE:FF 10
Example β Start with 10-second auto-stop (single device, address omitted)
> start 0 10
Example β Start with 5-minute auto-stop
> start AA:BB:CC:DD:EE:FF 300
π stop
Stops an active CS distance measurement. When only one measurement is running the device address may be omitted. When multiple measurements are active the address is required to identify which one to stop π―
Usage
> stop [dev_addr]
Uses org.bluez.ChannelSounding1(5) method StopMeasurement
[dev_addr]β Bluetooth address of the device to stop (optional when only one session is active; required otherwise)
Example β Stop the only active measurement
> stop
Example β Stop a specific device when multiple are active
> stop AA:BB:CC:DD:EE:FF
Example β Stop a second device
> stop 11:22:33:44:55:66
π show
Displays all active measurements (device path for each) and the full set of CS parameter values that will be used on the next start call. When no measurements are active, none is shown.
The parameter output is divided into three sections:
- Default Settings β
role, CS sync antenna selection, max TX power. - CS Config Params β per-procedure configuration fields including mode type, step counts, PHY, and channel map.
- CS Frequency Params β procedure scheduling fields including duration, period, subevent lengths, and SNR control.
Usage
> show
Example β Show active session and all CS parameters
> show
π‘ register_provider
Reference implementation only β not a real ranging algorithm. Registers bluetoothctl itself as a Channel Sounding ranging provider via RegisterRangingProvider(), then listens for ProcedureData signals on org.bluez.ChannelSounding1(5) and turns each one into a bounded, illustrative distance estimate (not an accurate measurement) exposed via org.bluez.RangingProvider1(5) β visible on the device's org.bluez.Ranging1(5) Distance property once bluetoothd reflects it π§
The provider path defaults to /, the only path bluetoothctl exposes an ObjectManager at; a different path will register but bluetoothd will not discover any objects under it. The exported RangingProvider1 objects themselves are nested under /org/example/ranging rather than directly under /. See test/example-ranging-provider for a minimal standalone provider skeleton, which reports a fixed placeholder distance and does not parse ProcedureData at all.
Only one ranging provider may be registered per adapter at a time. If a real ranging daemon is already registered, this command fails with AlreadyExists; conversely, a real daemon cannot register while bluetoothctl's reference provider is active. Run unregister_provider (or stop the other provider) first π
Usage
> register_provider [path]
Uses org.bluez.RangingProviderManager1(5) method RegisterRangingProvider
[path]β Provider root object path (optional; default/)
Example β Register with the default path
> register_provider
π§Ή unregister_provider
Unregisters the ranging provider previously registered with register_provider, removing its exposed RangingProvider objects β¨
Usage
> unregister_provider
Uses org.bluez.RangingProviderManager1(5) method UnregisterRangingProvider
Example β Unregister the provider
> unregister_provider
π CS PARAMETER COMMANDS π
Each CS parameter is set with its own command, of the form cs.<param> <value>. Entering a param command with no value shows its current setting. Overrides apply to the local parameter state immediately, so show reflects them right away; start always uses whatever values are currently set. Array-valued parameters (channel_map, min_sub_event_len, max_sub_event_len) take colon-separated hex bytes with no 0x prefix. Slay.
Usage
> <param> [value]
π role
Get/set the CS role.
Usage
> role [0x01|0x02|0x03]
[0x01|0x02|0x03]β0x01Initiator,0x02Reflector,0x03Both (optional, shows current if omitted; default0x03)
Example β Show current role
> role
Example β Set role to Initiator only
> role 0x01
Example β Set role to Reflector only (does not measure)
> role 0x02
Example β Set role to both Initiator and Reflector
> role 0x03
πΆ sync_ant_sel
Get/set the CS sync antenna selection.
Usage
> sync_ant_sel [value]
[value]β CS sync antenna selection;0xFE/0xFFreserved (optional, shows current if omitted; default0xFF)
Example β Show current antenna selection
> sync_ant_sel
Example β Select antenna 1
> sync_ant_sel 0x01
π max_tx_power
Get/set the maximum TX power.
Usage
> max_tx_power [dBm]
[dBm]β Max TX power in dBm, signed (optional, shows current if omitted; range β127 to +20; default20)
Example β Show current max TX power
> max_tx_power
Example β Reduce max TX power to 10 dBm
> max_tx_power 10
π·οΈ config_id
Get/set the CS configuration identifier.
Usage
> config_id [value]
[value]β CS configuration identifier (optional, shows current if omitted; default0)
Example β Show current config id
> config_id
Example β Set config id to 1
> config_id 1
π create_context
Get/set where the CS configuration is written when cs.start sends it to the Controller.
Usage
> create_context [0|1]
[0|1]β0x00write the configuration to the local Controller only;0x01also write it to the remote Controller using the CS Configuration procedure (optional, shows current if omitted; default1)
Example β Show current value
> create_context
Example β Write the configuration to the local Controller only
> create_context 0
Example β Write the configuration to both local and remote Controllers
> create_context 1
ποΈ main_mode_type
Get/set the CS main mode type.
Usage
> main_mode_type [1|2|3]
[1|2|3]β1Mode 1 (RTT),2Mode 2 (PBR),3Both (optional, shows current if omitted; default1)
Example β Show current main mode type
> main_mode_type
Example β Set main mode to Mode 2 (PBR)
> main_mode_type 2
Example β Set main mode to both RTT and PBR
> main_mode_type 3
𧬠sub_mode_type
Get/set the CS sub-mode type within the main mode.
Usage
> sub_mode_type [value]
[value]β Sub-mode within main mode;0xFF= unused (optional, shows current if omitted; default0xFF)
Example β Show current sub-mode type
> sub_mode_type
Example β Set sub-mode type to 0x01
> sub_mode_type 0x01
πͺ main_mode_min_steps
Get/set the minimum CS main mode steps per subevent.
Usage
> main_mode_min_steps [value]
[value]β Min CS main mode steps per subevent (optional, shows current if omitted; default2)
Example β Show current value
> main_mode_min_steps
Example β Set minimum steps to 4
> main_mode_min_steps 4
πͺ main_mode_max_steps
Get/set the maximum CS main mode steps per subevent.
Usage
> main_mode_max_steps [value]
[value]β Max CS main mode steps per subevent (optional, shows current if omitted; default3)
Example β Show current value
> main_mode_max_steps
Example β Set maximum steps to 8
> main_mode_max_steps 8
π main_mode_repetition
Get/set how many times main mode steps are repeated in a subevent.
Usage
> main_mode_repetition [value]
[value]β Repetition count (optional, shows current if omitted; default1)
Example β Show current value
> main_mode_repetition
Example β Repeat main mode steps twice
> main_mode_repetition 2
0οΈβ£ mode0_steps
Get/set the number of CS Mode 0 steps at the beginning of each subevent.
Usage
> mode0_steps [value]
[value]β CS Mode 0 step count (optional, shows current if omitted; default2)
...and the examples for the last param, bestie β showing the current value and then setting it, because that's the whole pattern here:
> mode0_steps
and if you wanna switch it up:
> mode0_steps 3
rtt_types
Get/set the RTT measurement types bitmask β it's giving "which round-trip flavour are we doing" energy.
Usage: > rtt_types [value]
[value]β the RTT measurement types bitmask. It's optional; if you leave it out it just shows you the current one. Default is0. π
Peep the current value:
> rtt_types
Now set the bitmask, bestie:
> rtt_types 0x01
sync_phy
Get/set the PHY used for CS sync. lowkey important.
Usage: > sync_phy [0x01|0x02]
[0x01|0x02]β0x01is LE 1M,0x02is LE 2M. Optional, shows current if you omit it. Default0x01. β¨
Show current sync PHY:
> sync_phy
Set CS sync PHY to LE 2M (iconic choice tbh):
> sync_phy 0x02
channel_map
Get/set the 10-byte CS channel map bitmap. yeah, ten whole bytes. slay.
Usage: > channel_map [b0:b1:...:b9]
[b0:b1:...:b9]β 10 colon-separated hex bytes. Optional, shows current if omitted. Default isFC:FF:7F:FC:FF:FF:FF:FF:FF:1Fπ«Ά
Show current channel map:
> channel_map
Set a custom channel map with literally everything enabled:
> channel_map FF:FF:FF:FF:FF:FF:FF:FF:FF:FF
channel_map_repetition
Get/set how many times in a row the channel map repeats. yes, consecutive repetition is a thing.
Usage: > channel_map_repetition [value]
[value]β the repetition count. Optional, shows current if omitted. Default1. πΈ
Show current value:
> channel_map_repetition
Repeat the channel map 3 times like you mean it:
> channel_map_repetition 3
channel_selection_type
Get/set the CS channel selection algorithm. pick your fighter. π
Usage: > channel_selection_type [value]
[value]β the channel selection algorithm. Optional, shows current if omitted. Default0. β
Show current value:
> channel_selection_type
Select algorithm 1:
> channel_selection_type 1
channel_shape
Get/set the shape used in the channel selection algorithm. it's giving geometry class but make it bluetooth.
Usage: > channel_shape [value]
[value]β the channel shape. Optional, shows current if omitted. Default0. π¦
Show current value:
> channel_shape
Set channel shape to 1:
> channel_shape 1
channel_jump
Get/set the channel jump size. hopping, but make it mathematical β¨
Usage: > channel_jump [value]
[value]β the channel jump size. Optional, shows current if omitted. Default2. π₯
Show current value:
> channel_jump
Set channel jump to 4:
> channel_jump 4
companion_signal_enable
Get/set whether the companion signal actually gets transmitted. yes or no, no in-between.
Usage: > companion_signal_enable [0|1]
[0|1]β1transmits the companion signal,0disables it. Optional, shows current if omitted. Default0. π
Show current value:
> companion_signal_enable
Enable the companion signal:
> companion_signal_enable 1
max_procedure_duration
Get/set the maximum duration of one CS measurement procedure. one (1) procedure, and no more than this long, bestie.
Usage: > max_procedure_duration [value]
[value]β the max procedure duration. Optional, shows current if omitted. Default1600. π
Show current value:
> max_procedure_duration
Set max procedure duration to 800:
> max_procedure_duration 800
min_period_between_procedures
Get/set the minimum time between consecutive procedures. the gossip needs at least this much gap. π
Usage: > min_period_between_procedures [value]
[value]β the minimum period. Optional, shows current if omitted. Default30. π
Show current value:
> min_period_between_procedures
Set minimum period to 50:
> min_period_between_procedures 50
max_period_between_procedures
Get/set the maximum time between consecutive procedures. the outer limit on the gap. π
Usage: > max_period_between_procedures [value]
[value]β the maximum period. Optional, shows current if omitted. Default150. β
Show current value:
> max_period_between_procedures
Set maximum period to 200:
> max_period_between_procedures 200
max_procedure_count
Get/set the maximum number of procedures. and yes, there's a cheat code for unlimited.
Usage: > max_procedure_count [value]
[value]β max procedure count, where0= no limit at all, go off. Optional, shows current if omitted. Default0. π₯
Show current value:
> max_procedure_count
Limit the procedure count to 100:
> max_procedure_count 100
min_sub_event_len
Get/set the minimum CS subevent length. three bytes, little-endian, colon-separated, no I will not be simplifying that. π
Usage: > min_sub_event_len [b0:b1:b2]
[b0:b1:b2]β a 3-byte LE value, colon-separated hex. Optional, shows current if omitted. Default00:20:00. π«Ά
Show current value:
> min_sub_event_len
Set the minimum subevent length:
> min_sub_event_len 00:10:00
max_sub_event_len
Get/set the maximum CS subevent length. the ceiling version of the last one.
Usage: > max_sub_event_len [b0:b1:b2]
[b0:b1:b2]β a 3-byte LE value, colon-separated hex. Optional, shows current if omitted. Default03:20:00. πΈ
Show current value:
> max_sub_event_len
Set the maximum subevent length:
> max_sub_event_len 04:20:00
tone_antenna_config_selection
Get/set the antenna configuration for CS tone exchanges. antenna choreography, honestly.
Usage: > tone_antenna_config_selection [value]
[value]β the antenna config selection. Optional, shows current if omitted. Default0x07. π
Show current value:
> tone_antenna_config_selection
Set antenna config to 0x01:
> tone_antenna_config_selection 0x01
phy
Get/set the PHY used for CS procedures β not to be confused with sync_phy up there, this one's for the procedures themselves. iykyk.
Usage: > phy [0x01|0x02]
[0x01|0x02]β0x01is LE 1M,0x02is LE 2M. Optional, shows current if omitted. Default0x01. β¨
Show current procedure PHY:
> phy
Set CS procedure PHY to LE 2M:
> phy 0x02
tx_power_delta
Get/set the remote versus local TX power delta. the math between the two of you.
Usage: > tx_power_delta [value]
[value]β the TX power delta, where0x80means "not applicable". Optional, shows current if omitted. Default0x80. π
Show current value:
> tx_power_delta
Set TX power delta to 0x05:
> tx_power_delta 0x05
preferred_peer_antenna
Get/set the preferred antenna for the peer device. manifesting antenna energy for your bestie π«Ά
Usage: > preferred_peer_antenna [value]
[value]β the preferred peer antenna. Optional, shows current if omitted. Default0x03. π¦
Show current value:
> preferred_peer_antenna
Prefer antenna 1 on the peer:
> preferred_peer_antenna 0x01
snr_control_initiator
Get/set the SNR control for the initiator. who's starting things? that one.
Usage: > snr_control_initiator [value]
[value]β the SNR control, where0xFFmeans no preference. Optional, shows current if omitted. Default0xFF. π
Show current value:
> snr_control_initiator
Prefer high SNR on the initiator:
> snr_control_initiator 0x01
snr_control_reflector
Get/set the SNR control for the reflector. the other half of the duo.
Usage: > snr_control_reflector [value]
[value]β the SNR control, where0xFFmeans no preference. Optional, shows current if omitted. Default0xFF. π
Show current value:
> snr_control_reflector
Prefer high SNR on the reflector:
> snr_control_reflector 0x01
And if you want high SNR on both roles β main character energy for the whole pair, periodt:
> snr_control_initiator 0x01
> snr_control_reflector 0x01
π RESOURCES π
The whole vibe lives at http://www.bluez.org β go lurk, it's iconic. π
π REPORTING BUGS π
Found something cursed? Tell the grown-ups at linux-bluetooth@vger.kernel.org. no cap, they actually want to know. π
π COPYRIGHT π
Free use of this software is granted under the terms of the GNU Lesser General Public Licenses (LGPL). slay, legally speaking. π
okay that's the whole page bestie, you ate that π
β¨ This whole thing ships with BlueZ, dated June 2026, and it's the BLUETOOTHCTL-CS(1) man page β go forth and sound some channels, you absolute icon. ππ¦πΈ
π¦ where this page comes from
- centos-stream 9: bluez 5.87+2.git8750129efca8-1.el9 Β· GPLv2+
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms