ieee80211/frames/data_frame/
amsdu.rs1use mac_parser::MACAddress;
2use scroll::{
3 ctx::{MeasureWith, TryFromCtx, TryIntoCtx},
4 Endian, Pread, Pwrite,
5};
6
7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
8#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
9pub struct AMSDUSubframe<Payload> {
14 pub destination_address: MACAddress,
15 pub source_address: MACAddress,
16 pub payload: Payload,
19}
20impl AMSDUSubframe<&'_ [u8]> {
21 pub const fn length_in_bytes(&self) -> usize {
24 14 + self.payload.len()
25 }
26}
27impl<Payload: MeasureWith<()>> MeasureWith<()> for AMSDUSubframe<Payload> {
28 fn measure_with(&self, ctx: &()) -> usize {
29 14 + self.payload.measure_with(ctx)
30 }
31}
32impl<'a> TryFromCtx<'a> for AMSDUSubframe<&'a [u8]> {
33 type Error = scroll::Error;
34 fn try_from_ctx(from: &'a [u8], _ctx: ()) -> Result<(Self, usize), Self::Error> {
35 let mut offset = 0;
36
37 let destination_address = from.gread(&mut offset)?;
38 let source_address = from.gread(&mut offset)?;
39 let length = from.gread_with::<u16>(&mut offset, Endian::Little)?;
40 let payload = from.gread_with(&mut offset, length as usize)?;
41 offset += 3;
43 offset &= !0b0000_0011;
44 Ok((
45 Self {
46 destination_address,
47 source_address,
48 payload,
49 },
50 offset,
51 ))
52 }
53}
54impl<Payload: TryIntoCtx<Error = scroll::Error> + MeasureWith<()>> TryIntoCtx
55 for AMSDUSubframe<Payload>
56{
57 type Error = scroll::Error;
58 fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
59 let mut offset = 0;
60
61 buf.gwrite(self.destination_address, &mut offset)?;
62 buf.gwrite(self.source_address, &mut offset)?;
63 buf.gwrite_with(
64 self.payload.measure_with(&()) as u16,
65 &mut offset,
66 Endian::Little,
67 )?;
68 buf.gwrite(self.payload, &mut offset)?;
69 offset += 3;
71 offset &= !0b0000_0011;
72
73 Ok(offset)
74 }
75}
76
77#[cfg_attr(feature = "defmt", derive(defmt::Format))]
78#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
79pub struct AMSDUSubframeIterator<'a> {
84 pub(crate) bytes: Option<&'a [u8]>,
86}
87impl<'a> AMSDUSubframeIterator<'a> {
88 pub const fn from_bytes(bytes: &'a [u8]) -> Self {
90 Self { bytes: Some(bytes) }
91 }
92 pub const fn length_in_bytes(&self) -> usize {
94 match self.bytes {
95 Some(bytes) => bytes.len(),
96 None => 0,
97 }
98 }
99}
100impl<'a> Iterator for AMSDUSubframeIterator<'a> {
101 type Item = AMSDUSubframe<&'a [u8]>;
102 fn next(&mut self) -> Option<Self::Item> {
103 let mut offset = 0;
104 let bytes = self.bytes?;
105 let sub_frame = bytes.gread(&mut offset).ok();
106 match sub_frame {
107 Some(sub_frame) => {
108 self.bytes = Some(&bytes[offset..]);
109 Some(sub_frame)
110 }
111 None => {
112 self.bytes = None;
113 None
114 }
115 }
116 }
117}
118#[cfg_attr(feature = "defmt", derive(defmt::Format))]
119#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
120pub struct AMSDUPayload<Frames> {
125 pub sub_frames: Frames,
126}
127impl<'a> AMSDUPayload<&'a [AMSDUSubframe<&'a [u8]>]> {
128 pub const fn length_in_bytes(&self) -> usize {
130 let mut size = 0;
131 let mut i = 0;
132 while i != self.sub_frames.len() {
133 size += self.sub_frames[i].length_in_bytes();
134 i += 1;
135 }
136 size
137 }
138}
139impl<Frames: IntoIterator<Item = Payload> + Clone, Payload: MeasureWith<()>> MeasureWith<()>
140 for AMSDUPayload<Frames>
141{
142 fn measure_with(&self, _ctx: &()) -> usize {
143 self.sub_frames
144 .clone()
145 .into_iter()
146 .map(|sub_frame| sub_frame.measure_with(&()))
147 .sum()
148 }
149}
150impl<Frames: IntoIterator<Item = Payload>, Payload: Copy + TryIntoCtx<Error = scroll::Error>>
151 TryIntoCtx for AMSDUPayload<Frames>
152{
153 type Error = scroll::Error;
154 fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
155 let mut offset = 0;
156 for sub_frame in self.sub_frames.into_iter() {
157 buf.gwrite(sub_frame, &mut offset)?;
158 }
159 Ok(offset)
160 }
161}