Commit Graph

1250 Commits

Author SHA1 Message Date
sjg 82009494b5 [fix](trx-frontend-http): return 403 for unrestricted RX users on control endpoints
When rx_passphrase is not set, RX users have an implicit role without
a session. They should get 403 on control endpoints, not 401.

Previously, unrestricted RX users (with no session) trying control
endpoints would get 401 Unauthorized, triggering login redirect.

Now they get 403 Forbidden with "Insufficient permissions" hint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:53:46 +01:00
sjg 65662a4f9b [fix](trx-frontend-http): return 403 for insufficient permissions, not 401
Fix auth middleware to return correct HTTP status codes:
- 401 Unauthorized: No session (not authenticated)
- 403 Forbidden: Has session but insufficient role

Previously, all auth errors returned 401, which caused the frontend
to redirect rx users to login when they tried control endpoints.

Now rx users scrolling jog wheel/frequency will get a "Insufficient
permissions" hint instead of being redirected to login.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:52:38 +01:00
sjg 00f82646c2 [refactor](trx-frontend-http): consolidate to single auth interface
Remove duplicate logout button from About tab. Use only the header
Login/Logout button for unified authentication control.

The About tab now shows the authentication badge (when logged in)
without the redundant logout button.

Single login view:
- Auth gate with Login form + Continue as Guest button (when no rx pass)
- Header Login/Logout button for quick access
- Auth badge in About tab showing current role

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:51:49 +01:00
sjg 4d959b649f [fix](trx-frontend-http): don't redirect to login on 403 (insufficient permissions)
Only redirect to login on 401 (unauthenticated). For 403 errors
(authenticated but insufficient role), let the caller handle the error.

This prevents rx-authenticated users from being redirected to login
when they attempt to scroll the jog wheel or frequency input, which
tries to call /set_freq (a control-only endpoint).

RX users will now see "Insufficient permissions" hint instead of
being sent to login screen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:50:58 +01:00
sjg 4d0a9d6d90 [feat](trx-frontend-http): disable plugin enable/disable for rx role
Disable plugin toggle buttons for rx-authenticated users:
- FT8 decode toggle
- WSPR decode toggle
- CW auto checkbox

RX users cannot enable/disable decoders, preventing unintended
configuration changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:47:58 +01:00
sjg 62f96a1e53 [fix](trx-frontend-http): show auth gate after logout and disable jog/VFO for rx
Fix logout flow to properly show auth gate and clear form. Also
disable additional controls for rx role:
- Jog wheel (faded out)
- Jog up/down buttons
- VFO selector buttons

For rx-authenticated users, all frequency/mode adjustment controls
are now properly disabled to prevent accidental changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:47:40 +01:00
sjg 0b7158f465 [fix](trx-frontend-http): prevent browser hang on logout
Replace location.reload() with disconnect() + auth gate to prevent
browser hang when logging out. The full page reload was causing
issues with resource loading and event source reconnection timers.

Changes:
- Add disconnect() function to cleanly close EventSource connections
  and clear all timers (esHeartbeat, reconnectTimer)
- authLogout() now disconnects locally and shows auth gate instead
  of reloading the page
- Faster logout experience without full page reload

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:46:25 +01:00
sjg 8b9da52fe7 [feat](trx-frontend-http): add header auth button (Login/Logout)
Add a Login/Logout button in the header next to the theme toggle,
styled consistently with the theme button. Button behavior:

- When logged in: Shows "Logout" with confirmation
- When not logged in: Shows "Login" to open auth gate
- Visible when on main app (not in auth gate)
- Same theme-toggle-btn styling

Provides quick access to authentication controls without needing to
navigate to the About tab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:44:52 +01:00
sjg 9d3b690aca [fix](trx-frontend-http): always show auth gate when no valid session
Do not auto-connect with guest role. Always show the auth gate when
there's no valid session, allowing the user to choose between:
- Login: Enter passphrase for control access
- Continue as Guest: Proceed with read-only access (if available)

This allows users to enter their control passphrase instead of being
forced into guest mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:43:14 +01:00
sjg 599fa42bb3 [feat](trx-frontend-http): add guest button to auth gate
When RX access is unrestricted (no rx_passphrase required), show
a "Continue as Guest" button on the auth gate to allow immediate
access without requiring login. The button is only shown when guest
mode is available.

