QSP Agent is a Rust daemon that connects a local radio transceiver to remote QSP clients through a signaling server and WebRTC.
It is intended to run close to the hardware:
- it talks to the transceiver through Hamlib
- it captures local audio input
- it exposes the radio to remote clients through the QSP signaling flow
QSP Agent combines three responsibilities:
- It connects to the QSP signaling server and authenticates itself as an agent.
- It controls the local transceiver through Hamlib CAT commands.
- It creates WebRTC sessions for remote clients and streams audio/control data.
qsp-agent/: main daemon cratelib-hamlib/: Rust binding crate around Hamlibpackage/: Debian and systemd packaging assets
- A supported radio reachable through Hamlib
- A working audio input device
- Access to the QSP signaling server
For local builds on Debian or Ubuntu, install:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libasound2-dev \
libhamlib-dev \
libopus-dev \
pkg-configBuild the full workspace:
cargo build --workspace --lockedRun tests:
cargo test --workspace --lockedCheck formatting:
cargo fmt --all --checkRun Clippy:
cargo clippy --workspace --all-targetsThe agent reads a TOML configuration file. By default it looks for config.toml
in the current working directory. A different file can be passed with
--config.
A packaged example configuration is provided in package/config.toml.
name = "My Station"
description = "Remote HF station"
[signaling_server]
url = "ws://signaling.example.net/server/session"
agentId = "YOUR_AGENT_ID"
agentSecret = "YOUR_AGENT_SECRET"
[transceiver]
model = 1
[transceiver.port]
rig_pathname = "/dev/ttyUSB0"
serial_speed = "115200"name: displayed agent namedescription: displayed agent descriptionagentLogLevel: optional default log level. Allowed values:Error,Warn,Info,Debug,TracepidFile: optional PID file path. Default:qsp-agent.pidlockFile: optional lock file path. Default:qsp-agent.lock
url: WebSocket URL of the signaling serveragentId: registered agent identifieragentSecret: secret used to authenticate the agentconnectionRetryDelaySeconds: optional retry delay sequence in seconds
If connectionRetryDelaySeconds is omitted, the default sequence is:
[1, 1, 3, 5, 15, 30, 60]The last value is reused indefinitely for later retries.
model: Hamlib rig model numberhamlibDebugLevel: optional Hamlib log level. Allowed values:None,Bug,Err,Warn,Verbose,Trace,CachestatePollingInterval: transceiver polling interval in milliseconds. Default:1000
This section is passed directly to Hamlib configuration tokens. Typical values depend on your rig and connection type, for example:
rig_pathnameserial_speed- network transport settings for TCP-connected radios
Use the appropriate Hamlib parameters for your hardware.
Run in the foreground:
cargo run -p qsp-agent -- --config ./config.tomlOr run the compiled binary directly:
./target/debug/qsp-agent --config ./config.toml-c, --config <CONFIG_PATH>: path to the TOML configuration file-d, --daemon: detach into the background on Unix platforms
- In foreground mode, logs are written to the console.
- In daemon mode, logs are written to the platform logging backend:
- Linux:
systemd-journald - macOS:
os_log - Windows: ETW
- Linux:
If RUST_LOG is set, it overrides the configured default log level.
Example:
RUST_LOG=debug ./target/debug/qsp-agent --config ./config.tomlOn Unix, the agent can detach itself with:
./target/debug/qsp-agent --config ./config.toml --daemonThis mode is useful for manual deployments. When using systemd, do not use
--daemon; the packaged service runs the agent in the foreground.
The repository includes Debian packaging assets under package/.
The generated package installs:
- binary:
/usr/bin/qsp-agent - configuration:
/etc/qsp-agent/config.toml - systemd unit:
/lib/systemd/system/qsp-agent.service - man page:
/usr/share/man/man1/qsp-agent.1.gz
The package also creates a dedicated system user and group named qsp-agent.
The packaged systemd service:
- runs as
qsp-agent:qsp-agent - uses
/var/lib/qsp-agentas working directory - uses
/run/qsp-agentfor runtime files - restarts on failure
- expects
/etc/qsp-agent/config.tomlto exist
The unit file is available in package/systemd/qsp-agent.service.
The repository includes a packaging script:
package/build-deb.shIt expects a release binary to already exist at target/release/qsp-agent.
Build manually:
cargo build --release --locked -p qsp-agent
package/build-deb.shGenerated packages are written to dist/.
After installing the Debian package:
sudo systemctl daemon-reload
sudo systemctl enable --now qsp-agent.serviceInspect logs:
journalctl -u qsp-agent.serviceIf your radio is exposed through /dev/tty* or /dev/serial/*, the
qsp-agent user may need access to a device group such as dialout.
GitHub Actions performs:
- workspace build and tests
- Debian package builds for:
amd64arm64armhf
On tags matching v*, the workflow publishes the generated .deb packages as
GitHub release assets.
- The signaling connection automatically retries with backoff.
- The agent keeps a lock file to avoid running multiple instances on the same configuration.
- Audio capture depends on a valid local input device and a supported audio format.
- Transceiver behavior depends heavily on Hamlib support and rig-specific configuration tokens.
This project is distributed under the GNU General Public License, version 3 or
later. See COPYING.