From 95fccd3da63fc18bd1a87a1802ab1e6ef5647351 Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Thu, 12 Mar 2026 22:57:25 +0100 Subject: [PATCH] [feat](trx-frontend-http): expand background decode selection Co-authored-by: OpenAI Codex Signed-off-by: Stan Grams --- .../trx-frontend-http/assets/web/index.html | 2 ++ .../assets/web/plugins/background-decode.js | 3 +- .../assets/web/plugins/bookmarks.js | 4 +++ .../trx-frontend-http/assets/web/style.css | 3 +- .../src/background_decode.rs | 29 ++++++++++++++++++- .../trx-frontend-http/src/server.rs | 4 +-- 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html index c0b541d..4cfdc36 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html @@ -358,6 +358,8 @@
Decoders
+ + diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/background-decode.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/background-decode.js index 752933c..5318fd1 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/background-decode.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/background-decode.js @@ -5,7 +5,7 @@ (function () { "use strict"; - const SUPPORTED_DECODERS = ["ft8", "wspr", "hf-aprs"]; + const SUPPORTED_DECODERS = ["aprs", "ais", "ft8", "wspr", "hf-aprs"]; let backgroundDecodeRole = null; let currentRigId = null; @@ -303,6 +303,7 @@ case "no_supported_decoders": return "Unsupported"; case "disabled": return "Disabled"; case "handled_by_scheduler": return "Scheduler"; + case "handled_by_virtual_channel": return "VChan"; default: return "Inactive"; } } diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js index 358d431..cfb4148 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js @@ -148,6 +148,8 @@ function bmRender(list) { // Read decoder checkboxes and return an array of selected decoder names. function bmReadDecoders() { const decoders = []; + if (document.getElementById("bm-dec-aprs").checked) decoders.push("aprs"); + if (document.getElementById("bm-dec-ais").checked) decoders.push("ais"); if (document.getElementById("bm-dec-ft8").checked) decoders.push("ft8"); if (document.getElementById("bm-dec-wspr").checked) decoders.push("wspr"); if (document.getElementById("bm-dec-hf-aprs").checked) decoders.push("hf-aprs"); @@ -157,6 +159,8 @@ function bmReadDecoders() { // Set decoder checkboxes to match the given array. function bmWriteDecoders(decoders) { const list = decoders || []; + document.getElementById("bm-dec-aprs").checked = list.includes("aprs"); + document.getElementById("bm-dec-ais").checked = list.includes("ais"); document.getElementById("bm-dec-ft8").checked = list.includes("ft8"); document.getElementById("bm-dec-wspr").checked = list.includes("wspr"); document.getElementById("bm-dec-hf-aprs").checked = list.includes("hf-aprs"); diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css index 3a952c5..02d6c4c 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css @@ -3559,7 +3559,8 @@ button:focus-visible, input:focus-visible, select:focus-visible { .bgd-status-state[data-state="waiting_for_spectrum"], .bgd-status-state[data-state="waiting_for_user"], .bgd-status-state[data-state="inactive"], -.bgd-status-state[data-state="handled_by_scheduler"] { +.bgd-status-state[data-state="handled_by_scheduler"], +.bgd-status-state[data-state="handled_by_virtual_channel"] { color: var(--accent-yellow); } .bgd-status-state[data-state="missing_bookmark"], diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/background_decode.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/background_decode.rs index 8063012..7d6eada 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/src/background_decode.rs +++ b/src/trx-client/trx-frontend/trx-frontend-http/src/background_decode.rs @@ -19,9 +19,11 @@ use uuid::Uuid; use crate::server::bookmarks::{Bookmark, BookmarkStore}; use crate::server::scheduler::SchedulerStatusMap; +use crate::server::vchan::{ClientChannel, ClientChannelManager}; -const SUPPORTED_DECODER_KINDS: &[&str] = &["ft8", "wspr", "hf-aprs"]; +const SUPPORTED_DECODER_KINDS: &[&str] = &["aprs", "ais", "ft8", "wspr", "hf-aprs"]; const CHANNEL_KIND_NAME: &str = "VirtualBackgroundDecodeChannel"; +const VISIBLE_CHANNEL_KIND_NAME: &str = "VirtualChannel"; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct BackgroundDecodeConfig { @@ -122,6 +124,7 @@ pub struct BackgroundDecodeManager { bookmarks: Arc, context: Arc, scheduler_status: SchedulerStatusMap, + vchan_mgr: Arc, status: Arc>>, notify_tx: broadcast::Sender<()>, } @@ -132,6 +135,7 @@ impl BackgroundDecodeManager { bookmarks: Arc, context: Arc, scheduler_status: SchedulerStatusMap, + vchan_mgr: Arc, ) -> Arc { let (notify_tx, _) = broadcast::channel(16); Arc::new(Self { @@ -139,6 +143,7 @@ impl BackgroundDecodeManager { bookmarks, context, scheduler_status, + vchan_mgr, status: Arc::new(RwLock::new(HashMap::new())), notify_tx, }) @@ -280,6 +285,13 @@ impl BackgroundDecodeManager { && channel.decoder_kinds == desired.decoder_kinds } + fn virtual_channels_cover_bookmark(&self, rig_id: &str, bookmark: &Bookmark) -> bool { + self.vchan_mgr + .channels(rig_id) + .into_iter() + .any(|channel| channel_matches_bookmark(&channel, bookmark)) + } + fn reconcile(&self, runtime: &mut BackgroundRuntimeState, spectrum: &SharedSpectrum) { let active_rig_id = self.active_rig_id(); @@ -367,6 +379,13 @@ impl BackgroundDecodeManager { continue; } + if self.virtual_channels_cover_bookmark(&rig_id, bookmark) { + status.state = "handled_by_virtual_channel".to_string(); + status.channel_kind = Some(VISIBLE_CHANNEL_KIND_NAME.to_string()); + statuses.push(status); + continue; + } + let (Some(center_hz), Some(half_span_hz)) = (center_hz, half_span_hz) else { status.state = "waiting_for_spectrum".to_string(); statuses.push(status); @@ -506,6 +525,14 @@ fn supported_decoder_kinds(decoders: &[String]) -> Vec { out } +fn channel_matches_bookmark(channel: &ClientChannel, bookmark: &Bookmark) -> bool { + channel.freq_hz == bookmark.freq_hz && normalized_mode(&channel.mode) == normalized_mode(&bookmark.mode) +} + +fn normalized_mode(mode: &str) -> String { + mode.trim().to_ascii_lowercase() +} + #[get("/background-decode/{rig_id}")] pub async fn get_background_decode( path: web::Path, diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/server.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/server.rs index d3be641..97b3c37 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/src/server.rs +++ b/src/trx-client/trx-frontend/trx-frontend-http/src/server.rs @@ -88,16 +88,16 @@ async fn serve( let background_decode_path = BackgroundDecodeStore::default_path(); let background_decode_store = Arc::new(BackgroundDecodeStore::open(&background_decode_path)); + let vchan_mgr = Arc::new(ClientChannelManager::new(4)); let background_decode_mgr = BackgroundDecodeManager::new( background_decode_store, bookmark_store.clone(), context.clone(), scheduler_status.clone(), + vchan_mgr.clone(), ); background_decode_mgr.spawn(); - let vchan_mgr = Arc::new(ClientChannelManager::new(4)); - // Wire the audio-command sender so allocate/delete/freq/mode operations on // virtual channels are forwarded to the audio-client task. if let Ok(guard) = context.vchan_audio_cmd.lock() {