Commit Graph
22 Commits
Author SHA1 Message Date
ClaudeandStan Grams 3e0169b91f [refactor](trx-backend-soapysdr): implement RigSdr trait for SoapySdrRig
Move 13 SDR-specific methods from impl RigCat into a new impl RigSdr
block. Add as_sdr()/as_sdr_ref() overrides returning Some(self) so the
SDR extension is accessible via the RigCat trait object.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 08:47:17 +01:00
ClaudeandStan Grams 748d26f47d [refactor](trx-server): route SDR commands through RigCat::as_sdr()
Update all SDR command handlers in rig_task to access SDR methods via
ctx.rig.as_sdr() instead of calling them directly on RigCat. Query-only
SDR operations (filter_state, get_spectrum, get_vchan_rds) use
as_sdr_ref(). Non-SDR rigs now get proper not_supported errors.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 08:47:17 +01:00
ClaudeandStan Grams 74749bc6de [refactor](trx-core): split RigCat into base trait + RigSdr extension
Extract 13 SDR-specific methods (set_center_freq, set_bandwidth,
set_sdr_gain/lna/agc/squelch/nb, set_wfm_*, filter_state, get_spectrum,
get_vchan_rds) into a new RigSdr trait. RigCat retains core CAT
operations and gains as_sdr()/as_sdr_ref() for optional SDR access.

Non-SDR backends no longer see SDR methods in their trait impl.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 08:47:17 +01:00
ClaudeandStan Grams aa3ed81786 [fix](trx-server): replace all history mutex .expect() with poison recovery
Replace 25 .expect("X history mutex poisoned") calls in DecoderHistories
with .unwrap_or_else(|e| e.into_inner()) to gracefully recover from
poisoned locks instead of crashing the server.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 08:47:17 +01:00
ClaudeandStan Grams 337cb72974 [refactor](trx-server): use state data constructors for pub(crate) fields
Migrate ready_data_from_state and transmitting_data_from_state to use
the new ReadyStateData::new() and TransmittingStateData::new()
constructors instead of direct struct field initialization.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:29:55 +01:00
ClaudeandStan Grams 8ce2e4ed08 [refactor](trx-core): restrict state data fields to pub(crate) with accessors
Make ReadyStateData and TransmittingStateData fields pub(crate) to
prevent external mutation that could bypass state machine invariants.
Add constructors and getter methods for external consumers.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:29:55 +01:00
ClaudeandStan Grams 71c23f0895 [refactor](trx-frontend-http): pre-allocate spectrum encoding output
Replace format! with pre-allocated String::with_capacity for spectrum
frame encoding, reducing allocation overhead in the hot SSE path.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:29:55 +01:00
ClaudeandStan Grams adf65ae56d [fix](trx-frontend-http): warn when auth enabled but cookie_secure is false
Log a startup warning when HTTP auth is active but cookie_secure remains
false, alerting operators that session cookies will be sent unencrypted.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:29:55 +01:00
ClaudeandStan Grams 9b6c845fa8 [fix](trx-frontend-http): recover from poisoned locks and document ordering
Replace all .unwrap() on RwLock/Mutex acquisitions with
.unwrap_or_else(|e| e.into_inner()) to gracefully recover from poisoned
locks instead of panicking. Add lock ordering documentation to the
module header to prevent deadlocks.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:29:55 +01:00
ClaudeandStan Grams c5320ca2fb [refactor](trx-server): add AtomicUsize counter and recover from poisoned locks
Add an AtomicUsize total_count field to DecoderHistories, maintained by
record/prune/clear methods, so estimated_total_count() avoids 9 separate
mutex acquisitions. Also replace audio ring buffer .unwrap() calls with
.unwrap_or_else(|e| e.into_inner()) to recover from poisoned locks.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:29:55 +01:00
ClaudeandStan Grams 74eb755858 [chore](trx-rs): update Cargo.lock
https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams 22ad90b2ba [fix](trx-server): release mutex before serialization in flush_all
Clone history data out under the lock, then drop the guard before
calling save_key, so serialization never blocks concurrent readers.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams d7c8eed44f [feat](trx-frontend-http): add per-IP login rate limiting
Implement LoginRateLimiter that tracks failed login attempts per IP,
enforcing a cooldown (10 attempts per 60s window) to mitigate brute-
force attacks on the /auth/login endpoint.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams c299e9a2d2 [fix](trx-server): truncate raw JSON in error logs to 128 chars
Prevent potential information disclosure by truncating raw client input
in log messages instead of logging the full payload.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams edf16b63d6 [fix](trx-core): log invalid state machine transitions
Add debug-level tracing for rejected state transitions instead of
silently returning false, aiding debugging of unexpected rig behavior.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams 9cf66fc04a [fix](trx-app): add plugin loading validation and disable toggle
Reject world-writable plugin files on Unix to prevent loading tampered
libraries. Add TRX_PLUGINS_DISABLED env var to disable plugin loading
entirely.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams cbe22bd7b6 [refactor](trx-frontend-http): replace string-level JSON splice with serde(flatten)
Use a StateWithMeta wrapper struct with #[serde(flatten)] for merging
rig state with frontend meta, replacing the manual string manipulation.
Also add Serialize derive and skip_serializing_if to FrontendMeta.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams 635a1214d0 [refactor](trx-client): switch VChanAudioCmd to bounded channels (cap 256)
Replace unbounded_channel with channel(256) for VChanAudioCmd to prevent
unlimited memory accumulation under backpressure. Use try_send in
synchronous contexts.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams c3abc5ff5b [refactor](trx-frontend): add DecodeHistory type alias and use bounded channels
Introduce DecodeHistory<T> alias for the repeated
Arc<Mutex<VecDeque<(Instant, Option<String>, T)>>> pattern (9 fields).
Also switch VChanAudioCmd channel senders from UnboundedSender to Sender
to prevent unbounded memory growth under backpressure.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams 449b877694 [refactor](trx-ftx): use HashSet for candidate deduplication
Replace Vec::contains() with HashSet::insert() for O(1) dedup lookups
instead of O(n), significantly reducing comparisons during decode.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams 99d95c8eb6 [refactor](trx-frontend-rigctl): adapt to Cow-returning mode_to_string
Update rig_mode_to_str to call .into_owned() on the new Cow return.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00
ClaudeandStan Grams 019f12e3fc [refactor](trx-protocol): return Cow<'static, str> from mode_to_string
Eliminates per-call String allocations for standard modes by returning
borrowed static strings. Only the Other variant allocates.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 07:02:46 +01:00