[feat](trx-client): relay server-side decoded messages to frontends

Handle APRS/CW decode message types (0x03/0x04) in audio_client,
deserialize and forward via broadcast channel.  Create decode channel
and pass to audio client and HTTP frontend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
This commit is contained in:
2026-02-08 22:28:48 +01:00
parent f7f0e46021
commit 50e1c44722
2 changed files with 17 additions and 4 deletions
+12 -3
View File
@@ -15,9 +15,10 @@ use tokio::time;
use tracing::{info, warn};
use trx_core::audio::{
read_audio_msg, write_audio_msg, AudioStreamInfo, AUDIO_MSG_RX_FRAME, AUDIO_MSG_STREAM_INFO,
AUDIO_MSG_TX_FRAME,
read_audio_msg, write_audio_msg, AudioStreamInfo, AUDIO_MSG_APRS_DECODE,
AUDIO_MSG_CW_DECODE, AUDIO_MSG_RX_FRAME, AUDIO_MSG_STREAM_INFO, AUDIO_MSG_TX_FRAME,
};
use trx_core::decode::DecodedMessage;
/// Run the audio client with auto-reconnect.
pub async fn run_audio_client(
@@ -25,6 +26,7 @@ pub async fn run_audio_client(
rx_tx: broadcast::Sender<Bytes>,
mut tx_rx: mpsc::Receiver<Bytes>,
stream_info_tx: watch::Sender<Option<AudioStreamInfo>>,
decode_tx: broadcast::Sender<DecodedMessage>,
) {
let mut reconnect_delay = Duration::from_secs(1);
@@ -34,7 +36,7 @@ pub async fn run_audio_client(
Ok(stream) => {
reconnect_delay = Duration::from_secs(1);
if let Err(e) =
handle_audio_connection(stream, &rx_tx, &mut tx_rx, &stream_info_tx).await
handle_audio_connection(stream, &rx_tx, &mut tx_rx, &stream_info_tx, &decode_tx).await
{
warn!("Audio connection dropped: {}", e);
}
@@ -55,6 +57,7 @@ async fn handle_audio_connection(
rx_tx: &broadcast::Sender<Bytes>,
tx_rx: &mut mpsc::Receiver<Bytes>,
stream_info_tx: &watch::Sender<Option<AudioStreamInfo>>,
decode_tx: &broadcast::Sender<DecodedMessage>,
) -> std::io::Result<()> {
let (reader, writer) = stream.into_split();
let mut reader = BufReader::new(reader);
@@ -78,12 +81,18 @@ async fn handle_audio_connection(
// Spawn RX read task
let rx_tx = rx_tx.clone();
let decode_tx = decode_tx.clone();
let mut rx_handle = tokio::spawn(async move {
loop {
match read_audio_msg(&mut reader).await {
Ok((AUDIO_MSG_RX_FRAME, payload)) => {
let _ = rx_tx.send(Bytes::from(payload));
}
Ok((AUDIO_MSG_APRS_DECODE | AUDIO_MSG_CW_DECODE, payload)) => {
if let Ok(msg) = serde_json::from_slice::<DecodedMessage>(&payload) {
let _ = decode_tx.send(msg);
}
}
Ok((msg_type, _)) => {
warn!("Audio client: unexpected message type {}", msg_type);
}