From 042aab7199b72440f71ef561b3bf635fafb1c48e Mon Sep 17 00:00:00 2001 From: Stanislaw Grams Date: Sun, 8 Feb 2026 22:28:34 +0100 Subject: [PATCH] [feat](trx-core): add decode types and wire protocol for APRS/CW Add shared DecodedMessage enum (tagged serde), AprsPacket and CwEvent types for server-side decoding. Add AUDIO_MSG_APRS_DECODE (0x03) and AUDIO_MSG_CW_DECODE (0x04) wire protocol constants. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Stanislaw Grams --- src/trx-core/src/audio.rs | 2 ++ src/trx-core/src/decode.rs | 48 ++++++++++++++++++++++++++++++++++++++ src/trx-core/src/lib.rs | 1 + 3 files changed, 51 insertions(+) create mode 100644 src/trx-core/src/decode.rs diff --git a/src/trx-core/src/audio.rs b/src/trx-core/src/audio.rs index 831e3b8..80fce12 100644 --- a/src/trx-core/src/audio.rs +++ b/src/trx-core/src/audio.rs @@ -11,6 +11,8 @@ use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; pub const AUDIO_MSG_STREAM_INFO: u8 = 0x00; pub const AUDIO_MSG_RX_FRAME: u8 = 0x01; pub const AUDIO_MSG_TX_FRAME: u8 = 0x02; +pub const AUDIO_MSG_APRS_DECODE: u8 = 0x03; +pub const AUDIO_MSG_CW_DECODE: u8 = 0x04; /// Maximum payload size (1 MB) to reject bogus frames early. const MAX_PAYLOAD_SIZE: u32 = 1_048_576; diff --git a/src/trx-core/src/decode.rs b/src/trx-core/src/decode.rs new file mode 100644 index 0000000..6f2de4d --- /dev/null +++ b/src/trx-core/src/decode.rs @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2025 Stanislaw Grams +// +// SPDX-License-Identifier: BSD-2-Clause + +//! Shared types for server-side decoded messages (APRS, CW). + +use serde::{Deserialize, Serialize}; + +/// A decoded message from the server-side decoders. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(tag = "type")] +pub enum DecodedMessage { + #[serde(rename = "aprs")] + Aprs(AprsPacket), + #[serde(rename = "cw")] + Cw(CwEvent), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AprsPacket { + pub src_call: String, + pub dest_call: String, + pub path: String, + pub info: String, + #[serde(rename = "type")] + pub packet_type: String, + pub crc_ok: bool, + #[serde(skip_serializing_if = "Option::is_none")] + pub lat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub lon: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub symbol_table: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub symbol_code: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CwEvent { + /// Decoded text fragment (one or more characters) + pub text: String, + /// Current detected WPM + pub wpm: u32, + /// Current detected tone frequency (Hz) + pub tone_hz: u32, + /// Whether a CW tone is currently detected + pub signal_on: bool, +} diff --git a/src/trx-core/src/lib.rs b/src/trx-core/src/lib.rs index 07346d3..c8b22ae 100644 --- a/src/trx-core/src/lib.rs +++ b/src/trx-core/src/lib.rs @@ -4,6 +4,7 @@ pub mod audio; pub mod client; +pub mod decode; pub mod math; pub mod radio; pub mod rig;