[style](trx-server): improve code formatting and remove unused imports
Reformat assertions, multi-line function calls, and error handling for better readability. Remove unused soapysdr feature import in main.rs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,11 @@ pub fn compute_passcode(callsign: &str) -> u16 {
|
|||||||
// Strip SSID
|
// Strip SSID
|
||||||
let base = callsign.split('-').next().unwrap_or(callsign);
|
let base = callsign.split('-').next().unwrap_or(callsign);
|
||||||
// First 10 chars, uppercase
|
// First 10 chars, uppercase
|
||||||
let upper: String = base.chars().take(10).map(|c| c.to_ascii_uppercase()).collect();
|
let upper: String = base
|
||||||
|
.chars()
|
||||||
|
.take(10)
|
||||||
|
.map(|c| c.to_ascii_uppercase())
|
||||||
|
.collect();
|
||||||
let bytes = upper.as_bytes();
|
let bytes = upper.as_bytes();
|
||||||
|
|
||||||
let mut hash: u16 = 0x73e2;
|
let mut hash: u16 = 0x73e2;
|
||||||
@@ -126,7 +130,10 @@ pub async fn run_aprsfi_uplink(
|
|||||||
line.clear();
|
line.clear();
|
||||||
match reader.read_line(&mut line).await {
|
match reader.read_line(&mut line).await {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
warn!("APRS-IS IGate: connection closed before logresp from {}:{}", cfg.host, cfg.port);
|
warn!(
|
||||||
|
"APRS-IS IGate: connection closed before logresp from {}:{}",
|
||||||
|
cfg.host, cfg.port
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
@@ -137,7 +144,10 @@ pub async fn run_aprsfi_uplink(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("APRS-IS IGate: error reading logresp from {}:{}: {}", cfg.host, cfg.port, e);
|
warn!(
|
||||||
|
"APRS-IS IGate: error reading logresp from {}:{}: {}",
|
||||||
|
cfg.host, cfg.port, e
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,18 @@
|
|||||||
|
|
||||||
//! Audio capture, playback, and TCP streaming for trx-server.
|
//! Audio capture, playback, and TCP streaming for trx-server.
|
||||||
|
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::collections::VecDeque;
|
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
use tokio::sync::{broadcast, mpsc, watch};
|
use tokio::sync::{broadcast, mpsc, watch};
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
|
use trx_aprs::AprsDecoder;
|
||||||
use trx_core::audio::{
|
use trx_core::audio::{
|
||||||
read_audio_msg, write_audio_msg, AudioStreamInfo, AUDIO_MSG_APRS_DECODE, AUDIO_MSG_CW_DECODE,
|
read_audio_msg, write_audio_msg, AudioStreamInfo, AUDIO_MSG_APRS_DECODE, AUDIO_MSG_CW_DECODE,
|
||||||
AUDIO_MSG_FT8_DECODE, AUDIO_MSG_RX_FRAME, AUDIO_MSG_STREAM_INFO, AUDIO_MSG_TX_FRAME,
|
AUDIO_MSG_FT8_DECODE, AUDIO_MSG_RX_FRAME, AUDIO_MSG_STREAM_INFO, AUDIO_MSG_TX_FRAME,
|
||||||
@@ -22,7 +23,6 @@ use trx_core::audio::{
|
|||||||
};
|
};
|
||||||
use trx_core::decode::{AprsPacket, DecodedMessage, Ft8Message, WsprMessage};
|
use trx_core::decode::{AprsPacket, DecodedMessage, Ft8Message, WsprMessage};
|
||||||
use trx_core::rig::state::{RigMode, RigState};
|
use trx_core::rig::state::{RigMode, RigState};
|
||||||
use trx_aprs::AprsDecoder;
|
|
||||||
use trx_cw::CwDecoder;
|
use trx_cw::CwDecoder;
|
||||||
use trx_ft8::Ft8Decoder;
|
use trx_ft8::Ft8Decoder;
|
||||||
use trx_wspr::WsprDecoder;
|
use trx_wspr::WsprDecoder;
|
||||||
@@ -164,7 +164,10 @@ impl DecoderHistories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_aprs_history(&self) {
|
pub fn clear_aprs_history(&self) {
|
||||||
self.aprs.lock().expect("aprs history mutex poisoned").clear();
|
self.aprs
|
||||||
|
.lock()
|
||||||
|
.expect("aprs history mutex poisoned")
|
||||||
|
.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- FT8 ---
|
// --- FT8 ---
|
||||||
@@ -222,7 +225,10 @@ impl DecoderHistories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_wspr_history(&self) {
|
pub fn clear_wspr_history(&self) {
|
||||||
self.wspr.lock().expect("wspr history mutex poisoned").clear();
|
self.wspr
|
||||||
|
.lock()
|
||||||
|
.expect("wspr history mutex poisoned")
|
||||||
|
.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +321,10 @@ fn run_capture(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Audio capture: failed to enumerate devices, retrying: {}", e);
|
warn!(
|
||||||
|
"Audio capture: failed to enumerate devices, retrying: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
std::thread::sleep(AUDIO_STREAM_RECOVERY_DELAY);
|
std::thread::sleep(AUDIO_STREAM_RECOVERY_DELAY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -520,7 +529,10 @@ fn run_playback(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Audio playback: failed to enumerate devices, retrying: {}", e);
|
warn!(
|
||||||
|
"Audio playback: failed to enumerate devices, retrying: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
std::thread::sleep(AUDIO_STREAM_RECOVERY_DELAY);
|
std::thread::sleep(AUDIO_STREAM_RECOVERY_DELAY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,7 +311,6 @@ impl Default for AprsFiConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Top-level SDR configuration (only used when [rig.access] type = "sdr").
|
/// Top-level SDR configuration (only used when [rig.access] type = "sdr").
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@@ -489,19 +488,14 @@ impl ServerConfig {
|
|||||||
|
|
||||||
// Multi-rig uniqueness checks.
|
// Multi-rig uniqueness checks.
|
||||||
if !self.rigs.is_empty() {
|
if !self.rigs.is_empty() {
|
||||||
let mut seen_ids: std::collections::HashSet<String> =
|
let mut seen_ids: std::collections::HashSet<String> = std::collections::HashSet::new();
|
||||||
std::collections::HashSet::new();
|
let mut seen_ports: std::collections::HashSet<u16> = std::collections::HashSet::new();
|
||||||
let mut seen_ports: std::collections::HashSet<u16> =
|
|
||||||
std::collections::HashSet::new();
|
|
||||||
for rig in &self.rigs {
|
for rig in &self.rigs {
|
||||||
if rig.id.trim().is_empty() {
|
if rig.id.trim().is_empty() {
|
||||||
return Err("[[rigs]] entry has an empty id".to_string());
|
return Err("[[rigs]] entry has an empty id".to_string());
|
||||||
}
|
}
|
||||||
if !seen_ids.insert(rig.id.clone()) {
|
if !seen_ids.insert(rig.id.clone()) {
|
||||||
return Err(format!(
|
return Err(format!("[[rigs]] duplicate rig id: \"{}\"", rig.id));
|
||||||
"[[rigs]] duplicate rig id: \"{}\"",
|
|
||||||
rig.id
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
if rig.audio.enabled {
|
if rig.audio.enabled {
|
||||||
if !seen_ports.insert(rig.audio.port) {
|
if !seen_ports.insert(rig.audio.port) {
|
||||||
@@ -523,9 +517,7 @@ impl ServerConfig {
|
|||||||
|| self.decode_logs.ft8_file.trim().is_empty()
|
|| self.decode_logs.ft8_file.trim().is_empty()
|
||||||
|| self.decode_logs.wspr_file.trim().is_empty()
|
|| self.decode_logs.wspr_file.trim().is_empty()
|
||||||
{
|
{
|
||||||
return Err(
|
return Err("[decode_logs] file names must not be empty when enabled".to_string());
|
||||||
"[decode_logs] file names must not be empty when enabled".to_string(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,7 +536,14 @@ impl ServerConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// args must be non-empty
|
// args must be non-empty
|
||||||
if self.rig.access.args.as_deref().map(str::is_empty).unwrap_or(true) {
|
if self
|
||||||
|
.rig
|
||||||
|
.access
|
||||||
|
.args
|
||||||
|
.as_deref()
|
||||||
|
.map(str::is_empty)
|
||||||
|
.unwrap_or(true)
|
||||||
|
{
|
||||||
errors.push("[rig.access] args must be non-empty for type = \"sdr\"".into());
|
errors.push("[rig.access] args must be non-empty for type = \"sdr\"".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,7 +584,7 @@ impl ServerConfig {
|
|||||||
for dec in &ch.decoders {
|
for dec in &ch.decoders {
|
||||||
if let Some(prev_id) = seen.get(dec) {
|
if let Some(prev_id) = seen.get(dec) {
|
||||||
errors.push(format!(
|
errors.push(format!(
|
||||||
"[sdr.channels] decoder \"{}\" appears in both \"{}\" and \"{}\"" ,
|
"[sdr.channels] decoder \"{}\" appears in both \"{}\" and \"{}\"",
|
||||||
dec, prev_id, ch.id
|
dec, prev_id, ch.id
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
@@ -799,10 +798,8 @@ mod tests {
|
|||||||
assert_eq!(config.aprsfi.port, 14580);
|
assert_eq!(config.aprsfi.port, 14580);
|
||||||
assert_eq!(config.aprsfi.passcode, -1);
|
assert_eq!(config.aprsfi.passcode, -1);
|
||||||
assert!(!config.decode_logs.enabled);
|
assert!(!config.decode_logs.enabled);
|
||||||
assert!(
|
assert!(std::path::Path::new(&config.decode_logs.dir)
|
||||||
std::path::Path::new(&config.decode_logs.dir)
|
.ends_with(std::path::Path::new("decoders")));
|
||||||
.ends_with(std::path::Path::new("decoders"))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -950,11 +947,7 @@ tokens = ["secret123"]
|
|||||||
let mut cfg = sdr_config_with_access("driver=rtlsdr");
|
let mut cfg = sdr_config_with_access("driver=rtlsdr");
|
||||||
add_channel(&mut cfg, "primary", 0, false, vec![]);
|
add_channel(&mut cfg, "primary", 0, false, vec![]);
|
||||||
let errors = cfg.validate_sdr();
|
let errors = cfg.validate_sdr();
|
||||||
assert!(
|
assert!(errors.is_empty(), "expected no errors, got: {:?}", errors);
|
||||||
errors.is_empty(),
|
|
||||||
"expected no errors, got: {:?}",
|
|
||||||
errors
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -972,7 +965,12 @@ tokens = ["secret123"]
|
|||||||
fn test_sdr_validate_empty_args() {
|
fn test_sdr_validate_empty_args() {
|
||||||
let cfg = sdr_config_with_access("");
|
let cfg = sdr_config_with_access("");
|
||||||
let errors = cfg.validate_sdr();
|
let errors = cfg.validate_sdr();
|
||||||
assert_eq!(errors.len(), 1, "expected exactly 1 error, got: {:?}", errors);
|
assert_eq!(
|
||||||
|
errors.len(),
|
||||||
|
1,
|
||||||
|
"expected exactly 1 error, got: {:?}",
|
||||||
|
errors
|
||||||
|
);
|
||||||
assert!(
|
assert!(
|
||||||
errors[0].contains("args"),
|
errors[0].contains("args"),
|
||||||
"expected error to mention 'args', got: {}",
|
"expected error to mention 'args', got: {}",
|
||||||
@@ -985,7 +983,12 @@ tokens = ["secret123"]
|
|||||||
let mut cfg = sdr_config_with_access("placeholder");
|
let mut cfg = sdr_config_with_access("placeholder");
|
||||||
cfg.rig.access.args = None;
|
cfg.rig.access.args = None;
|
||||||
let errors = cfg.validate_sdr();
|
let errors = cfg.validate_sdr();
|
||||||
assert_eq!(errors.len(), 1, "expected exactly 1 error, got: {:?}", errors);
|
assert_eq!(
|
||||||
|
errors.len(),
|
||||||
|
1,
|
||||||
|
"expected exactly 1 error, got: {:?}",
|
||||||
|
errors
|
||||||
|
);
|
||||||
assert!(
|
assert!(
|
||||||
errors[0].contains("args"),
|
errors[0].contains("args"),
|
||||||
"expected error to mention 'args', got: {}",
|
"expected error to mention 'args', got: {}",
|
||||||
@@ -1053,7 +1056,8 @@ tokens = ["secret123"]
|
|||||||
assert!(
|
assert!(
|
||||||
errors
|
errors
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| e.contains("ch_nyquist") && (e.contains("Nyquist") || e.contains("exceeds"))),
|
.any(|e| e.contains("ch_nyquist")
|
||||||
|
&& (e.contains("Nyquist") || e.contains("exceeds"))),
|
||||||
"expected error for IF exactly at Nyquist, got: {:?}",
|
"expected error for IF exactly at Nyquist, got: {:?}",
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ use config::{RigInstanceConfig, ServerConfig};
|
|||||||
use rig_handle::RigHandle;
|
use rig_handle::RigHandle;
|
||||||
use trx_decode_log::DecoderLoggers;
|
use trx_decode_log::DecoderLoggers;
|
||||||
|
|
||||||
#[cfg(feature = "soapysdr")]
|
|
||||||
use trx_backend_soapysdr;
|
|
||||||
|
|
||||||
const PKG_DESCRIPTION: &str = concat!(env!("CARGO_PKG_NAME"), " - rig server daemon");
|
const PKG_DESCRIPTION: &str = concat!(env!("CARGO_PKG_NAME"), " - rig server daemon");
|
||||||
const RIG_TASK_CHANNEL_BUFFER: usize = 32;
|
const RIG_TASK_CHANNEL_BUFFER: usize = 32;
|
||||||
const RETRY_MAX_DELAY_SECS: u64 = 2;
|
const RETRY_MAX_DELAY_SECS: u64 = 2;
|
||||||
|
|||||||
@@ -101,7 +101,10 @@ pub async fn run_rig_task(
|
|||||||
mut shutdown_rx: watch::Receiver<bool>,
|
mut shutdown_rx: watch::Receiver<bool>,
|
||||||
) -> DynResult<()> {
|
) -> DynResult<()> {
|
||||||
let histories = config.histories.clone();
|
let histories = config.histories.clone();
|
||||||
info!("[{}] Opening rig backend {}", config.rig_id, config.rig_model);
|
info!(
|
||||||
|
"[{}] Opening rig backend {}",
|
||||||
|
config.rig_id, config.rig_model
|
||||||
|
);
|
||||||
match &config.access {
|
match &config.access {
|
||||||
RigAccess::Serial { path, baud } => info!("Serial: {} @ {} baud", path, baud),
|
RigAccess::Serial { path, baud } => info!("Serial: {} @ {} baud", path, baud),
|
||||||
RigAccess::Tcp { addr } => info!("TCP CAT: {}", addr),
|
RigAccess::Tcp { addr } => info!("TCP CAT: {}", addr),
|
||||||
|
|||||||
Reference in New Issue
Block a user