diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index b4af334..4674853 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -3241,22 +3241,22 @@ function render(update) { const wsprStatus = document.getElementById("wspr-status"); setModeBoundDecodeStatus( aisStatus, - ["AIS"], - "Select AIS mode to decode", + ["AIS", "FM", "PKT"], + "Select AIS or FM mode to decode", "Connected, listening for packets", ); if (window.updateAisBar) window.updateAisBar(); setModeBoundDecodeStatus( vdesStatus, - ["VDES"], - "Select VDES mode to decode", + ["VDES", "FM"], + "Select VDES or FM mode to decode", "Connected, listening for bursts", ); if (window.updateVdesBar) window.updateVdesBar(); setModeBoundDecodeStatus( aprsStatus, - ["PKT"], - "Select PKT mode to decode", + ["PKT", "FM"], + "Select FM mode to decode", "Connected, listening for packets", ); if (window.updateAprsBar) window.updateAprsBar(); @@ -8903,10 +8903,10 @@ function updateDecodeStatus(text) { const ft8 = document.getElementById("ft8-status"); const ft4 = document.getElementById("ft4-status"); const ft2 = document.getElementById("ft2-status"); - setModeBoundDecodeStatus(ais, ["AIS"], "Select AIS mode to decode", text); + setModeBoundDecodeStatus(ais, ["AIS", "FM", "PKT"], "Select AIS or FM mode to decode", text); const vdesText = text === "Connected, listening for packets" ? "Connected, listening for bursts" : text; - setModeBoundDecodeStatus(vdes, ["VDES"], "Select VDES mode to decode", vdesText); - setModeBoundDecodeStatus(aprs, ["PKT"], "Select PKT mode to decode", text); + setModeBoundDecodeStatus(vdes, ["VDES", "FM"], "Select VDES or FM mode to decode", vdesText); + setModeBoundDecodeStatus(aprs, ["PKT", "FM"], "Select FM mode to decode", text); const cwText = text === "Connected, listening for packets" ? "Connected, listening for CW" : text; setModeBoundDecodeStatus(cw, ["CW", "CWR"], "Select CW mode to decode", cwText); if (ft8 && ft8.textContent !== "Receiving") ft8.textContent = text; 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 7341c82..6648ad5 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 @@ -449,14 +449,13 @@ Mode - + - @@ -561,25 +560,25 @@ FT8 Decoder - Decodes FT8 messages from RX audio (DIG/USB only, toggle required). + Decodes FT8 messages from RX audio (USB only, toggle required). FT4 Decoder - Decodes FT4 messages from RX audio (DIG/USB only, toggle required). 7.5-second slots. + Decodes FT4 messages from RX audio (USB only, toggle required). 7.5-second slots. FT2 Decoder - Decodes FT2 messages from RX audio (DIG/USB only, toggle required). 3.75-second slots. + Decodes FT2 messages from RX audio (USB only, toggle required). 3.75-second slots. WSPR Decoder - Decodes WSPR messages from RX audio (DIG/USB only, toggle required). + Decodes WSPR messages from RX audio (USB only, toggle required). diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/aprs.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/aprs.js index e5bb738..b496e77 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/aprs.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/aprs.js @@ -322,7 +322,8 @@ function renderAprsHistory() { function updateAprsBar() { if (!aprsBarOverlay) return; - const isPkt = (document.getElementById("mode")?.value || "").toUpperCase() === "PKT"; + const modeVal = (document.getElementById("mode")?.value || "").toUpperCase(); + const isPkt = modeVal === "PKT" || modeVal === "FM"; const cutoffMs = Date.now() - APRS_BAR_WINDOW_MS; const okFrames = aprsPacketHistory.filter((p) => p.crcOk && p._tsMs >= cutoffMs); const frames = collapseAprsDuplicates(okFrames).slice(0, 8); 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 4833160..4ef159d 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 @@ -102,7 +102,7 @@ if (supported.length > 0) return supported; const mode = String(bookmark && bookmark.mode || "").trim().toUpperCase(); if (mode === "AIS") return ["ais"]; - if (mode === "PKT") return ["aprs"]; + if (mode === "PKT" || mode === "FM") return ["aprs"]; return supported; } 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 3eabfb4..2cfb9cd 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 @@ -428,9 +428,9 @@ async function bmApply(bm) { await postPath("/set_freq?hz=" + bm.freq_hz); } })(); - // Decoder toggles (DIG / FM modes) — also fire-and-forget. + // Decoder toggles (USB / DIG / FM / PKT modes) — also fire-and-forget. const hasDecoders = Array.isArray(bm.decoders) && bm.decoders.length > 0; - const decoderMode = bm.mode === "DIG" || bm.mode === "FM"; + const decoderMode = bm.mode === "USB" || bm.mode === "DIG" || bm.mode === "FM" || bm.mode === "PKT"; const decoderPromise = (hasDecoders && decoderMode) ? (async () => { const statusResp = await fetch("/status"); if (statusResp.ok) { 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 ea675ae..9beb0a6 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 @@ -630,7 +630,7 @@ fn bookmark_supported_decoder_kinds(bookmark: &Bookmark) -> Vec { match bookmark.mode.trim().to_ascii_uppercase().as_str() { "AIS" => vec!["ais".to_string()], - "PKT" => vec!["aprs".to_string()], + "PKT" | "FM" => vec!["aprs".to_string()], _ => Vec::new(), } } diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs index 443e703..1d680f9 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs +++ b/src/trx-client/trx-frontend/trx-frontend-http/src/scheduler.rs @@ -966,7 +966,8 @@ async fn apply_scheduler_decoders( bookmark: &crate::server::bookmarks::Bookmark, extra_bookmarks: &[crate::server::bookmarks::Bookmark], ) { - let mut want_aprs = bookmark.mode.trim().eq_ignore_ascii_case("PKT"); + let mut want_aprs = bookmark.mode.trim().eq_ignore_ascii_case("PKT") + || bookmark.mode.trim().eq_ignore_ascii_case("FM"); let mut want_hf_aprs = false; let mut want_ft8 = false; let mut want_ft4 = false; diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/vchan.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/vchan.rs index 1d45b1b..dadceee 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/src/vchan.rs +++ b/src/trx-client/trx-frontend/trx-frontend-http/src/vchan.rs @@ -723,7 +723,7 @@ mod tests { mgr.init_rig(rig_id, 14_074_000, "USB"); let channel = mgr - .allocate(session_id, rig_id, 14_075_000, "DIG") + .allocate(session_id, rig_id, 14_075_000, "USB") .expect("allocate vchan"); assert_eq!(mgr.channels(rig_id).len(), 2); @@ -747,7 +747,7 @@ mod tests { &[( "bm-ft8".to_string(), 14_074_000, - "DIG".to_string(), + "USB".to_string(), 3_000, vec!["ft8".to_string()], )], @@ -756,7 +756,7 @@ mod tests { let channels = mgr.channels(rig_id); assert_eq!(channels.len(), 2); assert_eq!(channels[1].freq_hz, 14_074_000); - assert_eq!(channels[1].mode, "DIG"); + assert_eq!(channels[1].mode, "USB"); assert_eq!(channels[1].bandwidth_hz, 3_000); assert_eq!(channels[1].subscribers, 0); assert!(channels[1].permanent); @@ -770,14 +770,14 @@ mod tests { mgr.init_rig(rig_id, 14_074_000, "USB"); let _channel = mgr - .allocate(session_id, rig_id, 14_075_000, "DIG") + .allocate(session_id, rig_id, 14_075_000, "USB") .expect("allocate vchan"); mgr.sync_scheduler_channels( rig_id, &[( "bm-ft8".to_string(), 14_074_000, - "DIG".to_string(), + "USB".to_string(), 3_000, vec!["ft8".to_string()], )], @@ -787,7 +787,7 @@ mod tests { let channels = mgr.channels(rig_id); assert_eq!(channels.len(), 2); - assert_eq!(channels[1].mode, "DIG"); + assert_eq!(channels[1].mode, "USB"); assert_eq!(channels[1].subscribers, 0); } @@ -803,7 +803,7 @@ mod tests { &[( "bm-aprs".to_string(), 144_800_000, - "PKT".to_string(), + "FM".to_string(), 12_500, vec!["aprs".to_string()], )], diff --git a/src/trx-server/src/audio.rs b/src/trx-server/src/audio.rs index a852fb2..a22e2d0 100644 --- a/src/trx-server/src/audio.rs +++ b/src/trx-server/src/audio.rs @@ -1183,7 +1183,7 @@ fn run_playback( } } -/// Run the APRS decoder task. Only processes PCM when rig mode is PKT. +/// Run the APRS decoder task. Only processes PCM when rig mode is FM or PKT. pub async fn run_aprs_decoder( sample_rate: u32, channels: u16, @@ -1257,9 +1257,9 @@ async fn run_aprs_decoder_inner( let mode_match = |state: &RigState| -> bool { if is_hf { - matches!(state.status.mode, RigMode::DIG) + matches!(state.status.mode, RigMode::USB | RigMode::DIG) } else { - matches!(state.status.mode, RigMode::PKT) + matches!(state.status.mode, RigMode::FM | RigMode::PKT) } }; let get_reset_seq = |state: &RigState| -> u64 { @@ -1405,14 +1405,14 @@ pub async fn run_ais_decoder( let mut decoder_a = AisDecoder::new(sample_rate); let mut decoder_b = AisDecoder::new(sample_rate); let mut was_active = false; - let mut active = matches!(state_rx.borrow().status.mode, RigMode::AIS); + let mut active = matches!(state_rx.borrow().status.mode, RigMode::AIS | RigMode::FM | RigMode::PKT); loop { if !active { match state_rx.changed().await { Ok(()) => { let state = state_rx.borrow(); - active = matches!(state.status.mode, RigMode::AIS); + active = matches!(state.status.mode, RigMode::AIS | RigMode::FM | RigMode::PKT); if active { pcm_a_rx = pcm_a_rx.resubscribe(); pcm_b_rx = pcm_b_rx.resubscribe(); @@ -1476,7 +1476,7 @@ pub async fn run_ais_decoder( match changed { Ok(()) => { let state = state_rx.borrow(); - active = matches!(state.status.mode, RigMode::AIS); + active = matches!(state.status.mode, RigMode::AIS | RigMode::FM | RigMode::PKT); if !active && was_active { decoder_a.reset(); decoder_b.reset(); @@ -1505,14 +1505,14 @@ pub async fn run_vdes_decoder( info!("VDES decoder started ({}Hz complex baseband)", sample_rate); let mut decoder = VdesDecoder::new(sample_rate); let mut was_active = false; - let mut active = matches!(state_rx.borrow().status.mode, RigMode::VDES); + let mut active = matches!(state_rx.borrow().status.mode, RigMode::VDES | RigMode::FM); loop { if !active { match state_rx.changed().await { Ok(()) => { let state = state_rx.borrow(); - active = matches!(state.status.mode, RigMode::VDES); + active = matches!(state.status.mode, RigMode::VDES | RigMode::FM); if active { iq_rx = iq_rx.resubscribe(); } @@ -1550,7 +1550,7 @@ pub async fn run_vdes_decoder( match changed { Ok(()) => { let state = state_rx.borrow(); - active = matches!(state.status.mode, RigMode::VDES); + active = matches!(state.status.mode, RigMode::VDES | RigMode::FM); if !active && was_active { decoder.reset(); was_active = false; diff --git a/src/trx-server/trx-backend/trx-backend-soapysdr/src/lib.rs b/src/trx-server/trx-backend/trx-backend-soapysdr/src/lib.rs index 8e1747f..a7cc709 100644 --- a/src/trx-server/trx-backend/trx-backend-soapysdr/src/lib.rs +++ b/src/trx-server/trx-backend/trx-backend-soapysdr/src/lib.rs @@ -158,7 +158,8 @@ impl SoapySdrRig { fn default_bandwidth_for_mode(mode: &RigMode) -> u32 { match mode { RigMode::LSB | RigMode::USB | RigMode::DIG => 3_000, - RigMode::PKT | RigMode::AIS => 25_000, + RigMode::AIS => 25_000, + RigMode::PKT => 25_000, RigMode::VDES => 100_000, RigMode::CW | RigMode::CWR => 500, RigMode::AM | RigMode::SAM => 9_000, @@ -317,8 +318,6 @@ impl SoapySdrRig { RigMode::FM, RigMode::AIS, RigMode::VDES, - RigMode::DIG, - RigMode::PKT, ], num_vfos: 1, lock: false, diff --git a/src/trx-server/trx-backend/trx-backend-soapysdr/src/vchan_impl.rs b/src/trx-server/trx-backend/trx-backend-soapysdr/src/vchan_impl.rs index 5b5f2ca..57ca675 100644 --- a/src/trx-server/trx-backend/trx-backend-soapysdr/src/vchan_impl.rs +++ b/src/trx-server/trx-backend/trx-backend-soapysdr/src/vchan_impl.rs @@ -504,7 +504,7 @@ mod tests { mgr.add_channel(14_074_000, &RigMode::USB).unwrap(); let hidden_id = Uuid::new_v4(); - mgr.ensure_background_channel_pcm(hidden_id, 14_075_000, &RigMode::DIG) + mgr.ensure_background_channel_pcm(hidden_id, 14_075_000, &RigMode::USB) .unwrap(); let visible = mgr.channels();