From 9177206dd9c4977f01b282f6b52fc6ca72be8ec2 Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Wed, 25 Feb 2026 20:24:43 +0100 Subject: [PATCH] [feat](trx-core): add capability flags and filter state for UI gating Add five new boolean fields to RigCapabilities: tx, tx_limit, vfo_switch, filter_controls, signal_meter. These drive which controls the HTTP frontend shows or hides per rig type. Add RigFilterState struct (bandwidth_hz, fir_taps, cw_center_hz) and filter: Option to both RigState (skip-serialized) and RigSnapshot (skip_serializing_if = None). Add SetBandwidth and SetFirTaps to RigCommand; add default not-supported implementations of set_bandwidth, set_fir_taps, and filter_state to the RigCat trait. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Stan Grams --- src/trx-core/src/lib.rs | 2 +- src/trx-core/src/rig/command.rs | 2 ++ src/trx-core/src/rig/controller/handlers.rs | 14 +++++++++- src/trx-core/src/rig/controller/machine.rs | 5 ++++ src/trx-core/src/rig/mod.rs | 31 +++++++++++++++++++++ src/trx-core/src/rig/state.rs | 17 +++++++++++ 6 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/trx-core/src/lib.rs b/src/trx-core/src/lib.rs index 70e8e92..125c426 100644 --- a/src/trx-core/src/lib.rs +++ b/src/trx-core/src/lib.rs @@ -14,4 +14,4 @@ pub use rig::AudioSource; pub use rig::command::RigCommand; pub use rig::request::RigRequest; pub use rig::response::{RigError, RigResult}; -pub use rig::state::{RigMode, RigSnapshot, RigState}; +pub use rig::state::{RigFilterState, RigMode, RigSnapshot, RigState}; diff --git a/src/trx-core/src/rig/command.rs b/src/trx-core/src/rig/command.rs index 06d776e..e412ab0 100644 --- a/src/trx-core/src/rig/command.rs +++ b/src/trx-core/src/rig/command.rs @@ -30,4 +30,6 @@ pub enum RigCommand { ResetCwDecoder, ResetFt8Decoder, ResetWsprDecoder, + SetBandwidth(u32), + SetFirTaps(u32), } diff --git a/src/trx-core/src/rig/controller/handlers.rs b/src/trx-core/src/rig/controller/handlers.rs index 0854dd0..a6ddf26 100644 --- a/src/trx-core/src/rig/controller/handlers.rs +++ b/src/trx-core/src/rig/controller/handlers.rs @@ -512,7 +512,9 @@ pub fn command_from_rig_command(cmd: RigCommand) -> Box { | RigCommand::ResetAprsDecoder | RigCommand::ResetCwDecoder | RigCommand::ResetFt8Decoder - | RigCommand::ResetWsprDecoder => Box::new(GetSnapshotCommand), + | RigCommand::ResetWsprDecoder + | RigCommand::SetBandwidth(_) + | RigCommand::SetFirTaps(_) => Box::new(GetSnapshotCommand), } } @@ -553,6 +555,11 @@ mod tests { rit: false, rpt: false, split: false, + tx: true, + tx_limit: true, + vfo_switch: true, + filter_controls: false, + signal_meter: true, }, access: RigAccessMethod::Serial { path: "/dev/test".to_string(), @@ -607,6 +614,11 @@ mod tests { rit: false, rpt: false, split: false, + tx: true, + tx_limit: true, + vfo_switch: true, + filter_controls: false, + signal_meter: true, }, access: RigAccessMethod::Serial { path: "/dev/test".to_string(), diff --git a/src/trx-core/src/rig/controller/machine.rs b/src/trx-core/src/rig/controller/machine.rs index 6257a30..9b4b55d 100644 --- a/src/trx-core/src/rig/controller/machine.rs +++ b/src/trx-core/src/rig/controller/machine.rs @@ -450,6 +450,11 @@ mod tests { rit: false, rpt: false, split: false, + tx: true, + tx_limit: true, + vfo_switch: true, + filter_controls: false, + signal_meter: true, }, access: RigAccessMethod::Serial { path: "/dev/test".to_string(), diff --git a/src/trx-core/src/rig/mod.rs b/src/trx-core/src/rig/mod.rs index dbfaf5f..dc24c46 100644 --- a/src/trx-core/src/rig/mod.rs +++ b/src/trx-core/src/rig/mod.rs @@ -51,6 +51,16 @@ pub struct RigCapabilities { pub rit: bool, pub rpt: bool, pub split: bool, + /// Backend supports transmit: PTT, power on/off, TX meters, TX audio. + pub tx: bool, + /// Backend supports get_tx_limit / set_tx_limit. + pub tx_limit: bool, + /// Backend supports toggle_vfo. + pub vfo_switch: bool, + /// Backend supports runtime filter adjustment (bandwidth, FIR taps). + pub filter_controls: bool, + /// Backend returns a meaningful RX signal strength value. + pub signal_meter: bool, } fn default_min_freq_step_hz() -> u64 { @@ -112,6 +122,27 @@ pub trait RigCat: Rig + Send { fn unlock<'a>(&'a mut self) -> Pin> + Send + 'a>>; fn as_audio_source(&self) -> Option<&dyn AudioSource> { None } + + fn set_bandwidth<'a>( + &'a mut self, + _bandwidth_hz: u32, + ) -> Pin> + Send + 'a>> { + Box::pin(std::future::ready(Err(Box::new( + response::RigError::not_supported("set_bandwidth"), + ) as Box))) + } + + fn set_fir_taps<'a>( + &'a mut self, + _taps: u32, + ) -> Pin> + Send + 'a>> { + Box::pin(std::future::ready(Err(Box::new( + response::RigError::not_supported("set_fir_taps"), + ) as Box))) + } + + /// Return the current filter state if this backend supports filter controls. + fn filter_state(&self) -> Option { None } } /// Snapshot of a rig's status that every backend can expose. diff --git a/src/trx-core/src/rig/state.rs b/src/trx-core/src/rig/state.rs index 709f26f..3c8f47e 100644 --- a/src/trx-core/src/rig/state.rs +++ b/src/trx-core/src/rig/state.rs @@ -42,6 +42,10 @@ pub struct RigState { pub cw_wpm: u32, #[serde(default)] pub cw_tone_hz: u32, + /// Filter state for backends that support runtime filter adjustment. + /// Skipped in serde; flows into RigSnapshot via snapshot(). + #[serde(skip)] + pub filter: Option, #[serde(default, skip_serializing)] pub aprs_decode_reset_seq: u64, #[serde(default, skip_serializing)] @@ -127,6 +131,7 @@ impl RigState { cw_auto: true, cw_wpm: 15, cw_tone_hz: 700, + filter: None, aprs_decode_reset_seq: 0, cw_decode_reset_seq: 0, ft8_decode_reset_seq: 0, @@ -186,6 +191,7 @@ impl RigState { cw_tone_hz: snapshot.cw_tone_hz, ft8_decode_enabled: snapshot.ft8_decode_enabled, wspr_decode_enabled: snapshot.wspr_decode_enabled, + filter: snapshot.filter, aprs_decode_reset_seq: 0, cw_decode_reset_seq: 0, ft8_decode_reset_seq: 0, @@ -223,6 +229,7 @@ impl RigState { cw_tone_hz: self.cw_tone_hz, ft8_decode_enabled: self.ft8_decode_enabled, wspr_decode_enabled: self.wspr_decode_enabled, + filter: self.filter.clone(), }) } @@ -249,6 +256,14 @@ impl RigState { } } +/// Current filter/DSP state for backends that support runtime filter adjustment. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RigFilterState { + pub bandwidth_hz: u32, + pub fir_taps: u32, + pub cw_center_hz: u32, +} + /// Read-only projection of state shared with clients. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RigSnapshot { @@ -283,4 +298,6 @@ pub struct RigSnapshot { pub cw_wpm: u32, #[serde(default)] pub cw_tone_hz: u32, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub filter: Option, }