Guest mode:
- No authentication required
- Grants rx role immediately
- Can monitor radio but cannot transmit

Login path still available for full control access.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:41:36 +01:00
sjg 59ee8f5760 [feat](trx-frontend-http): grey out TX controls for rx-authenticated users
When a user is authenticated as 'rx' role (read-only), disable all
TX/PTT control buttons and frequency/mode inputs to prevent accidental
attempts to transmit. This provides clear visual feedback that these
controls are not available.

Controls disabled for rx role:
- PTT button
- Power button
- Lock button
- TX Audio button
- Frequency input
- Mode select
- TX Limit input/button
- Jog up/down buttons
- Jog step buttons

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:39:31 +01:00
sjg 20d08f6c7c [feat](trx-frontend-http): allow unrestricted RX access when rx_passphrase not set
When HTTP auth is enabled but rx_passphrase is not configured, allow
unauthenticated users to access read-only endpoints (status, events,
decode, audio) without authentication. This enables monitoring-only
access while protecting TX control with a passphrase.

Changes:
- AuthMiddleware: Skip auth check for read routes when rx_passphrase is None
- session_status: Grant rx role to unauthenticated users when no rx passphrase required

Use case: Set only control_passphrase to protect TX/PTT while allowing
anyone on the network to monitor the radio.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:39:05 +01:00
sjg e3deac2731 [fix](trx-client): pass HTTP auth config from TOML to server
The HTTP server was hardcoding auth config with enabled=false,
ignoring the actual configuration from trx-client.toml. This prevented
authentication enforcement even when enabled with passphrases.

Solution: Store auth config values in FrontendRuntimeContext during
initialization in main.rs, then extract and use them in server.rs
build_server() instead of hardcoding.

Fixes auth bypass where unauthenticated users could access the web UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:36:01 +01:00
sjg 070409c280 [docs](trx-client): add example auth passphrases to printed config
Update example_toml() to include example values for rx_passphrase and
control_passphrase in the printed config output, so users can see what
these configuration fields should look like.

Now --print-config shows:
[frontends.http.auth]
enabled = false
rx_passphrase = "rx-passphrase-example"
control_passphrase = "control-passphrase-example"
tx_access_control_enabled = true
session_ttl_min = 480
cookie_secure = false
cookie_same_site = "Lax"

This helps users understand all available auth parameters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:33:20 +01:00
sjg 19a4440e7f [feat](trx-client): add home directory config search path
Add ~/.trx-client.toml to the config file search paths, making it easy
for users to place their config in the home directory.

Updated search order:
1. Path specified via --config CLI argument
2. ./trx-client.toml (current directory)
3. ~/.trx-client.toml (home directory) [NEW]
4. ~/.config/trx-rs/client.toml (XDG config)
5. /etc/trx-rs/client.toml (system-wide)

This provides a more standard Unix convention for user config files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:30:27 +01:00
sjg 4e43b5b533 [fix](trx-frontend-http): grant full access by default when auth is disabled
When HTTP authentication is disabled (the default), the /auth/session
endpoint now returns { authenticated: true, role: "control" } instead
of 404. This allows the frontend to proceed without showing a login
gate, providing the expected out-of-the-box experience.

With this change:
- Default behavior: no login required, full control access
- Auth enabled: login gate shown, roles enforced per config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:26:20 +01:00
sjg a1c0755ccc [style](trx-frontend-http): remove duplicate logo from login screen
Remove the redundant logo image from the auth gate. The header already
displays the logo, so this duplicate was unnecessary.

The login screen now shows only:
- "Access Required" heading
- "Enter passphrase to continue" subtitle
- Passphrase input
- Login button

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:25:42 +01:00
sjg 6d058d4c7d [style](trx-frontend-http): align login button width with passphrase field
Add box-sizing: border-box to both the passphrase input and login button
to ensure padding is included in width calculations. This makes them
exactly the same width visually.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:25:32 +01:00
sjg 621865d69f [fix](trx-frontend-http): hide tabs until authentication is granted
Hide the Main/Plugins/About tab bar initially, only showing it after
the user successfully authenticates. This prevents navigation options
from being visible when access has not been granted.

Changes:
- Add display:none and id to tab-bar div in index.html
- Update showAuthGate() to hide tab-bar
- Update hideAuthGate() to show tab-bar

