Commit Graph

761 Commits

Author SHA1 Message Date
Claude d26ef6ca81 [feat](trx-wxsat): rename trx-noaa to trx-wxsat with full NOAA APT decode
Rename the crate from trx-noaa to trx-wxsat (weather satellite) across
the entire workspace. Add full NOAA satellite decode support:

- Telemetry frame parsing: extract 16-wedge calibration data from the
  128-line telemetry frames embedded in APT lines
- Radiometric calibration: piecewise-linear LUT built from wedges 1-8
  to correct pixel values against known reference levels
- Channel identification: detect AVHRR sensor channels (VIS, NIR, MIR,
  TIR) from wedge 9 values per APT sub-channel
- Satellite identification: heuristic NOAA-15/18/19 detection from
  channel A/B sensor pairings
- Histogram equalisation: per-channel contrast enhancement for improved
  image output
- WxsatImage now carries satellite name and channel labels in decoded
  message broadcasts

https://claude.ai/code/session_01JA13DHuzuHUL4nSBBRU83f
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-28 10:36:34 +01:00
sjg e0181c99da [fix](trx-client): handle NoaaImage in replay history sink
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-28 07:12:13 +01:00
sjg f148cc05fc [fix](trx-frontend-http): handle NoaaImage in snapshot and decode match
- Add noaa_decode_enabled to the fallback RigSnapshot initializer in api.rs
- Add NoaaImage arm (no-op) to the DecodedMessage match in audio.rs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-28 07:10:07 +01:00
Claude cf79df110a [fix](trx-frontend-http): map filter affects statistics, tooltips show receiver rig
Statistics panels (longest paths, strongest/weakest signals) now respect
all active map filters — source type, rig selector, band, search, and
history. Locator tooltips display which rig received each decoded frame.

https://claude.ai/code/session_01LT7zBnb2kQiYpeTuWNXHsT
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 22:01:43 +01:00
Claude 12726f3d2c [feat](trx-frontend-http): add R hotkey to round frequency up to next step
Remap retune from R to T, and add a new R hotkey that rounds the
current frequency forward to the next jog-step boundary. Both the
new hotkey and the remapped retune are documented in the F1 help
overlay.

https://claude.ai/code/session_017neG2jL9uXFSRpmhyS1EqG
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 21:52:28 +01:00
Claude 7c33af3d83 [feat](trx-frontend-http): add keyboard hotkeys for radio controls
Map R=retune, B=previous state, [/]=bandwidth ±10kHz, arrows=tune/center,
M=mode picker, Z=mono/stereo, N=noise blanker, Q=squelch toggle.
Document all shortcuts in the F1 help overlay.

https://claude.ai/code/session_01WDC889uQGW9XoPQqSZ6bVt
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 21:44:05 +01:00
Claude 71fe884ae6 [fix](trx-frontend-http): show all rigs data on map panel regardless of active rig
Remove rig_id filtering from dispatchDecodeMessage and dispatchDecodeBatch
so that decode data from all rigs (including remote/non-primary) flows into
the map. Also remove the rig_filter query param from decode history fetch
so all history is loaded. The existing map rig filter dropdown handles
visibility filtering via marker.__trxRigIds.

https://claude.ai/code/session_01GGvdXKdEbRBnJa2BjAQuVB
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 21:21:25 +01:00
sjg 0efdb5e360 [fix](trx-rs): show signal strength with decimal precision
Change RigRxStatus.sig from i32 to f64 and add get_signal_strength_db
to RigCat trait so SDR backends can bypass the coarse 0..15 quantisation.
Compensate for decimation processing gain so the meter matches the
spectrum peak. Display with one decimal place in all units.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-27 20:06:36 +01:00
Claude cf82c853cf [fix](trx-frontend-http): stabilize signal strength field width and BW overlay positioning
Increase sig-strength-display min-width to 7.5rem so the field no longer
resizes when the value switches between two-digit and three-digit numbers.

Reposition the fast BW overlay immediately when bandwidth changes arrive
via SSE, and force-display on bookmark apply so freq+bw render atomically
instead of the BW bars wiggling from a stale intermediate state.

