[fix](trx-server): gate aprs decode strictly by mode

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
This commit is contained in:
2026-02-09 19:48:55 +01:00
parent af9b44f4d4
commit 3dbf590472
+47 -14
View File
@@ -315,36 +315,45 @@ pub async fn run_aprs_decoder(
sample_rate: u32, sample_rate: u32,
channels: u16, channels: u16,
mut pcm_rx: broadcast::Receiver<Vec<f32>>, mut pcm_rx: broadcast::Receiver<Vec<f32>>,
state_rx: watch::Receiver<RigState>, mut state_rx: watch::Receiver<RigState>,
decode_tx: broadcast::Sender<DecodedMessage>, decode_tx: broadcast::Sender<DecodedMessage>,
) { ) {
info!("APRS decoder started ({}Hz, {} ch)", sample_rate, channels); info!("APRS decoder started ({}Hz, {} ch)", sample_rate, channels);
let mut decoder = decode::aprs::AprsDecoder::new(sample_rate); let mut decoder = decode::aprs::AprsDecoder::new(sample_rate);
let mut was_active = false; let mut was_active = false;
let mut last_reset_seq: u64 = 0; let mut last_reset_seq: u64 = 0;
let mut active = matches!(state_rx.borrow().status.mode, RigMode::PKT);
loop { loop {
match pcm_rx.recv().await { if !active {
Ok(frame) => { match state_rx.changed().await {
let state = state_rx.borrow().clone(); Ok(()) => {
let mode = &state.status.mode; let state = state_rx.borrow();
let active = matches!(mode, RigMode::PKT); active = matches!(state.status.mode, RigMode::PKT);
if active {
// Check for reset request pcm_rx = pcm_rx.resubscribe();
}
if state.aprs_decode_reset_seq != last_reset_seq { if state.aprs_decode_reset_seq != last_reset_seq {
last_reset_seq = state.aprs_decode_reset_seq; last_reset_seq = state.aprs_decode_reset_seq;
decoder.reset(); decoder.reset();
info!("APRS decoder reset (seq={})", last_reset_seq); info!("APRS decoder reset (seq={})", last_reset_seq);
} }
}
if !active { Err(_) => break,
if was_active {
decoder.reset();
was_active = false;
} }
continue; continue;
} }
was_active = true;
tokio::select! {
recv = pcm_rx.recv() => {
match recv {
Ok(frame) => {
let state = state_rx.borrow();
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);
}
// Downmix to mono if stereo // Downmix to mono if stereo
let mono = if channels > 1 { let mono = if channels > 1 {
@@ -358,6 +367,7 @@ pub async fn run_aprs_decoder(
frame frame
}; };
was_active = true;
for pkt in decoder.process_samples(&mono) { for pkt in decoder.process_samples(&mono) {
record_aprs_packet(pkt.clone()); record_aprs_packet(pkt.clone());
let _ = decode_tx.send(DecodedMessage::Aprs(pkt)); let _ = decode_tx.send(DecodedMessage::Aprs(pkt));
@@ -369,6 +379,29 @@ pub async fn run_aprs_decoder(
Err(broadcast::error::RecvError::Closed) => break, Err(broadcast::error::RecvError::Closed) => break,
} }
} }
changed = state_rx.changed() => {
match changed {
Ok(()) => {
let state = state_rx.borrow();
active = matches!(state.status.mode, RigMode::PKT);
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 && was_active {
decoder.reset();
was_active = false;
}
if active {
pcm_rx = pcm_rx.resubscribe();
}
}
Err(_) => break,
}
}
}
}
} }
/// Run the CW decoder task. Only processes PCM when rig mode is CW or CWR. /// Run the CW decoder task. Only processes PCM when rig mode is CW or CWR.