Now the UI flow is:
1. Header only (auth gate visible)
2. After login: Header + tabs + content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:24:52 +01:00
sjg 59dde88b2e [style](trx-client, trx-frontend-http): fix clippy warnings
- Derive Default for SameSite enum in auth.rs using #[default] attribute
- Derive Default for CookieSameSite enum in config.rs
- Replace and_then(|x| Some(y)) with map(|x| y) in extract_session_id()

All clippy warnings resolved. Tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:23:17 +01:00
sjg 0459bf16b1 [chore](trx-client): update example config to include HTTP auth section
Update ClientConfig::example_toml() to explicitly include all HTTP auth
config fields with their default values, so the --print-config output
displays the complete auth configuration section.

Also add #[allow(dead_code)] to session_ttl() method to suppress warning.

The example config now shows:
[frontends.http.auth]
enabled = false
tx_access_control_enabled = true
session_ttl_min = 480
cookie_secure = false
cookie_same_site = "Lax"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:20:25 +01:00
sjg 65e1073ea0 [feat](trx-frontend-http): complete HTTP authentication implementation (phases 4-5)
Phase 4: Frontend login gate and role-based UI
- Add auth-gate HTML overlay with passphrase form
- Implement checkAuthStatus, authLogin, authLogout functions
- Auth startup sequence checks /auth/session before connecting
- Apply role-based restrictions: hide PTT/TX controls for rx role
- Handle 401/403 errors in postPath, return to login screen
- Add logout button in About tab with auth role display
- Passphrase form shows generic error messages (no info leakage)

Phase 5: Documentation
- Update trx-client.toml.example with [frontends.http.auth] section
  - All config fields with inline documentation and examples
  - security notes about cookie settings
- Update README.md with HTTP Frontend Authentication section
  - Role model explanation (rx vs control)
  - Configuration example
  - Security considerations for local, LAN, and remote deployments
  - Architecture overview

UI Features:
- Login gate blocks main UI until authenticated
- Role badge shows authenticated status in About tab
- Error messages clear after 5 seconds
- Logout confirmation prevents accidental logouts
- Smooth transition from auth gate to main UI

All code compiles successfully. HTTP frontend build verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:18:49 +01:00
sjg a4b014d66a [feat](trx-frontend-http): implement HTTP authentication (phases 1-3)
Add optional passphrase-based authentication with two roles (rx/control),
session management, auth middleware, and protected routes.

Phase 1: Config model with HttpAuthConfig struct, CookieSameSite enum,
validation logic for enabled auth requiring at least one passphrase.

Phase 2: Auth module with:
- AuthRole enum (Rx, Control)
- SessionRecord and SessionStore for in-memory session management
- AuthConfig at runtime
- /auth/login, /auth/logout, /auth/session endpoints
- Constant-time passphrase comparison for timing attack mitigation

Phase 3: Integration with:
- AuthMiddleware for route protection with public/read/control classification
- Server-side AuthState setup with cleanup task for expired sessions
- Auth endpoints registered in api.rs configure()

Sessions use 128-bit random IDs (hex-encoded), HttpOnly cookies, configurable
SameSite attribute. Auth is disabled by default to preserve current behavior.

