[refactor](trx-server): route SDR commands through RigCat::as_sdr()

Update all SDR command handlers in rig_task to access SDR methods via
ctx.rig.as_sdr() instead of calling them directly on RigCat. Query-only
SDR operations (filter_state, get_spectrum, get_vchan_rds) use
as_sdr_ref(). Non-SDR rigs now get proper not_supported errors.

https://claude.ai/code/session_01XzurkeuUmamBuhQwxVy7T4
Signed-off-by: Claude <noreply@anthropic.com>
This commit is contained in:
Claude
2026-03-26 06:41:46 +00:00
committed by Stan Grams
parent 74749bc6de
commit 748d26f47d
+63 -41
View File
@@ -21,7 +21,7 @@ use trx_core::rig::controller::{
}; };
use trx_core::rig::request::RigRequest; use trx_core::rig::request::RigRequest;
use trx_core::rig::state::{RigMode, RigSnapshot, RigState}; use trx_core::rig::state::{RigMode, RigSnapshot, RigState};
use trx_core::rig::{RigCat, RigRxStatus, RigTxStatus}; use trx_core::rig::{RigCat, RigRxStatus, RigSdr, RigTxStatus};
use trx_core::{DynResult, RigError, RigResult}; use trx_core::{DynResult, RigError, RigResult};
use crate::audio::DecoderHistories; use crate::audio::DecoderHistories;
@@ -153,7 +153,7 @@ pub async fn run_rig_task(
// Initial setup: get rig info // Initial setup: get rig info
let rig_info = rig.info().clone(); let rig_info = rig.info().clone();
state.rig_info = Some(rig_info); state.rig_info = Some(rig_info);
state.filter = rig.filter_state(); state.filter = rig.as_sdr_ref().and_then(|s| s.filter_state());
if let Some(info) = state.rig_info.as_ref() { if let Some(info) = state.rig_info.as_ref() {
info!( info!(
"Rig info: {} {} {}", "Rig info: {} {} {}",
@@ -546,8 +546,12 @@ async fn process_command(
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetBandwidth(hz) => { RigCommand::SetBandwidth(hz) => {
if let Err(e) = ctx.rig.set_bandwidth(hz).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_bandwidth: {e}"))); if let Err(e) = sdr.set_bandwidth(hz).await {
return Err(RigError::communication(format!("set_bandwidth: {e}")));
}
} else {
return Err(RigError::not_supported("set_bandwidth"));
} }
if let Some(f) = ctx.state.filter.as_mut() { if let Some(f) = ctx.state.filter.as_mut() {
f.bandwidth_hz = hz; f.bandwidth_hz = hz;
@@ -556,26 +560,32 @@ async fn process_command(
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetSdrGain(gain_db) => { RigCommand::SetSdrGain(gain_db) => {
if let Err(e) = ctx.rig.set_sdr_gain(gain_db).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_sdr_gain: {e}"))); if let Err(e) = sdr.set_sdr_gain(gain_db).await {
} return Err(RigError::communication(format!("set_sdr_gain: {e}")));
ctx.state.filter = ctx.rig.filter_state(); }
} else { return Err(RigError::not_supported("set_sdr_gain")); }
ctx.state.filter = ctx.rig.as_sdr_ref().and_then(|s| s.filter_state());
let _ = ctx.state_tx.send(ctx.state.clone()); let _ = ctx.state_tx.send(ctx.state.clone());
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetSdrLnaGain(gain_db) => { RigCommand::SetSdrLnaGain(gain_db) => {
if let Err(e) = ctx.rig.set_sdr_lna_gain(gain_db).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_sdr_lna_gain: {e}"))); if let Err(e) = sdr.set_sdr_lna_gain(gain_db).await {
} return Err(RigError::communication(format!("set_sdr_lna_gain: {e}")));
ctx.state.filter = ctx.rig.filter_state(); }
} else { return Err(RigError::not_supported("set_sdr_lna_gain")); }
ctx.state.filter = ctx.rig.as_sdr_ref().and_then(|s| s.filter_state());
let _ = ctx.state_tx.send(ctx.state.clone()); let _ = ctx.state_tx.send(ctx.state.clone());
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetSdrAgc(enabled) => { RigCommand::SetSdrAgc(enabled) => {
if let Err(e) = ctx.rig.set_sdr_agc(enabled).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_sdr_agc: {e}"))); if let Err(e) = sdr.set_sdr_agc(enabled).await {
} return Err(RigError::communication(format!("set_sdr_agc: {e}")));
ctx.state.filter = ctx.rig.filter_state(); }
} else { return Err(RigError::not_supported("set_sdr_agc")); }
ctx.state.filter = ctx.rig.as_sdr_ref().and_then(|s| s.filter_state());
let _ = ctx.state_tx.send(ctx.state.clone()); let _ = ctx.state_tx.send(ctx.state.clone());
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
@@ -583,27 +593,33 @@ async fn process_command(
enabled, enabled,
threshold_db, threshold_db,
} => { } => {
if let Err(e) = ctx.rig.set_sdr_squelch(enabled, threshold_db).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_sdr_squelch: {e}"))); if let Err(e) = sdr.set_sdr_squelch(enabled, threshold_db).await {
} return Err(RigError::communication(format!("set_sdr_squelch: {e}")));
ctx.state.filter = ctx.rig.filter_state(); }
} else { return Err(RigError::not_supported("set_sdr_squelch")); }
ctx.state.filter = ctx.rig.as_sdr_ref().and_then(|s| s.filter_state());
let _ = ctx.state_tx.send(ctx.state.clone()); let _ = ctx.state_tx.send(ctx.state.clone());
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetSdrNoiseBlanker { enabled, threshold } => { RigCommand::SetSdrNoiseBlanker { enabled, threshold } => {
if let Err(e) = ctx.rig.set_sdr_noise_blanker(enabled, threshold).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!( if let Err(e) = sdr.set_sdr_noise_blanker(enabled, threshold).await {
"set_sdr_noise_blanker: {e}" return Err(RigError::communication(format!(
))); "set_sdr_noise_blanker: {e}"
} )));
ctx.state.filter = ctx.rig.filter_state(); }
} else { return Err(RigError::not_supported("set_sdr_noise_blanker")); }
ctx.state.filter = ctx.rig.as_sdr_ref().and_then(|s| s.filter_state());
let _ = ctx.state_tx.send(ctx.state.clone()); let _ = ctx.state_tx.send(ctx.state.clone());
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetWfmDeemphasis(deemphasis_us) => { RigCommand::SetWfmDeemphasis(deemphasis_us) => {
if let Err(e) = ctx.rig.set_wfm_deemphasis(deemphasis_us).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_wfm_deemphasis: {e}"))); if let Err(e) = sdr.set_wfm_deemphasis(deemphasis_us).await {
} return Err(RigError::communication(format!("set_wfm_deemphasis: {e}")));
}
} else { return Err(RigError::not_supported("set_wfm_deemphasis")); }
if let Some(f) = ctx.state.filter.as_mut() { if let Some(f) = ctx.state.filter.as_mut() {
f.wfm_deemphasis_us = deemphasis_us; f.wfm_deemphasis_us = deemphasis_us;
} }
@@ -611,9 +627,11 @@ async fn process_command(
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetWfmStereo(enabled) => { RigCommand::SetWfmStereo(enabled) => {
if let Err(e) = ctx.rig.set_wfm_stereo(enabled).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_wfm_stereo: {e}"))); if let Err(e) = sdr.set_wfm_stereo(enabled).await {
} return Err(RigError::communication(format!("set_wfm_stereo: {e}")));
}
} else { return Err(RigError::not_supported("set_wfm_stereo")); }
if let Some(f) = ctx.state.filter.as_mut() { if let Some(f) = ctx.state.filter.as_mut() {
f.wfm_stereo = enabled; f.wfm_stereo = enabled;
} }
@@ -621,9 +639,11 @@ async fn process_command(
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetWfmDenoise(level) => { RigCommand::SetWfmDenoise(level) => {
if let Err(e) = ctx.rig.set_wfm_denoise(level).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_wfm_denoise: {e}"))); if let Err(e) = sdr.set_wfm_denoise(level).await {
} return Err(RigError::communication(format!("set_wfm_denoise: {e}")));
}
} else { return Err(RigError::not_supported("set_wfm_denoise")); }
if let Some(f) = ctx.state.filter.as_mut() { if let Some(f) = ctx.state.filter.as_mut() {
f.wfm_denoise = level; f.wfm_denoise = level;
} }
@@ -631,16 +651,18 @@ async fn process_command(
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::SetCenterFreq(freq) => { RigCommand::SetCenterFreq(freq) => {
if let Err(e) = ctx.rig.set_center_freq(freq).await { if let Some(sdr) = ctx.rig.as_sdr() {
return Err(RigError::communication(format!("set_center_freq: {e}"))); if let Err(e) = sdr.set_center_freq(freq).await {
} return Err(RigError::communication(format!("set_center_freq: {e}")));
}
} else { return Err(RigError::not_supported("set_center_freq")); }
*ctx.poll_pause_until = Some(Instant::now() + Duration::from_millis(200)); *ctx.poll_pause_until = Some(Instant::now() + Duration::from_millis(200));
return snapshot_from(ctx.state); return snapshot_from(ctx.state);
} }
RigCommand::GetSpectrum => { RigCommand::GetSpectrum => {
// Fetch current spectrum and embed it in a one-shot snapshot. // Fetch current spectrum and embed it in a one-shot snapshot.
ctx.state.spectrum = ctx.rig.get_spectrum(); ctx.state.spectrum = ctx.rig.as_sdr_ref().and_then(|s| s.get_spectrum());
ctx.state.vchan_rds = ctx.rig.get_vchan_rds(); ctx.state.vchan_rds = ctx.rig.as_sdr_ref().and_then(|s| s.get_vchan_rds());
let result = snapshot_from(ctx.state); let result = snapshot_from(ctx.state);
ctx.state.spectrum = None; // don't persist in ongoing state ctx.state.spectrum = None; // don't persist in ongoing state
ctx.state.vchan_rds = None; // don't persist in ongoing state ctx.state.vchan_rds = None; // don't persist in ongoing state
@@ -806,7 +828,7 @@ async fn refresh_state_with_retry(
/// Read current state from the rig via CAT. /// Read current state from the rig via CAT.
async fn refresh_state_from_cat(rig: &mut Box<dyn RigCat>, state: &mut RigState) -> DynResult<()> { async fn refresh_state_from_cat(rig: &mut Box<dyn RigCat>, state: &mut RigState) -> DynResult<()> {
let (freq, mode, vfo) = rig.get_status().await?; let (freq, mode, vfo) = rig.get_status().await?;
state.filter = rig.filter_state(); state.filter = rig.as_sdr_ref().and_then(|s| s.filter_state());
state.control.enabled = Some(true); state.control.enabled = Some(true);
let prev_freq_hz = state.status.freq.hz; let prev_freq_hz = state.status.freq.hz;
state.apply_freq(freq); state.apply_freq(freq);