Skip to content

Commit fe46947

Browse files
committed
Rework Kind
- Generate from macro. - Add missing fields. - Make iterator work with new `Kind`.
1 parent 61bf9fc commit fe46947

File tree

4 files changed

+159
-182
lines changed

4 files changed

+159
-182
lines changed

src/field/_macros.rs

+45-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,51 @@ macro_rules! ensure_length {
66
};
77
}
88

9+
macro_rules! impl_kind {
10+
(
11+
$(#[$outer:meta])*
12+
pub enum $name:ident {
13+
$(
14+
$(#[$inner:ident $($args:tt)*])*
15+
$variant:ident { bit: $bit:expr, align: $align:expr, size: $size:expr },
16+
)+
17+
}
18+
) => {
19+
$(#[$outer])*
20+
pub enum $name {
21+
$(
22+
$(#[$inner $($args)*])*
23+
$variant,
24+
)+
25+
}
26+
27+
impl $name {
28+
pub fn from_bit(bit: u32) -> Option<Self> {
29+
match bit {
30+
$( $bit => Some(Self::$variant), )+
31+
_ => None
32+
}
33+
}
34+
35+
/// Returns the present bit value for the field.
36+
pub fn bit(&self) -> u32 {
37+
match self { $( Self::$variant => $bit, )+ }
38+
}
39+
40+
/// Returns the alignment of the field.
41+
pub fn align(&self) -> u32 {
42+
match self { $( Self::$variant => $align, )+ }
43+
}
44+
45+
/// Returns the size of the field.
46+
pub fn size(&self) -> usize {
47+
match self { $( Self::$variant => $size, )+ }
48+
}
49+
}
50+
51+
};
52+
}
53+
954
macro_rules! impl_enum {
1055
(
1156
$(#[$outer:meta])*
@@ -60,12 +105,6 @@ macro_rules! impl_newtype {
60105

61106
impl_from_bytes_newtype!($name);
62107

63-
impl PartialEq<$ty> for $name {
64-
fn eq(&self, other: &$ty) -> bool {
65-
self.0.eq(other)
66-
}
67-
}
68-
69108
impl $name {
70109
/// Consumes this field and returns the underlying value.
71110
#[inline]

src/field/kind.rs

+33-99
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,35 @@
1-
use crate::field::VendorNamespace;
2-
use crate::{Error, Result};
3-
4-
/// The type of radiotap field.
5-
#[derive(Debug, Clone, PartialEq)]
6-
#[non_exhaustive]
7-
pub enum Kind {
8-
Tsft,
9-
Flags,
10-
Rate,
11-
Channel,
12-
Fhss,
13-
AntennaSignal,
14-
AntennaNoise,
15-
LockQuality,
16-
TxAttenuation,
17-
TxAttenuationDb,
18-
TxPower,
19-
Antenna,
20-
AntennaSignalDb,
21-
AntennaNoiseDb,
22-
RxFlags,
23-
TxFlags,
24-
RtsRetries,
25-
DataRetries,
26-
XChannel,
27-
Mcs,
28-
AmpduStatus,
29-
Vht,
30-
Timestamp,
31-
VendorNamespace(Option<VendorNamespace>),
32-
}
33-
34-
impl Kind {
35-
pub fn new(value: u8) -> Result<Self> {
36-
Ok(match value {
37-
0 => Self::Tsft,
38-
1 => Self::Flags,
39-
2 => Self::Rate,
40-
3 => Self::Channel,
41-
4 => Self::Fhss,
42-
5 => Self::AntennaSignal,
43-
6 => Self::AntennaNoise,
44-
7 => Self::LockQuality,
45-
8 => Self::TxAttenuation,
46-
9 => Self::TxAttenuationDb,
47-
10 => Self::TxPower,
48-
11 => Self::Antenna,
49-
12 => Self::AntennaSignalDb,
50-
13 => Self::AntennaNoiseDb,
51-
14 => Self::RxFlags,
52-
15 => Self::TxFlags,
53-
16 => Self::RtsRetries,
54-
17 => Self::DataRetries,
55-
18 => Self::XChannel,
56-
19 => Self::Mcs,
57-
20 => Self::AmpduStatus,
58-
21 => Self::Vht,
59-
22 => Self::Timestamp,
60-
_ => {
61-
return Err(Error::UnsupportedField);
62-
}
63-
})
64-
}
65-
66-
/// Returns the align value for the field.
67-
pub fn align(&self) -> u64 {
68-
match self {
69-
Self::Tsft | Self::Timestamp => 8,
70-
Self::XChannel | Self::AmpduStatus => 4,
71-
Self::Channel
72-
| Self::Fhss
73-
| Self::LockQuality
74-
| Self::TxAttenuation
75-
| Self::TxAttenuationDb
76-
| Self::RxFlags
77-
| Self::TxFlags
78-
| Self::Vht
79-
| Self::VendorNamespace(_) => 2,
80-
_ => 1,
81-
}
82-
}
83-
84-
/// Returns the size of the field.
85-
pub fn size(&self) -> usize {
86-
match self {
87-
Self::Vht | Self::Timestamp => 12,
88-
Self::Tsft | Self::AmpduStatus | Self::XChannel => 8,
89-
Self::VendorNamespace(_) => 6,
90-
Self::Channel => 4,
91-
Self::Mcs => 3,
92-
Self::Fhss
93-
| Self::LockQuality
94-
| Self::TxAttenuation
95-
| Self::TxAttenuationDb
96-
| Self::RxFlags
97-
| Self::TxFlags => 2,
98-
_ => 1,
99-
}
1+
impl_kind! {
2+
/// The type of radiotap field.
3+
#[derive(Debug, Clone, PartialEq)]
4+
#[non_exhaustive]
5+
pub enum Kind {
6+
Tsft { bit: 0, align: 8, size: 8 },
7+
Flags { bit: 1, align: 1, size: 1 },
8+
Rate { bit: 2, align: 1, size: 1 },
9+
Channel { bit: 3, align: 2, size: 4 },
10+
Fhss { bit: 4, align: 2, size: 2 },
11+
AntennaSignal { bit: 5, align: 1, size: 1 },
12+
AntennaNoise { bit: 6, align: 1, size: 1 },
13+
LockQuality { bit: 7, align: 2, size: 2 },
14+
TxAttenuation { bit: 8, align: 2, size: 2 },
15+
TxAttenuationDb { bit: 9, align: 2, size: 2 },
16+
TxPower { bit: 10, align: 1, size: 1 },
17+
Antenna { bit: 11, align: 1, size: 1 },
18+
AntennaSignalDb { bit: 12, align: 1, size: 1 },
19+
AntennaNoiseDb { bit: 13, align: 1, size: 1 },
20+
RxFlags { bit: 14, align: 2, size: 2 },
21+
RtsRetries { bit: 16, align: 1, size: 1 },
22+
TxFlags { bit: 15, align: 2, size: 2 },
23+
DataRetries { bit: 17, align: 1, size: 1 },
24+
XChannel { bit: 18, align: 4, size: 8 },
25+
Mcs { bit: 19, align: 1, size: 3 },
26+
AmpduStatus { bit: 20, align: 4, size: 8 },
27+
Vht { bit: 21, align: 2, size: 12 },
28+
Timestamp { bit: 22, align: 8, size: 12 },
29+
He { bit: 23, align: 8, size: 12 },
30+
HeMu { bit: 24, align: 8, size: 12 },
31+
HeMuUser { bit: 25, align: 8, size: 12 },
32+
ZeroLenPsdu { bit: 26, align: 1, size: 1 },
33+
LSig { bit: 27, align: 2, size: 4 },
10034
}
10135
}

src/field/mod.rs

+2-39
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub struct Header {
2929
/// The size of the radiotap header.
3030
pub size: usize,
3131
/// The fields present in the radiotap capture.
32-
pub present: Vec<Kind>,
32+
pub present: Vec<u32>,
3333
}
3434

3535
impl FromBytes for Header {
@@ -50,48 +50,11 @@ impl FromBytes for Header {
5050
}
5151

5252
let mut present;
53-
let mut present_count = 0;
54-
let mut vendor_namespace = false;
5553
let mut kinds = Vec::new();
5654

5755
loop {
5856
present = cursor.read_u32::<LE>()?;
59-
60-
if !vendor_namespace {
61-
for bit in 0..29 {
62-
if present.is_bit_set(bit) {
63-
match Kind::new(present_count * 32 + bit) {
64-
Ok(kind) => {
65-
kinds.push(kind);
66-
}
67-
Err(Error::UnsupportedField) => {
68-
// Does not matter, we will just parse the ones
69-
// we can
70-
}
71-
Err(e) => return Err(e),
72-
}
73-
}
74-
}
75-
}
76-
77-
// Need to move to radiotap namespace
78-
if present.is_bit_set(29) {
79-
present_count = 0;
80-
vendor_namespace = false;
81-
82-
// Need to move to vendor namespace
83-
} else if present.is_bit_set(30) {
84-
present_count = 0;
85-
vendor_namespace = true;
86-
// We'll figure out what namespace it is later, just use none
87-
kinds.push(Kind::VendorNamespace(None))
88-
89-
// Need to stay in the same namespace
90-
} else {
91-
present_count += 1;
92-
}
93-
94-
// More present words do not exist
57+
kinds.push(present);
9558
if !present.is_bit_set(31) {
9659
break;
9760
}

0 commit comments

Comments
 (0)