https://claude.ai/code/session_01R2XBFEBL8CrsTx5inu25MA
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 17:18:45 +01:00
Claude 434a7f899d [fix](trx-frontend-http): stop SSE updates from resetting frequency input and causing redundant spectrum redraws
SSE status updates called applyLocalTunedFrequency with forceDisplay=true,
clearing the freqDirty flag on every update and overwriting user input mid-
typing. Remove forceDisplay from SSE path so the dirty flag is respected.

Skip applyLocalTunedFrequency entirely when frequency hasn't changed to
avoid redundant spectrum redraws and overlay repositioning on every SSE
frame. Only trigger scheduleSpectrumDraw when frequency actually changes.

Add blur and Escape handlers on frequency inputs to cleanly exit editing
mode when the user abandons input.

https://claude.ai/code/session_01H2VMATj29FPgR64t9YMdSR
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 17:02:57 +01:00
sjg 4fc32f0e90 [fix](trx-rs): wire DSP signal strength to Signal strength field and per-vchan SSE
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-27 14:24:44 +01:00
Claude d864969742 [feat](trx-frontend-http): add clickable Sig Strength field between Wavelength and Frequency
Add a new "Sig Strength" display field in the freq row that shows
the measured signal strength. Clicking the field cycles through
three units: dBFS (default), dBf, and dBm. The selected unit is
persisted in localStorage.

https://claude.ai/code/session_01EvRV8UgsVtbrcH4t2hmFBF
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 13:37:47 +01:00
Claude 4da4d8ec66 [feat](trx-rs): add CCI/ACI bars to WFM panel with RDS mitigation
Estimate Co-Channel Interference (CCI) from pilot tone quadrature
leakage and coherence degradation.  Estimate Adjacent Channel
Interference (ACI) from CMA equalizer tap deviation from identity.
Both metrics (0-100 scale) are surfaced through RigFilterState and
displayed as colour-coded bars in the WFM control panel.

The RDS decoder quality parameter is now adaptively penalised when
CCI/ACI levels are elevated, reducing block-error rate under
interference conditions.

https://claude.ai/code/session_016EKzep42RCvE4GxvvRaCwu
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 09:44:28 +01:00
Claude 2ba942f33b [refactor](trx-frontend-http): simplify auto-squelch to single-click action
Revert toggle approach back to a simple button: click sets squelch to
noise floor + 6 dB when spectrum data is available, or Off otherwise.

https://claude.ai/code/session_01TDQyrZiPKfWGATVWPsLmHT
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 07:49:18 +01:00
Claude 0e5410c0c5 [feat](trx-frontend-http): make auto-squelch a toggle, default to Off
The Auto button now toggles between Off and Auto states. Default is Off.
First click sets squelch to noise floor + 6 dB; second click resets to
Open (0%). Button shows active state with green highlight when engaged.

https://claude.ai/code/session_01TDQyrZiPKfWGATVWPsLmHT
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 07:49:18 +01:00
Claude 7edc8b7bfe [fix](trx-frontend-http): auto-squelch defaults to Off without spectrum data
When no spectrum data is available, the Auto button now sets squelch
to 0% (Off) instead of silently doing nothing.

https://claude.ai/code/session_01TDQyrZiPKfWGATVWPsLmHT
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 07:49:18 +01:00
Claude 2d8dfb1a3d [feat](trx-frontend-http): add auto-squelch button to Audio panel
Add an "Auto" button next to the SQL slider that sets the squelch
threshold to the current noise floor (estimated from spectrum bins)
plus a 6 dB margin. Uses the existing estimateNoiseFloorDb() heuristic.

