diff --git a/src/trx-server/src/audio.rs b/src/trx-server/src/audio.rs index 16d10d9..f8bb378 100644 --- a/src/trx-server/src/audio.rs +++ b/src/trx-server/src/audio.rs @@ -283,12 +283,22 @@ pub async fn run_aprs_decoder( info!("APRS decoder started ({}Hz, {} ch)", sample_rate, channels); let mut decoder = decode::aprs::AprsDecoder::new(sample_rate); let mut was_active = false; + let mut last_reset_seq: u64 = 0; loop { match pcm_rx.recv().await { Ok(frame) => { - let mode = &state_rx.borrow().status.mode; - let active = matches!(mode, RigMode::PKT); + let state = state_rx.borrow().clone(); + let mode = &state.status.mode; + let enabled = state.aprs_decode_enabled; + let active = enabled && matches!(mode, RigMode::PKT); + + // Check for reset request + if state.aprs_decode_reset_seq != last_reset_seq { + last_reset_seq = state.aprs_decode_reset_seq; + decoder.reset(); + info!("APRS decoder reset (seq={})", last_reset_seq); + } if !active { if was_active { @@ -334,12 +344,22 @@ pub async fn run_cw_decoder( info!("CW decoder started ({}Hz, {} ch)", sample_rate, channels); let mut decoder = decode::cw::CwDecoder::new(sample_rate); let mut was_active = false; + let mut last_reset_seq: u64 = 0; loop { match pcm_rx.recv().await { Ok(frame) => { - let mode = &state_rx.borrow().status.mode; - let active = matches!(mode, RigMode::CW | RigMode::CWR); + let state = state_rx.borrow().clone(); + let mode = &state.status.mode; + let enabled = state.cw_decode_enabled; + let active = enabled && matches!(mode, RigMode::CW | RigMode::CWR); + + // Check for reset request + if state.cw_decode_reset_seq != last_reset_seq { + last_reset_seq = state.cw_decode_reset_seq; + decoder.reset(); + info!("CW decoder reset (seq={})", last_reset_seq); + } if !active { if was_active { diff --git a/src/trx-server/src/listener.rs b/src/trx-server/src/listener.rs index d0d7fbb..1cc1653 100644 --- a/src/trx-server/src/listener.rs +++ b/src/trx-server/src/listener.rs @@ -188,6 +188,10 @@ fn map_command(cmd: ClientCommand) -> RigCommand { ClientCommand::Unlock => RigCommand::Unlock, ClientCommand::GetTxLimit => RigCommand::GetTxLimit, ClientCommand::SetTxLimit { limit } => RigCommand::SetTxLimit(limit), + ClientCommand::SetAprsDecodeEnabled { enabled } => RigCommand::SetAprsDecodeEnabled(enabled), + ClientCommand::SetCwDecodeEnabled { enabled } => RigCommand::SetCwDecodeEnabled(enabled), + ClientCommand::ResetAprsDecoder => RigCommand::ResetAprsDecoder, + ClientCommand::ResetCwDecoder => RigCommand::ResetCwDecoder, } } diff --git a/src/trx-server/src/main.rs b/src/trx-server/src/main.rs index 90360d9..b2021f8 100644 --- a/src/trx-server/src/main.rs +++ b/src/trx-server/src/main.rs @@ -222,6 +222,10 @@ fn build_initial_state(cfg: &ServerConfig, resolved: &ResolvedConfig) -> RigStat server_version: Some(env!("CARGO_PKG_VERSION").to_string()), server_latitude: resolved.latitude, server_longitude: resolved.longitude, + aprs_decode_enabled: false, + cw_decode_enabled: false, + aprs_decode_reset_seq: 0, + cw_decode_reset_seq: 0, } } diff --git a/src/trx-server/src/rig_task.rs b/src/trx-server/src/rig_task.rs index 729a539..eeef560 100644 --- a/src/trx-server/src/rig_task.rs +++ b/src/trx-server/src/rig_task.rs @@ -122,6 +122,10 @@ pub async fn run_rig_task( server_version, server_latitude, server_longitude, + aprs_decode_enabled: false, + cw_decode_enabled: false, + aprs_decode_reset_seq: 0, + cw_decode_reset_seq: 0, }; // Polling configuration @@ -343,6 +347,31 @@ async fn process_command( cmd: RigCommand, ctx: &mut CommandExecContext<'_>, ) -> RigResult { + // Handle decoder commands early — they don't touch the rig CAT. + match cmd { + RigCommand::SetAprsDecodeEnabled(en) => { + ctx.state.aprs_decode_enabled = en; + let _ = ctx.state_tx.send(ctx.state.clone()); + return snapshot_from(ctx.state); + } + RigCommand::SetCwDecodeEnabled(en) => { + ctx.state.cw_decode_enabled = en; + let _ = ctx.state_tx.send(ctx.state.clone()); + return snapshot_from(ctx.state); + } + RigCommand::ResetAprsDecoder => { + ctx.state.aprs_decode_reset_seq += 1; + let _ = ctx.state_tx.send(ctx.state.clone()); + return snapshot_from(ctx.state); + } + RigCommand::ResetCwDecoder => { + ctx.state.cw_decode_reset_seq += 1; + let _ = ctx.state_tx.send(ctx.state.clone()); + return snapshot_from(ctx.state); + } + _ => {} // fall through to normal rig handler + } + sync_machine_state(ctx.machine, ctx.state); // Check if rig is ready for commands