From fdb53f0b7fdddff3d9819bdf0086cedf0965d7e0 Mon Sep 17 00:00:00 2001 From: Ben Sherriff Date: Tue, 22 Apr 2025 22:23:34 -0400 Subject: [PATCH] Formatting --- Makefile | 5 +- adsb/{adsb_recv => adsb_lib}/src/adsb.rs | 127 +++++++++++------------ adsb/adsb_lib/src/lib.rs | 62 ++++++++--- adsb/adsb_recv/src/main.rs | 57 ++-------- adsb/adsb_recv/src/rusb_rtl.rs | 45 ++++---- adsb/adsb_recv/src/tcp_rtl.rs | 10 +- adsb/adsb_sim/src/main.rs | 26 ++--- adsb/rust-toolchain.toml | 3 + adsb/rustfmt.toml | 3 + 9 files changed, 170 insertions(+), 168 deletions(-) rename adsb/{adsb_recv => adsb_lib}/src/adsb.rs (84%) create mode 100644 adsb/rust-toolchain.toml create mode 100644 adsb/rustfmt.toml diff --git a/Makefile b/Makefile index 1e1308a..e0e2745 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ help: ## This info @cat Makefile | grep -E '^[a-zA-Z\/_-]+:.*?## .*$$' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @echo -format: format-api format-ui ## Format code +format: format-api format-ui format-adsb ## Format code psql: ## Connect to the PSQL DB @docker exec -it aviation-postgres psql -U ${POSTGRES_USER} -P pager=off @@ -34,6 +34,9 @@ run-api: ## Run the API project # ADS-B Commands # ################## +format-adsb: ## Format code + @cd adsb && cargo fmt + build-adsb: ## Build the ADS-B project @cd adsb && cargo build diff --git a/adsb/adsb_recv/src/adsb.rs b/adsb/adsb_lib/src/adsb.rs similarity index 84% rename from adsb/adsb_recv/src/adsb.rs rename to adsb/adsb_lib/src/adsb.rs index 345c23b..572ad3e 100644 --- a/adsb/adsb_recv/src/adsb.rs +++ b/adsb/adsb_lib/src/adsb.rs @@ -1,3 +1,4 @@ +use crate::hex_to_bytes; use std::fmt::Display; use std::io::{Error, ErrorKind, Result}; @@ -24,7 +25,8 @@ impl ADSBFrame { if frame.len() != 14 { return Err(Error::new( ErrorKind::InvalidInput, - format!("expected 14 bytes, received {}", frame.len()))); + format!("expected 14 bytes, received {}", frame.len()), + )); } let mut raw_frame = "".to_string(); @@ -37,13 +39,16 @@ impl ADSBFrame { if downlink_format != 17 { return Err(Error::new( ErrorKind::Unsupported, - format!("downlink format {} is not currently supported", downlink_format) + format!( + "downlink format {} is not currently supported", + downlink_format + ), )); } // Decode the capability by masking off everything but the lower 3 bits let capability_value = &frame[0] & 0b0000_0111; - let capability = Capability::try_from(capability_value)?; + let capability = Capability::try_from(capability_value)?; let icao = Self::decode_icao(&frame[1..=3])?; let message = ADSBMessage::decode(&frame[4..=10])?; @@ -55,17 +60,23 @@ impl ADSBFrame { capability, icao, message, - parity + parity, }) } + pub fn encode(&self) -> Result> { + Ok(hex_to_bytes(&self.raw_frame)?) + } + fn decode_icao(data: &[u8]) -> Result { if data.len() != 3 { return Err(Error::new( ErrorKind::InvalidInput, - format!("ICAO must be 3 bytes, received {}", data.len()))); + format!("ICAO must be 3 bytes, received {}", data.len()), + )); } - let s = data.iter() + let s = data + .iter() .map(|b| format!("{:02X}", b)) .collect::(); Ok(s) @@ -75,29 +86,26 @@ impl ADSBFrame { if data.len() != 3 { return Err(Error::new( ErrorKind::InvalidInput, - format!("parity must be 3 bytes, received {}", data.len()))); + format!("parity must be 3 bytes, received {}", data.len()), + )); } - let p = ((data[0] as u32) << 16) - | ((data[1] as u32) << 8) - | (data[2] as u32); + let p = ((data[0] as u32) << 16) | ((data[1] as u32) << 8) | (data[2] as u32); Ok(p) } } impl Display for ADSBFrame { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Frame: {}\ + write!( + f, + "Frame: {}\ \nDF: {}\ \nCA: {:?}\ \nICAO: {}\ \nME: {:?}\ \nPI: {}", - self.raw_frame, - self.downlink_format, - &self.capability, - self.icao, - &self.message, - self.parity) + self.raw_frame, self.downlink_format, &self.capability, self.icao, &self.message, self.parity + ) } } @@ -176,7 +184,9 @@ impl ADSBMessage { // First 5 bits is the type code let type_code = data[0] >> 3; let message = match type_code { - 1..=4 => ADSBMessage::AircraftIdentification(AircraftIdentification::decode(type_code, data)?), + 1..=4 => { + ADSBMessage::AircraftIdentification(AircraftIdentification::decode(type_code, data)?) + } 5..=8 => ADSBMessage::SurfacePosition(SurfacePosition::decode(data)?), 9..=18 => ADSBMessage::AirbornePositionBaro(AirbornePositionBaro::decode(data)?), 19 => ADSBMessage::AirborneVelocities(AirborneVelocities::decode(data)?), @@ -185,10 +195,12 @@ impl ADSBMessage { 28 => ADSBMessage::AircraftStatus(AircraftStatus::decode(data)?), 29 => ADSBMessage::TargetState(TargetState::decode(data)?), 31 => ADSBMessage::AircraftOperationStatus(AircraftOperationStatus::decode(data)?), - _ => return Err(Error::new( - ErrorKind::InvalidData, - format!("unsupported ADS‑B type_code {}", type_code), - )) + _ => { + return Err(Error::new( + ErrorKind::InvalidData, + format!("unsupported ADS‑B type_code {}", type_code), + )) + } }; Ok(message) @@ -215,12 +227,12 @@ impl AircraftIdentification { } let mut callsign = String::with_capacity(8); - for i in 0 .. 8 { + for i in 0..8 { let shift = 48 - 6 * (i + 1); let raw6 = ((bits >> shift) & 0x3F) as u8; let ch = match raw6 { - 1 ..= 26 => (b'A' + (raw6 - 1)) as char, - 48 ..= 57 => (b'0' + (raw6 - 48)) as char, + 1..=26 => (b'A' + (raw6 - 1)) as char, + 48..=57 => (b'0' + (raw6 - 48)) as char, 32 => ' ', _ => continue, }; @@ -289,78 +301,64 @@ impl WakeVortexCategory { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct SurfacePosition { - -} +pub struct SurfacePosition {} impl SurfacePosition { - pub fn decode(data: &[u8]) -> Result { + pub fn decode(_data: &[u8]) -> Result { Ok(Self {}) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct AirbornePositionBaro { - -} +pub struct AirbornePositionBaro {} impl AirbornePositionBaro { - pub fn decode(data: &[u8]) -> Result { + pub fn decode(_data: &[u8]) -> Result { Ok(Self {}) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct AirborneVelocities { - -} +pub struct AirborneVelocities {} impl AirborneVelocities { - pub fn decode(data: &[u8]) -> Result { + pub fn decode(_data: &[u8]) -> Result { Ok(Self {}) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct AirbornePositionGNSS { - -} +pub struct AirbornePositionGNSS {} impl AirbornePositionGNSS { - pub fn decode(data: &[u8]) -> Result { + pub fn decode(_data: &[u8]) -> Result { Ok(Self {}) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct AircraftStatus { - -} +pub struct AircraftStatus {} impl AircraftStatus { - pub fn decode(data: &[u8]) -> Result { + pub fn decode(_data: &[u8]) -> Result { Ok(Self {}) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct TargetState { - -} +pub struct TargetState {} impl TargetState { - pub fn decode(data: &[u8]) -> Result { + pub fn decode(_data: &[u8]) -> Result { Ok(Self {}) } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct AircraftOperationStatus { - -} +pub struct AircraftOperationStatus {} impl AircraftOperationStatus { - pub fn decode(data: &[u8]) -> Result { + pub fn decode(_data: &[u8]) -> Result { Ok(Self {}) } } @@ -372,8 +370,7 @@ mod tests { #[test] fn test_decode_df_17_aircraft_information() { let input = [ - 0x8D, 0x48, 0x40, 0xD6, 0x20, 0x2C, 0xC3, 0x71, - 0xC3, 0x1C, 0x32, 0xCE, 0x05, 0x76, + 0x8D, 0x48, 0x40, 0xD6, 0x20, 0x2C, 0xC3, 0x71, 0xC3, 0x1C, 0x32, 0xCE, 0x05, 0x76, ]; let frame = ADSBFrame::decode(&input).unwrap(); assert_eq!(frame.downlink_format, 17); @@ -391,8 +388,7 @@ mod tests { assert_eq!(frame.parity, 13501814); let input = [ - 0x8D, 0x48, 0x40, 0xD6, 0x20, 0x2C, 0xC3, 0x71, - 0xC3, 0x2C, 0xE0, 0x57, 0x60, 0x98 + 0x8D, 0x48, 0x40, 0xD6, 0x20, 0x2C, 0xC3, 0x71, 0xC3, 0x2C, 0xE0, 0x57, 0x60, 0x98, ]; let frame = ADSBFrame::decode(&input).unwrap(); assert_eq!(frame.downlink_format, 17); @@ -410,8 +406,7 @@ mod tests { assert_eq!(frame.parity, 5726360); let input = [ - 0x8D, 0x7C, 0x71, 0x81, 0x21, 0x5D, 0x01, 0xA0, - 0x82, 0x08, 0x20, 0x4D, 0x8B, 0xF1 + 0x8D, 0x7C, 0x71, 0x81, 0x21, 0x5D, 0x01, 0xA0, 0x82, 0x08, 0x20, 0x4D, 0x8B, 0xF1, ]; let frame = ADSBFrame::decode(&input).unwrap(); assert_eq!(frame.downlink_format, 17); @@ -429,8 +424,7 @@ mod tests { assert_eq!(frame.parity, 5082097); let input = [ - 0x8D, 0x7C, 0x77, 0x45, 0x22, 0x61, 0x51, 0xA0, - 0x82, 0x08, 0x20, 0x5C, 0xE9, 0xC2 + 0x8D, 0x7C, 0x77, 0x45, 0x22, 0x61, 0x51, 0xA0, 0x82, 0x08, 0x20, 0x5C, 0xE9, 0xC2, ]; let frame = ADSBFrame::decode(&input).unwrap(); assert_eq!(frame.downlink_format, 17); @@ -448,8 +442,7 @@ mod tests { assert_eq!(frame.parity, 6089154); let input = [ - 0x8D, 0x7C, 0x80, 0xAD, 0x23, 0x58, 0xF6, 0xB1, - 0xE3, 0x5C, 0x60, 0xFF, 0x19, 0x25 + 0x8D, 0x7C, 0x80, 0xAD, 0x23, 0x58, 0xF6, 0xB1, 0xE3, 0x5C, 0x60, 0xFF, 0x19, 0x25, ]; let frame = ADSBFrame::decode(&input).unwrap(); assert_eq!(frame.downlink_format, 17); @@ -467,8 +460,7 @@ mod tests { assert_eq!(frame.parity, 16718117); let input = [ - 0x8D, 0x7C, 0x14, 0x65, 0x25, 0x44, 0x60, 0x74, - 0xDF, 0x58, 0x20, 0x73, 0x8E, 0x90 + 0x8D, 0x7C, 0x14, 0x65, 0x25, 0x44, 0x60, 0x74, 0xDF, 0x58, 0x20, 0x73, 0x8E, 0x90, ]; let frame = ADSBFrame::decode(&input).unwrap(); assert_eq!(frame.downlink_format, 17); @@ -489,10 +481,9 @@ mod tests { #[test] fn test_decode_df_17_operation_status() { let input = [ - 0x8D, 0x89, 0x65, 0xD2, 0xF8, 0x21, 0x00, 0x02, - 0x00, 0x49, 0xB8, 0x94, 0xA4, 0x5F, + 0x8D, 0x89, 0x65, 0xD2, 0xF8, 0x21, 0x00, 0x02, 0x00, 0x49, 0xB8, 0x94, 0xA4, 0x5F, ]; let frame = ADSBFrame::decode(&input).unwrap(); dbg!(frame); } -} \ No newline at end of file +} diff --git a/adsb/adsb_lib/src/lib.rs b/adsb/adsb_lib/src/lib.rs index adcbd77..4226144 100644 --- a/adsb/adsb_lib/src/lib.rs +++ b/adsb/adsb_lib/src/lib.rs @@ -1,4 +1,6 @@ -use std::io::Result; +use std::io::{Error, ErrorKind, Result}; + +pub mod adsb; pub trait RtlDevice { /// Send a control message to the device @@ -26,10 +28,7 @@ pub fn run(device: &mut S) -> Result<()> { device.control_send(0x04, &[1])?; // Precompute the preamble pattern in “half‐bit” units (16 samples) - let preamble_halfbit_pattern = [ - 1,1, 0,0, 1,1, 0,0, - 1,1, 0,0, 0,0, 0,0 - ]; + let preamble_halfbit_pattern = [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0]; // Create a big buffer to hold raw I/Q bytes let mut iq_buffer = [0u8; 16_384]; @@ -50,11 +49,7 @@ pub fn run(device: &mut S) -> Result<()> { for pair in raw.chunks_exact(2) { let i_sample = pair[0] as u16; // Threshold at 200 - halfbit_samples.push(if i_sample > 200 { - 1 - } else { - 0 - }); + halfbit_samples.push(if i_sample > 200 { 1 } else { 0 }); } // Scan for the 16-sample preamble @@ -68,7 +63,7 @@ pub fn run(device: &mut S) -> Result<()> { let data_start = match data_start_index { Some(i) => i, - None => continue // No preamble found in this chunk + None => continue, // No preamble found in this chunk }; // Collect 112 ADS-B bits, each manchester-encoded into 2 half-bits @@ -116,4 +111,47 @@ pub fn run(device: &mut S) -> Result<()> { } println!(); } -} \ No newline at end of file +} + +pub fn hex_to_bytes(s: &str) -> Result> { + let bytes = s.as_bytes(); + if bytes.len() % 2 != 0 { + return Err(Error::new( + ErrorKind::InvalidInput, + format!("hex string must have even length, got {}", bytes.len()), + )); + } + + let mut out = Vec::with_capacity(bytes.len() / 2); + for chunk in bytes.chunks(2) { + let hi = match hex_val(chunk[0]) { + Some(hi) => hi, + None => { + return Err(Error::new( + ErrorKind::InvalidInput, + format!("invalid hex char '{}'", chunk[0] as char), + )) + } + }; + let lo = match hex_val(chunk[1]) { + Some(lo) => lo, + None => { + return Err(Error::new( + ErrorKind::InvalidInput, + format!("invalid hex char '{}'", chunk[1] as char), + )) + } + }; + out.push((hi << 4) | lo); + } + Ok(out) +} + +fn hex_val(b: u8) -> Option { + match b { + b'0'..=b'9' => Some(b - b'0'), + b'a'..=b'f' => Some(b - b'a' + 10), + b'A'..=b'F' => Some(b - b'A' + 10), + _ => None, + } +} diff --git a/adsb/adsb_recv/src/main.rs b/adsb/adsb_recv/src/main.rs index 99bffdd..f6aa490 100644 --- a/adsb/adsb_recv/src/main.rs +++ b/adsb/adsb_recv/src/main.rs @@ -1,13 +1,12 @@ -mod tcp_rtl; mod rusb_rtl; -mod adsb; +mod tcp_rtl; -use std::io::{Error, ErrorKind, Result}; -use clap::Parser; -use adsb_lib::run; -use crate::adsb::ADSBFrame; use crate::rusb_rtl::RusbRtl; use crate::tcp_rtl::TcpRtl; +use adsb_lib::adsb::ADSBFrame; +use adsb_lib::{hex_to_bytes, run}; +use clap::Parser; +use std::io::Result; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] @@ -23,11 +22,11 @@ struct ReceiverArgs { fn main() -> Result<()> { let args = ReceiverArgs::parse(); - if let Some(mut hexString) = args.decode { - if let Some(stripped) = hexString.strip_prefix("0x") { - hexString = stripped.to_string(); + if let Some(mut hex_string) = args.decode { + if let Some(stripped) = hex_string.strip_prefix("0x") { + hex_string = stripped.to_string(); } - let buf = hex_to_bytes(&hexString)?; + let buf = hex_to_bytes(&hex_string)?; let frame = ADSBFrame::decode(&buf)?; println!("{}", frame); @@ -44,41 +43,3 @@ fn main() -> Result<()> { run(&mut device) } } - -fn hex_to_bytes(s: &str) -> Result> { - let bytes = s.as_bytes(); - if bytes.len() % 2 != 0 { - return Err(Error::new( - ErrorKind::InvalidInput, - format!("hex string must have even length, got {}", bytes.len()))); - } - - let mut out = Vec::with_capacity(bytes.len() / 2); - for chunk in bytes.chunks(2) { - let hi = match hex_val(chunk[0]) { - Some(hi) => hi, - None => return Err(Error::new( - ErrorKind::InvalidInput, - format!("invalid hex char '{}'", chunk[0] as char) - )) - }; - let lo = match hex_val(chunk[1]) { - Some(lo) => lo, - None => return Err(Error::new( - ErrorKind::InvalidInput, - format!("invalid hex char '{}'", chunk[1] as char) - )) - }; - out.push((hi << 4) | lo); - } - Ok(out) -} - -fn hex_val(b: u8) -> Option { - match b { - b'0'..=b'9' => Some(b - b'0'), - b'a'..=b'f' => Some(b - b'a' + 10), - b'A'..=b'F' => Some(b - b'A' + 10), - _ => None, - } -} \ No newline at end of file diff --git a/adsb/adsb_recv/src/rusb_rtl.rs b/adsb/adsb_recv/src/rusb_rtl.rs index b364d10..d983b2b 100644 --- a/adsb/adsb_recv/src/rusb_rtl.rs +++ b/adsb/adsb_recv/src/rusb_rtl.rs @@ -1,7 +1,7 @@ +use adsb_lib::RtlDevice; +use rusb::{request_type, Context, DeviceHandle, Direction, Recipient, RequestType, UsbContext}; use std::io::{Error, ErrorKind, Result}; use std::time::Duration; -use rusb::{request_type, Context, DeviceHandle, Direction, Recipient, RequestType, UsbContext}; -use adsb_lib::RtlDevice; // USB identifiers for RTL-SDR const VENDOR_ID: u16 = 0x0BDA; @@ -19,15 +19,17 @@ impl RusbRtl { /// Open the USB device, claim interface 0, and return a wrapper pub fn open() -> Result { // Create a new libusb context - let mut ctx = Context::new().map_err(|err| Error::new(ErrorKind::Other, err))?; + let ctx = Context::new().map_err(|err| Error::new(ErrorKind::Other, err))?; // Find and open the RTL-SDR by VID/PID - let mut handle = ctx + let handle = ctx .open_device_with_vid_pid(VENDOR_ID, PRODUCT_ID) .ok_or_else(|| Error::new(ErrorKind::NotFound, "Device not found"))?; // Claim interface 0 - handle.claim_interface(0).map_err(|err| Error::new(ErrorKind::Other, err))?; + handle + .claim_interface(0) + .map_err(|err| Error::new(ErrorKind::Other, err))?; Ok(Self { handle }) } @@ -42,14 +44,16 @@ impl RusbRtl { let bm_request_type = request_type(Direction::Out, RequestType::Vendor, Recipient::Device); // Perform the control transfer. - self.handle + self + .handle .write_control( bm_request_type, request, 0, // wValue 0, // wIndex data, - Duration::from_secs(1)) + USB_TRANSFER_TIMEOUT, + ) .map(|_bytes_written| ()) } @@ -66,14 +70,14 @@ impl RusbRtl { let mut buffer = vec![0u8; response_length]; // Read the control response into the buffer - let n = self.handle - .read_control( - bm_request_type, - request, - 0, // wValue - 0, // wIndex - &mut buffer, - Duration::from_secs(1))?; + let n = self.handle.read_control( + bm_request_type, + request, + 0, // wValue + 0, // wIndex + &mut buffer, + USB_TRANSFER_TIMEOUT, + )?; // Truncate to the actual length returned by the device buffer.truncate(n); @@ -83,18 +87,21 @@ impl RusbRtl { impl RtlDevice for RusbRtl { fn control_send(&mut self, b_request: u8, data: &[u8]) -> Result<()> { - self.control_out(b_request, data) + self + .control_out(b_request, data) .map_err(|err| Error::new(ErrorKind::Other, err)) } fn control_recv(&mut self, b_request: u8, length: usize) -> Result> { - self.control_in(b_request, length) + self + .control_in(b_request, length) .map_err(|err| Error::new(ErrorKind::Other, err)) } fn read_bulk(&mut self, buffer: &mut [u8]) -> Result { - self.handle - .read_bulk(DATA_ENDPOINT_ADDRESS, buffer, Duration::from_secs(1)) + self + .handle + .read_bulk(DATA_ENDPOINT_ADDRESS, buffer, USB_TRANSFER_TIMEOUT) .map_err(|err| Error::new(ErrorKind::Other, err)) } } diff --git a/adsb/adsb_recv/src/tcp_rtl.rs b/adsb/adsb_recv/src/tcp_rtl.rs index 950ad0c..4fa00a2 100644 --- a/adsb/adsb_recv/src/tcp_rtl.rs +++ b/adsb/adsb_recv/src/tcp_rtl.rs @@ -1,6 +1,6 @@ +use adsb_lib::RtlDevice; use std::io::{Error, ErrorKind, Read, Result, Write}; use std::net::TcpStream; -use adsb_lib::RtlDevice; // Tags for framing requests/responses over the TCP socket const TAG_CTRL_OUT: u8 = 0x10; @@ -47,7 +47,7 @@ impl TcpRtl { let mut status_byte = [0u8; 1]; self.socket.read_exact(&mut status_byte)?; if status_byte[0] != 0 { - Err(Error::new(ErrorKind::Other, "Remote reported error" )) + Err(Error::new(ErrorKind::Other, "Remote reported error")) } else { Ok(()) } @@ -112,7 +112,9 @@ impl RtlDevice for TcpRtl { let actual_payload_length = u32::from_le_bytes(length_bytes) as usize; // Read the payload - self.socket.read_exact(&mut buffer[..actual_payload_length])?; + self + .socket + .read_exact(&mut buffer[..actual_payload_length])?; Ok(actual_payload_length) } -} \ No newline at end of file +} diff --git a/adsb/adsb_sim/src/main.rs b/adsb/adsb_sim/src/main.rs index 092bd79..c62a7aa 100644 --- a/adsb/adsb_sim/src/main.rs +++ b/adsb/adsb_sim/src/main.rs @@ -1,8 +1,8 @@ +use clap::Parser; use std::io::{Read, Write}; use std::net::{TcpListener, TcpStream}; use std::thread; use std::time::Duration; -use clap::Parser; // Framing tags const TAG_CONTROL_OUT: u8 = 0x10; @@ -10,8 +10,7 @@ const TAG_CONTROL_IN: u8 = 0x11; const TAG_BULK: u8 = 0x20; const ADSB_MESSAGE: [u8; 14] = [ - 0x8D, 0x48, 0x40, 0xD6, 0x20, 0x2C, 0xC3, - 0x71, 0xC3, 0x2C, 0xE0, 0x57, 0x60, 0x98, + 0x8D, 0x48, 0x40, 0xD6, 0x20, 0x2C, 0xC3, 0x71, 0xC3, 0x2C, 0xE0, 0x57, 0x60, 0x98, ]; #[derive(Parser, Debug)] @@ -84,13 +83,13 @@ fn handle_client_connection(mut connection: TcpStream) { payload_buffer[0], payload_buffer[1], payload_buffer[2], - payload_buffer[3] + payload_buffer[3], ]); println!("SET_FREQ -> {} Hz", current_frequency_hz); } // Acknowledge with a single byte = 0 (OK) connection.write_all(&[0u8]).ok(); - }, + } TAG_CONTROL_IN => { dbg!(message_tag); // Simulate a CONTROL_IN reply with a fixed pattern @@ -105,7 +104,7 @@ fn handle_client_connection(mut connection: TcpStream) { // Payload (0x42 repeated) let reply = vec![0x42; payload_length]; let _ = connection.write_all(&reply).ok(); - }, + } TAG_BULK => { dbg!(message_tag); // Generate a ADS-B IQ burst @@ -123,11 +122,11 @@ fn handle_client_connection(mut connection: TcpStream) { // Throttle a bit to simulate real USB/bulk behavior thread::sleep(Duration::from_millis(10)); - }, + } _unknown_tag => { // On any unrecognized tag, break out - break - }, + break; + } } } @@ -158,8 +157,7 @@ fn generate_adsb_iq_samples() -> Vec { } // Concatenate preamble + data - let mut full_bitstream = Vec::with_capacity( - preamble_bits.len() * 2 + manchester_bits.len()); + let mut full_bitstream = Vec::with_capacity(preamble_bits.len() * 2 + manchester_bits.len()); // Preamble: each '1' or '0' is one microsecond = 2 samples for &pb in preamble_bits.iter() { @@ -175,11 +173,7 @@ fn generate_adsb_iq_samples() -> Vec { // I = 128 + 127*(bit), Q = 128 let mut iq = Vec::with_capacity(full_bitstream.len() * 2); for &level in full_bitstream.iter() { - let i_sample = if level == 1 { - 255u8 - } else { - 128u8 - }; + let i_sample = if level == 1 { 255u8 } else { 128u8 }; let q_sample = 128u8; iq.push(i_sample); iq.push(q_sample); diff --git a/adsb/rust-toolchain.toml b/adsb/rust-toolchain.toml new file mode 100644 index 0000000..02d090f --- /dev/null +++ b/adsb/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable" +components = ["rustfmt", "clippy"] \ No newline at end of file diff --git a/adsb/rustfmt.toml b/adsb/rustfmt.toml new file mode 100644 index 0000000..76f62b4 --- /dev/null +++ b/adsb/rustfmt.toml @@ -0,0 +1,3 @@ +indent_style = "Block" +reorder_imports = false +tab_spaces = 2 \ No newline at end of file