All unit and integration tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 08:15:55 +01:00
sjg 66989b306f [feat](trx-frontend-http): refine main UI controls and map visuals
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 02:43:04 +01:00
sjg c510efb331 [feat](trx-frontend-http): sync frequency input wheel with jog control
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 02:16:33 +01:00
sjg 1955d2491d [fix](trx-frontend-http): fix rig access path and unify control height
Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 02:14:15 +01:00
sjg 4f35be539f [feat](trx-frontend-http): improve locator map plotting and themed filters
Refine map plotting and filter UX in HTTP frontend plugins.\n\n- support plotting multiple locator squares from FT8/WSPR messages\n- show locator lists in popup content as newline-separated entries\n- add WSPR map layer filter toggle and marker typing\n- style filter controls for strong dark/light mode contrast\n- keep themed behavior aligned with map and control updates\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 02:11:31 +01:00
sjg f637cf23d3 [feat](trx-frontend-http): add theme toggle and themed map/audio visuals
Add dark/light mode selector below logo and wire theme-aware visuals.\n\n- add compact theme toggle control under header logo\n- support persistent dark/light theme switching\n- use emoji labels for theme toggle actions\n- make jog and audio level visuals theme-aware\n- add dark-mode map tile layer and live layer switching on theme changes\n- keep responsive behavior for header graph and controls\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 02:08:40 +01:00
sjg 53ce663adc [feat](trx-frontend-http): enhance header telemetry and responsive UX
Implement UI refinements for the HTTP frontend main and plugin views.\n\n- add dimmed header signal graph with live rendering and scale\n- make graph responsive, colorized by signal strength, and keep last 10s only\n- add APRS and WSPR text filtering, matching FT8 behavior\n- refine responsive layout for controls/map/header behavior\n- tune jog wheel/button sizing and mode selector height alignment\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 02:03:20 +01:00
sjg 630a02789c [feat](trx-frontend-http): refine responsive main and map layout
Adjust responsive behavior and interaction details in the HTTP frontend.\n\n- switch signal measurement from sample-based to time-based averaging\n- move Transmit/Power below Mode+Tune on small viewports\n- add practical mobile breakpoints and width handling\n- resize and tune logo/top spacing/layout placement\n- make map height viewport-aware with adjustable minimum\n- improve FT8/WSPR control wrapping on small screens\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 01:50:10 +01:00
sjg 088a683c62 [feat](trx-frontend-http): streamline main control layout
Refine main control interactions and presentation in the HTTP frontend.\n\n- remove frequency and mode Set buttons\n- apply mode changes immediately on picker change\n- place Mode/Tune/Transmit-Power controls in one horizontal row\n- align control labels vertically across that row\n- move and enlarge MHz/kHz/Hz selector beside frequency input\n- keep Enter-to-set frequency behavior\n- switch signal measurement to elapsed-time averaging\n- enlarge header logo 2x\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 01:38:51 +01:00
sjg 55c70f0fb7 [feat](trx-rs): expose rigctl metadata in HTTP about tab
Add rigctl frontend visibility in HTTP status/about UI and refine frequency controls layout.\n\n- track rigctl listen endpoint and active rigctl client count in frontend runtime context\n- inject rigctl metadata into HTTP /events payload\n- show rigctl endpoint and rigctl client count in About tab\n- remove frequency Set button from UI\n- move MHz/kHz/Hz selector beside frequency input and enlarge it\n- center jog wheel row and keep Enter-to-set frequency behavior\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 01:33:54 +01:00
sjg 86ca1a60fb [fix](trx-rs): harden hamlib rigctl compatibility
Improve rigctl interoperability with hamlib/WSJT-X and stabilize FT-817 PTT handling.\n\n- support extended '+' command replies\n- accept decimal and MHz-style frequency inputs\n- retry set_freq rounded to 10 Hz on CAT alignment errors\n- add compatibility handling for get_level probes\n- broaden PTT command parsing and aliases\n- derive PTT capability dynamically from snapshot data\n- improve dump_state/dump_caps compatibility behavior\n- move temporary rigctl diagnostics to debug level\n- make FT-817 set_ptt more reliable with unlock/clear and double-send\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 01:30:04 +01:00
sjg c1a7eaa72d [fix](trx-frontend-rigctl): improve hamlib rigctl compatibility
Handle hamlib/netrigctl protocol quirks for command parsing and replies.\n\n- support extended '+' response format\n- accept decimal and MHz-style frequency inputs\n- retry set_freq rounded to 10 Hz on CAT alignment errors\n- accept get_level probes (e.g. KEYSPD)\n- accept broader PTT argument variants\n- add trailing 'done' to dump_state for compatibility\n\nCo-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 01:16:08 +01:00
sjg ca88eec131 [fix](trx-frontend-rigctl): add rigctld dumpcaps handshake
Return setting=value lines with a done terminator for dumpcaps commands so Hamlib netrigctl_open can parse capabilities.

Add a unit test that verifies dumpcaps output formatting.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 01:04:16 +01:00
sjg 6591fcfec7 [feat](trx-client): add local cpal audio bridge for WSJT-X
Add configurable bidirectional local audio bridge (RX playback + TX capture) using cpal/opus for virtual-device routing on Linux/macOS, and document bridge settings.

