Documentation
¶
Overview ¶
Package soapyremote implements an sdr.Driver that talks to a remote SoapySDRServer (from pothosware/SoapyRemote) in pure Go, with no CGO and no SoapySDR C libraries. SoapySDRServer exposes any SoapySDR-supported radio — USRP, LimeSDR, bladeRF, HackRF, Airspy, RTL-SDR, SDRplay and more — over the network with a real control plane, so GopherTrunk can demodulate trunked systems from high-dynamic-range hardware that rtl_tcp's hardcoded 8-bit stream cannot carry (issue #536).
Two channels are used, mirroring SoapyRemote itself:
- A TCP RPC control socket (default port 55132) carries device creation, tuning, gain and stream setup as length-framed, type-tagged packets (see rpc.go).
- A separate stream socket carries 24-byte-framed IQ datagrams (see stream.go), plus a second "status" socket the server requires alongside it. This driver implements the TCP stream transport, which is in-order and needs no UDP flow-control; the operator selects it with `stream_protocol: tcp` (the default). UDP streaming is a future addition (issue #536 phase 2).
The wire format was reverse-engineered from SoapyRemote@master and the RPC, datagram framing, and TCP stream setup choreography are byte-matched to the source (client/Streaming.cpp + server/ClientHandler.cpp). It is exercised by a fake server in the tests; validate against live hardware before release.
Limitations:
- Receive only. One RX channel (channel 0) by default; `diversity: mrc` opens channels 0 and 1 and combines them into one stream (see mrc.go). Every per-channel setting (frequency, rate, gain, frequency correction) is programmed on both — an unconfigured second receiver is a branch that contributes nothing (issue #1062).
- SetPPM / SetBiasTee are best-effort: SoapySDR has no universal call for either, so they map to setFrequencyCorrection / writeSetting and silently no-op when the underlying driver doesn't support them.
- Plaintext, like rtl_tcp. Use on trusted networks or through a tunnel.
Index ¶
Constants ¶
const DefaultConnectTimeout = 3 * time.Second
DefaultConnectTimeout caps RPC dials and per-call round-trips.
const DefaultServicePort = "55132"
DefaultServicePort is SoapyRemote's default RPC port (SOAPY_REMOTE_DEFAULT_SERVICE).
const DriverName = "soapyremote"
DriverName is the sdr.Driver name registered with the pool.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Driver ¶
type Driver struct {
// contains filtered or unexported fields
}
Driver implements sdr.Driver over a set of SoapySDRServer endpoints.
type Spec ¶
type Spec struct {
// Addr is the server host:port, e.g. "192.168.1.60:55132". A bare host
// gets DefaultServicePort appended. Required.
Addr string
// Serial is the virtual device serial the pool reports. Empty generates
// one from Addr so multi-endpoint configs stay unique.
Serial string
// Role hints the pool's role assignment: "control" | "voice" | "auto".
Role string
// DeviceArgs are the SoapySDR device-selection kwargs passed to MAKE,
// e.g. {"driver":"lime"} or {"serial":"..."}. Empty selects the server's
// first/only device.
DeviceArgs map[string]string
// Format is the requested wire sample format: "CS16" (default) or "CF32".
Format string
// StreamProtocol selects the stream transport: "tcp" (default/only).
StreamProtocol string
// StreamMTU sets the stream endpoint MTU in bytes, sent to the server as
// the "remote:mtu" setupStream arg and used to size the client's
// flow-control window. Zero (or <=0) uses SoapyRemote's default (1500).
StreamMTU int
// StreamWindow sets the stream flow-control window in bytes, sent to the
// server as the "remote:window" setupStream arg and used as the client's
// in-flight credit ceiling (advertised as window/StreamMTU sequences).
// Zero (or <=0) uses the client default (streamWindowBytes, 8 MiB).
StreamWindow int
// ConnectTimeout overrides DefaultConnectTimeout when non-zero.
ConnectTimeout time.Duration
// Diversity selects a spatial-diversity combiner over a multi-channel RX
// stream. "" / "none" (default) is the ordinary single-channel stream.
// "mrc" opens RX channels 0 and 1 and phase-coherently combines them into
// one stream (shared-LO front-ends only, e.g. USRP B210 / AD9361). See
// mrc.go. EXPERIMENTAL — issue #1062.
Diversity string
// Antennas selects the RX antenna port per channel (SoapySDR setAntenna),
// applied in channel order after MAKE: Antennas[0] to RX channel 0,
// Antennas[1] to channel 1 (the diversity second receiver). Empty leaves the
// device default. A comma-separated multi-antenna value cannot be expressed
// in the flat DeviceArgs kwargs string, so per-channel antenna routing (e.g.
// an X310's RX1/RX2 under MRC) goes here instead of args.
Antennas []string
// DiversityCapture is a path prefix under which the driver dumps the
// PRE-COMBINE per-branch IQ once per stream (see branchcapture.go). Empty
// disables it. Only meaningful with Diversity set.
DiversityCapture string
// DiversityCaptureSeconds bounds that dump; <=0 selects
// defaultDiversityCaptureSeconds.
DiversityCaptureSeconds int
// DiversityCaptureFormat selects the branch container: "" / "cs16"
// (headerless int16 pairs) or "flac" (lossless compressed twin; falls back
// to cs16 above flacCaptureMaxRateHz).
DiversityCaptureFormat string
// VerboseDebug logs every control-channel RPC request and response —
// decoded arguments plus a hex dump of the frame — at DEBUG. Off by
// default; the trace is per endpoint so a multi-radio config can follow
// one server. See rpcdebug.go.
VerboseDebug bool
}
Spec names one SoapySDRServer endpoint to expose as a virtual tuner.