https://claude.ai/code/session_01TDQyrZiPKfWGATVWPsLmHT
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-27 07:49:18 +01:00
sjg bb5beb79da [feat](trx-client): freeze only the disconnected rig's view in multi-rig mode
Track per-rig server connection state in `rig_server_connected` so that when
one trx-server drops, only the rig(s) it serves are marked disconnected. Other
rigs with active connections remain fully interactive. The SSE `server_connected`
field is now resolved from the per-rig map for the session's active rig, falling
back to the global flag for backward compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 23:22:07 +01:00
sjg 27489c3745 [feat](trx-rs): rename AMC (AM C-QUAM) to SAM (Stereo AM) with stereo width and carrier sync controls
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:50:53 +01:00
sjg 20a22622e7 [fix](trx-frontend-http): hide scheduler controls in main view when scheduler disabled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:35:06 +01:00
sjg 79fcb1ba9c [feat](trx-frontend-http): add Client sub-tab to About page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:23:47 +01:00
sjg dd8d2a4bfa [fix](trx-frontend-http): hide duplicate spectrum waterfall, use overview waterfall only
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:06:36 +01:00
sjg d99ce62562 [fix](trx-frontend-http): swap spectrum layout — waterfall on top, waveform on bottom
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 21:01:12 +01:00
sjg a82541e24e [fix](trx-frontend-http): drop peak labels, equalize spectrum/waterfall split
Remove overkill peak frequency labels from spectrum view. Set waterfall
height to match spectrum height (1:1 split) instead of fixed 120px.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:53:50 +01:00
sjg 36be58a537 [feat](trx-frontend-http): spectrum view UI/UX improvements
Add 8 enhancements to the spectrum display:

1. Noise floor reference line — dashed horizontal line at estimated
   noise floor (15th-percentile heuristic)
2. Peak frequency labels — top 5 strongest peaks labeled with
   frequency text on the spectrum canvas
3. Crosshair lines — vertical + horizontal guide lines follow
   cursor on hover for precise frequency/dB reading
4. Zoom indicator + minimap — shows current zoom level (e.g. "4.0x")
   and a minimap showing the visible window within the full span
5. dB range control — new Range input alongside Floor, with Auto
   button updating both; allows direct control of vertical span
6. Keyboard shortcuts — Arrow Left/Right to pan, +/- to zoom,
   0 to reset zoom; documented in hint bar
7. Full waterfall panel — WebGL waterfall canvas below the spectrum
   plot, synchronized with zoom/pan, with scroll/click/drag support
8. Signal overlay extended — overlay height now includes waterfall
   canvas for consistent BW/bookmark/freq marker coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:48:30 +01:00
sjg caa7603489 [fix](trx-rs): frost main view on trx-server disconnect
Nudge state watch when server_connected goes false so SSE delivers the change. Frontend applies a desaturated frost + banner instead of a blocking overlay, keeping the last-known state visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:28:56 +01:00
sjg c8de54d85e [feat](trx-rs): show audio bitrate and active stream count on About page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:18:19 +01:00
sjg 25338710ee [feat](trx-frontend-http): rework About page with grouped cards and new info
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 20:07:33 +01:00
sjg 5be4019c04 [feat](trx-frontend-http): rename Decoders tab to Digital modes and filter by active rig
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 19:44:01 +01:00
sjg 1a744e427a [feat](trx-frontend-http): draw radio path from each receiver location
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 18:57:41 +01:00
sjg ab0003b08d [feat](trx-frontend-http): show receiver/locator on map panel stat cards
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-26 18:36:08 +01:00
Claude 8e6623b39e [fix](trx-rs): use per-message rig_id for map marker tagging
The map module was tagging all decode markers (APRS, AIS, VDES,
FT8/FT4/FT2/WSPR locators) with the global rig picker's active rig
instead of the actual source rig. This made the map's own rig filter
dropdown ineffective in multi-rig setups.

- Add rig_id field to all decode message structs (AisMessage,
  VdesMessage, AprsPacket, CwEvent, Ft8Message, WsprMessage)
- Set rig_id on messages in audio_client before broadcasting, using
  the actual rig connection identifier
- Update history collector to prefer message rig_id over the global
  active rig fallback
- Pass rig_id through plugin normalize functions (AIS, APRS, VDES,
  HF-APRS) so it reaches the map add functions
- Update all map marker functions (aprsMapAddStation, aisMapAddVessel,
  vdesMapAddPoint, mapAddLocator) to use the message's rig_id with
  fallback to the global picker for backward compatibility

