Skip to content

Commit

Permalink
wip: Update deku
Browse files Browse the repository at this point in the history
  • Loading branch information
wcampbell0x2a committed Aug 26, 2023
1 parent 29b37de commit 33a7d27
Show file tree
Hide file tree
Showing 15 changed files with 664 additions and 548 deletions.
721 changes: 364 additions & 357 deletions Cargo.lock

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions apps/src/1090/1090.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::io::{BufRead, BufReader};
use std::io::{BufRead, BufReader, Cursor};
use std::net::TcpStream;

use adsb_deku::deku::DekuContainerRead;
Expand All @@ -22,7 +22,7 @@ struct Options {
/// Panic on adsb_deku::Frame::fmt::Display not implemented
#[arg(long)]
panic_display: bool,
/// Panic on adsb_deku::Frame::from_bytes() error
/// Panic on adsb_deku::Frame::from_reader() error
#[arg(long)]
panic_decode: bool,
/// Display debug of adsb::Frame
Expand All @@ -48,7 +48,7 @@ fn main() {
// convert from string hex -> bytes
let hex = &mut input.to_string()[1..len - 2].to_string();
println!("{}", hex.to_lowercase());
let bytes = if let Ok(bytes) = hex::decode(&hex) {
let mut bytes = if let Ok(bytes) = hex::decode(&hex) {
bytes
} else {
continue;
Expand All @@ -60,8 +60,9 @@ fn main() {
}

// decode
match Frame::from_bytes((&bytes, 0)) {
Ok((_, frame)) => {
let cursor = Cursor::new(bytes);
match Frame::from_reader(cursor) {
Ok(frame) => {
if options.debug {
println!("{frame:#?}");
}
Expand Down
12 changes: 5 additions & 7 deletions apps/src/radar/radar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod help;
use crate::help::build_tab_help;

mod airplanes;
use std::io::{self, BufRead, BufReader, BufWriter};
use std::io::{self, BufRead, BufReader, BufWriter, Cursor};
use std::net::{SocketAddr, TcpStream};
use std::sync::{Arc, Mutex};
use std::time::Duration;
Expand Down Expand Up @@ -368,7 +368,7 @@ fn main() -> Result<()> {
// convert from string hex -> bytes
let hex = &mut input.to_string()[1..len - 2].to_string();
debug!("bytes: {hex}");
let bytes = if let Ok(bytes) = hex::decode(&hex) {
let mut bytes = if let Ok(bytes) = hex::decode(&hex) {
bytes
} else {
continue;
Expand All @@ -389,18 +389,16 @@ fn main() -> Result<()> {
};
if df_adsb {
// parse the entire DF frame
let frame = Frame::from_bytes((&bytes, 0));
let cursor = Cursor::new(bytes);
let frame = Frame::from_reader(cursor);
match frame {
Ok((left_over, frame)) => {
Ok(frame) => {
debug!("ADS-B Frame: {frame}");
let airplane_added = adsb_airplanes.action(
frame,
(settings.lat, settings.long),
settings.opts.max_range,
);
if left_over.1 != 0 {
error!("{left_over:x?}");
}
// update stats
stats.update(&adsb_airplanes, airplane_added);
},
Expand Down
4 changes: 3 additions & 1 deletion libadsb_deku/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ std = ["deku/std", "alloc"]
alloc = ["deku/alloc"]

[dependencies]
deku = { version = "0.16", default-features = false }
deku = { git = "https://github.com/sharksforarms/deku", branch = "impl-reader", default-features = false, features = ["const_generics", "read_cache", "logging"] }
serde = { version = "1.0", features = ["derive"], optional = true }
libm = "0.2.2"
env_logger = "*"
log = "*"

[dev-dependencies]
hex = "0.4"
Expand Down
6 changes: 3 additions & 3 deletions libadsb_deku/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use adsb_deku::Frame;
use adsb_deku::deku::DekuContainerRead;

let bytes = hex!("8da2c1bd587ba2adb31799cb802b");
let frame = Frame::from_bytes((&bytes, 0)).unwrap().1;
let frame = Frame::from_reader(bytes.as_ref()).unwrap();
assert_eq!(
r#" Extended Squitter Airborne position (barometric altitude)
Address: a2c1bd (Mode S / ADS-B)
Expand Down Expand Up @@ -101,11 +101,11 @@ This library is also fuzzed, ensuring no panic when parsing from demodulated byt

## Benchmark
Benchmarking is done against a file containing `215606` ADS-B messages: [lax-messages.txt](tests/lax-messages.txt).
Quick math `(215606 / 692.80)` says the average speed of decoding is `~311.21 ms` a message.
Quick math `(215606 / 1000.00)` says the average speed of decoding is `~215.6 ms` a message.
A `~3%` speedup can be gained on some systems by using `RUSTFLAGS="-C target-cpu=native"`
```text
> cargo bench
lax_messsages time: [680.70 ms 692.82 ms 704.99 ms]
lax_messsages time: [1.0625 s 1.0665 s 1.0708 s]
```

## Derivation
Expand Down
6 changes: 4 additions & 2 deletions libadsb_deku/benches/decoding.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::io::Cursor;

use adsb_deku::cpr::get_position;
use adsb_deku::deku::prelude::*;
use adsb_deku::{Altitude, CPRFormat, Frame};
use criterion::{criterion_group, criterion_main, Criterion};

Expand Down Expand Up @@ -47,7 +48,8 @@ fn lax_message() {
let hex = &mut line.to_string()[1..len - 1].to_string();
let bytes = hex::decode(&hex).unwrap();
// test non panic decode
let _frame = Frame::from_bytes((&bytes, 0)).unwrap().1;
let cursor = Cursor::new(bytes);
let _frame = Frame::from_reader(cursor).unwrap();
}
}

Expand Down
87 changes: 59 additions & 28 deletions libadsb_deku/src/adsb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ use core::{
result::Result::Ok,
stringify, write, writeln,
};
use std::io::Read;
#[cfg(not(feature = "alloc"))]
use std::{fmt, i64};

use deku::bitvec::{BitSlice, Msb0};
use deku::prelude::*;

use crate::mode_ac::decode_id13_field;
Expand Down Expand Up @@ -65,7 +65,7 @@ impl ADSB {
#[deku(type = "u8", bits = "5")]
pub enum ME {
#[deku(id_pat = "9..=18")]
AirbornePositionBaroAltitude(Altitude),
AirbornePositionBaroAltitude { id: u8, value: Altitude },

#[deku(id = "19")]
AirborneVelocity(AirborneVelocity),
Expand All @@ -74,22 +74,26 @@ pub enum ME {
NoPosition([u8; 6]),

#[deku(id_pat = "1..=4")]
AircraftIdentification(Identification),
AircraftIdentification {
#[deku(map = "|field: u8| -> Result<_, DekuError> { TypeCoding::try_from(field) }")]
tc: TypeCoding,
value: Identification,
},

#[deku(id_pat = "5..=8")]
SurfacePosition(SurfacePosition),
SurfacePosition { id: u8, value: SurfacePosition },

#[deku(id_pat = "20..=22")]
AirbornePositionGNSSAltitude(Altitude),
AirbornePositionGNSSAltitude { id: u8, value: Altitude },

#[deku(id = "23")]
Reserved0([u8; 6]),

#[deku(id_pat = "24")]
#[deku(id = "24")]
SurfaceSystemStatus([u8; 6]),

#[deku(id_pat = "25..=27")]
Reserved1([u8; 6]),
Reserved1 { id: u8, value: [u8; 6] },

#[deku(id = "28")]
AircraftStatus(AircraftStatus),
Expand Down Expand Up @@ -124,7 +128,10 @@ impl ME {
writeln!(f, " Address: {icao} {address_type}")?;
writeln!(f, " Air/Ground: {capability}")?;
},
ME::AircraftIdentification(Identification { tc, ca, cn }) => {
ME::AircraftIdentification {
tc,
value: Identification { ca, cn, .. },
} => {
writeln!(
f,
" Extended Squitter{transponder}Aircraft identification and category"
Expand All @@ -134,11 +141,14 @@ impl ME {
writeln!(f, " Ident: {cn}")?;
writeln!(f, " Category: {tc}{ca}")?;
},
ME::SurfacePosition(..) => {
ME::SurfacePosition { .. } => {
writeln!(f, " Extended Squitter{transponder}Surface position")?;
writeln!(f, " Address: {icao} {address_type}")?;
},
ME::AirbornePositionBaroAltitude(altitude) => {
ME::AirbornePositionBaroAltitude {
id: _,
value: altitude,
} => {
writeln!(
f,
" Extended Squitter{transponder}Airborne position (barometric altitude)"
Expand Down Expand Up @@ -204,15 +214,18 @@ impl ME {
writeln!(f, " Address: {icao} {address_type}")?;
},
},
ME::AirbornePositionGNSSAltitude(altitude) => {
ME::AirbornePositionGNSSAltitude {
id: _,
value: altitude,
} => {
writeln!(
f,
" Extended Squitter{transponder}Airborne position (GNSS altitude)",
)?;
writeln!(f, " Address: {icao} {address_type}")?;
write!(f, "{altitude}")?;
},
ME::Reserved0(_) | ME::Reserved1(_) => {
ME::Reserved0(_) | ME::Reserved1 { .. } => {
writeln!(f, " Extended Squitter{transponder}Unknown")?;
writeln!(f, " Address: {icao} {address_type}")?;
writeln!(f, " Air/Ground: {capability}")?;
Expand Down Expand Up @@ -300,7 +313,7 @@ impl ME {
writeln!(f, " Air/Ground: {capability}")?;
write!(f, " Aircraft Operational Status:\n {opstatus_surface}")?;
},
ME::AircraftOperationStatus(OperationStatus::Reserved(..)) => {
ME::AircraftOperationStatus(OperationStatus::Reserved { .. }) => {
writeln!(
f,
" Extended Squitter{transponder}Aircraft operational status (reserved)",
Expand Down Expand Up @@ -354,7 +367,12 @@ pub enum OperationStatus {
Surface(OperationStatusSurface),

#[deku(id_pat = "2..=7")]
Reserved(#[deku(bits = "5")] u8, [u8; 5]),
Reserved {
id: u8,
#[deku(bits = "5")]
more: u8,
value: [u8; 5],
},
}

/// [`ME::AircraftOperationStatus`] && [`OperationStatus`] == 0
Expand Down Expand Up @@ -826,26 +844,39 @@ pub struct OperationCodeSurface {
#[derive(Debug, PartialEq, Eq, DekuRead, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Identification {
pub tc: TypeCoding,

#[deku(bits = "3")]
pub ca: u8,

/// N-Number / Tail Number
#[deku(reader = "aircraft_identification_read(deku::rest)")]
#[deku(reader = "aircraft_identification_read(deku::reader)")]
pub cn: String,
}

#[derive(Debug, PartialEq, Eq, DekuRead, Copy, Clone)]
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[deku(type = "u8", bits = "5")]
pub enum TypeCoding {
D = 1,
C = 2,
B = 3,
A = 4,
}

impl TryFrom<u8> for TypeCoding {
type Error = DekuError;

fn try_from(value: u8) -> Result<Self, Self::Error> {
let a = match value {
1 => TypeCoding::D,
2 => TypeCoding::C,
3 => TypeCoding::B,
4 => TypeCoding::A,
_ => return Err(DekuError::Unexpected("not a type coding value".to_string())),
};

Ok(a)
}
}

impl fmt::Display for TypeCoding {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
Expand Down Expand Up @@ -995,26 +1026,26 @@ pub enum AirborneVelocityType {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AirborneVelocitySubFields {
pub dew: DirectionEW,
#[deku(reader = "Self::read_v(deku::rest, t)")]
#[deku(reader = "Self::read_v(deku::reader, t)")]
pub vew: u16,
pub dns: DirectionNS,
#[deku(reader = "Self::read_v(deku::rest, t)")]
#[deku(reader = "Self::read_v(deku::reader, t)")]
pub vns: u16,
}

impl AirborneVelocitySubFields {
fn read_v(
rest: &BitSlice<u8, Msb0>,
fn read_v<R: Read>(
reader: &mut Reader<R>,
t: AirborneVelocityType,
) -> result::Result<(&BitSlice<u8, Msb0>, u16), DekuError> {
) -> result::Result<u16, DekuError> {
match t {
AirborneVelocityType::Subsonic => {
u16::read(rest, (deku::ctx::Endian::Big, deku::ctx::BitSize(10)))
.map(|(rest, value)| (rest, value - 1))
u16::from_reader_with_ctx(reader, (deku::ctx::Endian::Big, deku::ctx::BitSize(10)))
.map(|value| value - 1)
},
AirborneVelocityType::Supersonic => {
u16::read(rest, (deku::ctx::Endian::Big, deku::ctx::BitSize(10)))
.map(|(rest, value)| (rest, 4 * (value - 1)))
u16::from_reader_with_ctx(reader, (deku::ctx::Endian::Big, deku::ctx::BitSize(10)))
.map(|value| 4 * (value - 1))
},
}
}
Expand Down
12 changes: 6 additions & 6 deletions libadsb_deku/src/bds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ use alloc::format;
use alloc::string::String;
#[cfg(feature = "alloc")]
use core::{
clone::Clone, cmp::PartialEq, fmt, fmt::Debug, prelude::rust_2021::derive, result::Result,
result::Result::Ok, writeln,
clone::Clone, cmp::PartialEq, fmt, fmt::Debug, prelude::rust_2021::derive, result::Result::Ok,
writeln,
};

use deku::prelude::*;

use crate::aircraft_identification_read;

#[derive(Debug, PartialEq, Eq, DekuRead, Clone)]
#[deku(type = "u8", bits = "8")]
#[deku(type = "u8")]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum BDS {
/// (1, 0) Table A-2-16
Expand All @@ -26,10 +26,10 @@ pub enum BDS {

/// (2, 0) Table A-2-32
#[deku(id = "0x20")]
AircraftIdentification(#[deku(reader = "aircraft_identification_read(deku::rest)")] String),
AircraftIdentification(#[deku(reader = "aircraft_identification_read(deku::reader)")] String),

#[deku(id_pat = "_")]
Unknown([u8; 6]),
Unknown { id: u8, value: [u8; 5] },
}

impl fmt::Display for BDS {
Expand All @@ -45,7 +45,7 @@ impl fmt::Display for BDS {
Self::DataLinkCapability(_) => {
writeln!(f, "Comm-B format: BDS1,0 Datalink capabilities")?;
},
Self::Unknown(_) => {
Self::Unknown { id: _, value: _ } => {
writeln!(f, "Comm-B format: unknown format")?;
},
}
Expand Down
1 change: 1 addition & 0 deletions libadsb_deku/src/crc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ pub fn modes_checksum(message: &[u8], bits: usize) -> result::Result<u32, DekuEr
let mut rem: u32 = 0;
let n = bits / 8;

log::trace!("{message:02x?}");
if (n < 3) || (message.len() < n) {
return Err(DekuError::Incomplete(NeedSize::new(4)));
}
Expand Down
Loading

0 comments on commit 33a7d27

Please sign in to comment.