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
| Header | Value | Why |
|---|---|---|
User-Agent | sdrtrunk | Some 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.
| Field | Type | Example | Purpose |
|---|---|---|---|
key | text | stargazer-key | API key configured via rdio.api_key. |
system | text | 10030 | Numeric system id — see crate::upload::compute_system_id. |
systemLabel | text | REF030 (DPlus) | Human-readable system name. |
talkgroup | text | 3 | Numeric talkgroup id (A → 1, B → 2, …). |
talkgroupLabel | text | Module C | Human-readable talkgroup name. |
talkgroupGroup | text | D-STAR | Fixed group label. |
source | text | W1AW | Operator callsign. The user confirmed their Rdio fork accepts alphanumeric callsigns in this field (upstream expects a numeric radio id). |
talkerAlias | text | W1AW / D75 | Callsign + optional suffix. |
frequency | text | 0 | Always zero — reflectors have no RF carrier. |
dateTime | text | 1760289000 | Unix seconds at start of transmission. |
audio | file | audio/mpeg MP3 bytes | The recorded call. Filename follows crate::upload::make_audio_name. |
patches | text | [] | Literal empty-array JSON — no patches. |
talkgroupTag | text | D-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§
- Upload
Fields 🔒 - Parameters for a single Rdio Scanner upload.
Enums§
- Upload
Error 🔒 - 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-Agentheader value. Must be the literal"sdrtrunk"so thatsdrtrunk-rdio-apiroutes the request through its ingest pipeline.
Functions§
- truncate_
body 🔒 - Returns
bodytruncated to at mostmax_charsUTF-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.