Module rdio

Module rdio 

Source
Expand description

SDRTrunk-compatible Rdio API multipart upload client.

This module implements the wire-level protocol used by the open-source SDRTrunk radio-recording tool to push completed call audio into a Rdio Scanner ingest server. The user’s sdrtrunk-rdio-api Python service speaks the same protocol; stargazer impersonates SDRTrunk so that existing tooling does not need to grow a stargazer-specific code path.

§Endpoint

The caller configures a single base URL (default http://rdio-api:8080/api/call-upload). Every completed voice stream is POSTed to this URL as multipart/form-data.

§Required request headers

HeaderValueWhy
User-AgentsdrtrunkSome Rdio deployments gate ingest on the UA string — sdrtrunk-rdio-api accepts the literal "sdrtrunk" token.

The Content-Type: multipart/form-data; boundary=... header is set automatically by [reqwest::multipart::Form]; we do not build it by hand.

§Form fields

The server accepts the same field set that SDRTrunk emits when forwarding a trunked call. Text fields are UTF-8 strings; the audio part is a binary MP3 blob with an explicit filename and audio/mpeg content-type.

FieldTypeExamplePurpose
keytextstargazer-keyAPI key configured via rdio.api_key.
systemtext10030Numeric system id — see crate::upload::compute_system_id.
systemLabeltextREF030 (DPlus)Human-readable system name.
talkgrouptext3Numeric talkgroup id (A1, B2, …).
talkgroupLabeltextModule CHuman-readable talkgroup name.
talkgroupGrouptextD-STARFixed group label.
sourcetextW1AWOperator callsign. The user confirmed their Rdio fork accepts alphanumeric callsigns in this field (upstream expects a numeric radio id).
talkerAliastextW1AW / D75Callsign + optional suffix.
frequencytext0Always zero — reflectors have no RF carrier.
dateTimetext1760289000Unix seconds at start of transmission.
audiofileaudio/mpeg MP3 bytesThe recorded call. Filename follows crate::upload::make_audio_name.
patchestext[]Literal empty-array JSON — no patches.
talkgroupTagtextD-STAR text message, or ""Free-form 20-char slow-data message, passed through verbatim.

§Success signalling

Rdio Scanner returns HTTP 200 with the literal string "Call imported successfully." embedded in the response body when ingest succeeds. This client reads the full body and checks for that substring via str::contains. Any other outcome — non-2xx status, missing marker, network error — becomes an UploadError variant so the caller can decide whether to retry.

Structs§

UploadFields 🔒
Parameters for a single Rdio Scanner upload.

Enums§

UploadError 🔒
Errors returned by upload_stream.

Constants§

AUDIO_MIME 🔒
MIME type for the uploaded MP3 blob.
SUCCESS_MARKER 🔒
Marker substring that the Rdio Scanner API includes in a successful response body. Verified against the upstream source at https://github.com/chuot/rdio-scanner.
USER_AGENT 🔒
User-Agent header value. Must be the literal "sdrtrunk" so that sdrtrunk-rdio-api routes the request through its ingest pipeline.

Functions§

truncate_body 🔒
Returns body truncated to at most max_chars UTF-8 characters, with an explicit "... (truncated)" suffix appended if truncation occurred.
upload_stream 🔒
Uploads one completed voice stream to an SDRTrunk-compatible Rdio Scanner endpoint.