Also expand rigctl frontend command compatibility aliases for hamlib/WSJT-X clients.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 00:30:49 +01:00
sjg 81890b15a8 [fix](trx-core): expose rig min tuning step and align UI tuning
Add min_freq_step_hz to RigCapabilities, set backend values, and make HTTP frontend parse suffix-less frequency input using the selected unit while snapping set/jog frequencies to rig step granularity.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 00:17:16 +01:00
sjg a7719bd7a9 [fix](trx-server): make ALSA stream recovery reliable
Signal backend stream callback failures directly to capture/playback loops and strengthen cross-thread failure flag visibility so recurring POLLERR conditions consistently trigger stream recreation.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 00:12:12 +01:00
sjg c5b441f75b [fix](trx-frontend-http): adapt frequency input to selected unit
Make the frequency field render and parse values in the currently selected unit (MHz/kHz/Hz), including immediate refresh when switching jog step.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 00:07:53 +01:00
sjg a1d56dc1d0 [fix](trx-server): make PSK Reporter activation diagnosable
Require a receiver locator source when PSK Reporter is enabled,
show inactive reason in status text, and add periodic uplink runtime
counters (received/sent/skipped/errors).

This makes missing-spot issues visible instead of silently dropping
all decode events.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-13 00:05:54 +01:00
sjg d085f96838 [fix](trx-server): auto-recover audio streams and harden frontend reconnect
Implement ALSA/CPAL stream auto-recovery by recreating input/output
streams after backend callback failures with bounded retry delay.

Also improve HTTP frontend resilience by polling /status on reconnect
and after SSE errors to refresh snapshot state after broken pipes.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:59:39 +01:00
sjg 273283708e [fix](trx-server): preserve PSK Reporter status in snapshots
Pass pskreporter_status through RigTaskConfig and apply it to rig_task
state initialization so snapshot updates keep the About-tab value.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:50:41 +01:00
sjg e243f0e4cc [fix](trx-server): include legacy home config path and coords in print-config
Fix server config discovery to include ~/.trx-server.toml and update
example/print-config output to explicitly include general latitude and
longitude fields.

Also update config docs and add a test for the legacy search path.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:47:36 +01:00
sjg 28dab2d00f [feat](trx-server): expose PSK Reporter status in About
Add pskreporter_status to shared rig snapshots and display it in the
HTTP frontend About tab.

Also include audio stream error log throttling to avoid repetitive ALSA
error flooding in backend logs.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:37:15 +01:00
sjg db792cc9d8 [feat](trx-server): add PSK Reporter uplink for FT8/WSPR
Add a PSK Reporter uploader task that subscribes to decoded FT8/WSPR
messages and sends spots over UDP when [pskreporter].enabled is true.

Include new [pskreporter] server config options and example config docs,
and hardcode software identification as 'trx-server v<version> by SP2SJG'.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:31:04 +01:00
sjg 4b1252a3e3 [fix](trx-frontend-http): update WSPR slot countdown timer
Wire the WSPR period label to a live 120-second slot countdown so
it no longer stays at the placeholder value.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:24:11 +01:00
sjg eb3c69df39 [feat](trx-frontend-http): reorder plugin tabs and add FT8 slot timer
Reorder Plugins subtabs to align with the Overview plugin listing
(APRS, CW, FT8, WSPR), with Map moved to the end.

Also add a live FT8 period countdown indicator in the FT8 panel.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:22:37 +01:00
sjg 7b75049f4f [feat](trx-frontend-http): add dedicated WSPR plugin tab
Expose a WSPR subtab in the Plugins view with its own controls and
message list, wire a dedicated wspr.js asset endpoint, and route WSPR
decode events to the new panel.

This makes WSPR visible in the HTTP frontend instead of reusing the
FT8 panel for WSPR messages.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:18:36 +01:00
sjg 6d2d647511 [refactor](trx-wspr): remove external wsprd integration
Drop all external wsprd wrapper/build plumbing and keep trx-wspr on
an internal Rust-only decoder path.

This removes wsprd process dependencies and leaves a native decoder
scaffold with the same public API for incremental algorithm work.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 23:15:01 +01:00
sjg ae5edabc27 [refactor](trx-wspr): split wsprd wrapper from decoder
Extract external wsprd process invocation into a dedicated wrapper
module and keep WSPR decode orchestration in a separate decoder module.

This mirrors the ft8 crate layering and makes wsprd integration easier
to test and evolve.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
2026-02-12 22:54:44 +01:00