mod constants; mod device; mod error; mod frame; mod hex; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use crate::device::RtlSdrDevice; use clap::Parser; use crate::constants::DEVICE_RTL2832U; use crate::frame::ADSBFrame; use crate::hex::hex_to_bytes; #[derive(Parser, Debug)] #[command(author, version, about = "An ADS-B Receiver")] struct ReceiverArgs { /// Hex-string to decode #[arg(short = 'd', long)] decode: Option, /// Connect to the USB device #[arg(short = 'c', long, action)] connect: bool, /// Display ADS-B/Mode-S receiver info #[arg(short = 'i', long, action)] info: bool, /// Enable debug logging #[arg(short = 'D', long, action = clap::ArgAction::Count)] debug: u8, } fn main() { let args = ReceiverArgs::parse(); let default_filter = match args.debug { 0 => "warn,adsb=info", // no -D 1 => "warn,adsb=debug", // -D _ => "trace,adsb=trace", // -DD or more }; env_logger::init_from_env(env_logger::Env::default().filter_or("RUST_LOG", default_filter)); let device_info = DEVICE_RTL2832U; // Handle connection if args.connect { log::info!("Connecting to {:?}", device_info); let mut device = match RtlSdrDevice::open(device_info.vid, device_info.pid) { Ok(d) => d, Err(err) => { log::error!("Unable to open RTL SDR device: {:?}", err); return; } }; log::debug!("Connected to {:?}", device_info.to_string()); let running = Arc::new(AtomicBool::new(true)); if let Err(err) = ctrlc::set_handler({ let running = running.clone(); move || running.store(false, Ordering::SeqCst) }) { log::error!("Error setting Ctrl-C handler: {}", err); running.store(false, Ordering::SeqCst); }; if let Err(err) = device.process(running) { log::error!("Failed to read from device: {}", err); if let Err(err) = device.close() { log::error!("Failed to close device: {}", err); }; }; } // Display dongle info else if args.info { RtlSdrDevice::info(device_info.vid, device_info.pid); } // Handle decode mode else if let Some(mut hex_string) = args.decode { if let Some(stripped) = hex_string.strip_prefix("0x") { hex_string = stripped.to_string(); } let buffer = match hex_to_bytes(&hex_string) { Ok(buffer) => buffer, Err(err) => { eprintln!("Unable to convert hex to bytes: {:?}", err); return; } }; if let Ok(frame) = ADSBFrame::decode(&buffer) { println!("{:?}", frame); }; } else { eprintln!("No connection specified"); } }