https://claude.ai/code/session_015gC7axHk2jmp7HbFPdbivN
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 16:29:53 +01:00
Claude a63f27971d fix(trx-server): remove unused RigSdr import in rig_task.rs
Also run cargo fmt to fix formatting issues across trx-server,
trx-frontend-http, and trx-configurator.

https://claude.ai/code/session_01RsHUyVz2wjQjsEsxJo5owt
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 14:01:44 +01:00
Claude c8f33b8939 [refactor](trx-rs): remove shared-library plugin system
Drop the plugin loading infrastructure (libloading-based dynamic .so/.dylib/.dll
loading) from both trx-server and trx-client. The feature was unused and posed an
unnecessary security risk by executing arbitrary native code from disk.

Removed:
- src/trx-app/src/plugins.rs (plugin discovery, validation, FFI registration)
- examples/trx-plugin-example/ (cdylib example plugin)
- libloading dependency from trx-app
- load_backend_plugins / load_frontend_plugins calls from server and client
- Plugin documentation from README.md and CLAUDE.md

https://claude.ai/code/session_01DTEUpz3XPUeWmz74NeaFgb
Signed-off-by: Claude <noreply@anthropic.com>
2026-03-26 12:44:56 +01:00
Claude 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
Claude 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
Claude 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
Claude 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
Claude 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
Claude 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
Claude 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
Claude 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
sjg 6eff023271 [fix](trx-frontend-http): reduce decoder overlay opacity in spectrum screenshots
Decoder bar overlays (AIS, VDES, FT8, APRS, RDS) use backdrop-filter
blur for a frosted-glass look in the browser, but this can't be
replicated on canvas — resulting in opaque blocks covering the spectrum
in screenshots. Cap their background alpha to 0.35 when rendering to
the snapshot canvas.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 23:11:51 +01:00
sjg d11f7b4876 [feat](trx-frontend-http): add F1 keyboard shortcuts overlay
Press F1 to toggle a help overlay listing available keyboard shortcuts.
Dismiss with F1, Escape, or clicking the backdrop. Refactored the
global keydown handler to route all shortcuts through one listener.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-25 23:11:50 +01:00
sjg 6eb0f3a116 [fix](trx-frontend-http): preserve bookmark bandwidth
Order bookmark mode and bandwidth updates so WFM bookmarks do\nnot race against the backend mode default.\n\nAlso apply saved bookmark bandwidth in the scheduler path so\nscheduled bookmark replays keep the configured filter width.\n\nTested with:\n- cargo test -p trx-frontend-http\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 23:04:35 +01:00
sjg c93e855f0d [fix](trx-frontend-http): draw radio paths from actual receiver, improve mobile spectrum controls
Radio paths now originate from the rig that decoded the message rather
than the currently selected rig. Bookmark locators no longer draw radio
paths. Rig switch no longer tears down decode pipeline since it is
rig-independent. Mobile spectrum controls use flex-wrap for better layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 22:34:43 +01:00
sjg a5e443a224 [feat](trx-frontend-http): show all rig locations on map, load decode history for all remotes
Add latitude/longitude to /rigs API response. Map now displays receiver
markers for all configured rigs, de-duplicated by location. Decode history
is no longer filtered to the active rig so all remotes contribute to the map.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 22:26:48 +01:00
sjg a32560a9ab [feat](trx-frontend-http): restore rig selector on map with All as default
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 22:15:55 +01:00
sjg 4b387457af [fix](trx-frontend-http): show general bookmarks in scheduler bookmark selector
Use the merged bookmarks endpoint instead of separate fetches so general
bookmarks are always visible alongside rig-specific ones.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 22:03:00 +01:00
sjg d88eb89e16 [feat](trx-frontend-http): add WASM Opus decoder fallback for Safari/iPadOS audio
WebCodecs AudioDecoder does not support Opus on Safari. Fall back to
opus-decoder WASM library (loaded from CDN) for browsers without
WebCodecs Opus support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
2026-03-24 21:52:09 +01:00