@@ -16,7 +16,7 @@ use crate::mac::command::Command;
1616
1717mod frame_control;
1818pub mod header;
19- use byte:: { BytesExt , TryRead , TryWrite } ;
19+ use byte:: { ctx :: Bytes , BytesExt , TryRead , TryWrite , LE } ;
2020use header:: FrameType ;
2121pub use header:: Header ;
2222
@@ -49,34 +49,47 @@ pub struct Frame<'p> {
4949 pub footer : [ u8 ; 2 ] ,
5050}
5151
52- impl TryWrite for Frame < ' _ > {
53- fn try_write ( self , bytes : & mut [ u8 ] , _ctx : ( ) ) -> byte:: Result < usize > {
52+ impl TryWrite < FooterMode > for Frame < ' _ > {
53+ fn try_write ( self , bytes : & mut [ u8 ] , mode : FooterMode ) -> byte:: Result < usize > {
5454 let offset = & mut 0 ;
5555 bytes. write ( offset, self . header ) ?;
5656 bytes. write ( offset, self . content ) ?;
5757 bytes. write ( offset, self . payload ) ?;
58+ match mode {
59+ FooterMode :: None => { }
60+ FooterMode :: Explicit => bytes. write ( offset, & self . footer [ ..] ) ?,
61+ }
5862 Ok ( * offset)
5963 }
6064}
6165
62- impl < ' a > TryRead < ' a > for Frame < ' a > {
63- fn try_read ( bytes : & ' a [ u8 ] , _ctx : ( ) ) -> byte:: Result < ( Self , usize ) > {
66+ impl < ' a > TryRead < ' a , FooterMode > for Frame < ' a > {
67+ fn try_read ( bytes : & ' a [ u8 ] , mode : FooterMode ) -> byte:: Result < ( Self , usize ) > {
6468 let offset = & mut 0 ;
6569 let header = bytes. read ( offset) ?;
6670 let content = bytes. read_with ( offset, & header) ?;
71+ let ( payload, footer) = match mode {
72+ FooterMode :: None => (
73+ bytes. read_with ( offset, Bytes :: Len ( bytes. len ( ) - * offset) ) ?,
74+ 0u16 ,
75+ ) ,
76+ FooterMode :: Explicit => (
77+ bytes. read_with ( offset, Bytes :: Len ( bytes. len ( ) - * offset - 2 ) ) ?,
78+ bytes. read_with ( offset, LE ) ?,
79+ ) ,
80+ } ;
6781 Ok ( (
6882 Frame {
6983 header : header,
7084 content : content,
71- payload : & bytes [ * offset.. ] ,
72- footer : [ 0 ; 2 ] ,
85+ payload,
86+ footer : footer . to_le_bytes ( ) ,
7387 } ,
7488 * offset,
7589 ) )
7690 }
7791}
7892
79- // impl<'p> Frame<'p> {
8093/// Decodes a frame from a byte buffer
8194///
8295/// # Errors
@@ -88,15 +101,15 @@ impl<'a> TryRead<'a> for Frame<'a> {
88101/// # Example
89102///
90103/// ``` rust
91- /// use ieee802154::mac::frame:: {
104+ /// use ieee802154::mac::{
92105/// Frame,
93- /// header::{
94106/// Address,
95107/// ShortAddress,
96108/// FrameType,
109+ /// FooterMode,
97110/// PanId,
98111/// Security
99- /// }} ;
112+ /// };
100113/// use byte::BytesExt;
101114///
102115/// # fn main() -> Result<(), ::ieee802154::mac::frame::DecodeError> {
@@ -108,9 +121,10 @@ impl<'a> TryRead<'a> for Frame<'a> {
108121/// 0x12, 0x34, 0x56, 0x78, // PAN identifier and address of destination
109122/// 0x12, 0x34, 0x9a, 0xbc, // PAN identifier and address of source
110123/// 0xde, 0xf0, // payload
124+ /// 0x12, 0x34, // payload
111125/// ];
112126///
113- /// let frame: Frame = bytes.read (&mut 0).unwrap();
127+ /// let frame: Frame = bytes.read_with (&mut 0, FooterMode::Explicit ).unwrap();
114128/// let header = frame.header;
115129///
116130/// assert_eq!(frame.header.seq, 0x00);
@@ -130,6 +144,8 @@ impl<'a> TryRead<'a> for Frame<'a> {
130144/// );
131145///
132146/// assert_eq!(frame.payload, &[0xde, 0xf0]);
147+ ///
148+ /// assert_eq!(frame.footer, [0x12, 0x34]);
133149/// #
134150/// # Ok(())
135151/// # }
@@ -143,7 +159,7 @@ impl<'a> TryRead<'a> for Frame<'a> {
143159/// use ieee802154::mac::{
144160/// Frame,
145161/// FrameContent,
146- /// WriteFooter ,
162+ /// FooterMode ,
147163/// Address,
148164/// ShortAddress,
149165/// FrameType,
@@ -176,91 +192,40 @@ impl<'a> TryRead<'a> for Frame<'a> {
176192/// let mut bytes = [0u8; 32];
177193/// let mut len = 0usize;
178194///
179- /// bytes.write (&mut len, frame).unwrap();
195+ /// bytes.write_with (&mut len, frame, FooterMode::Explicit ).unwrap();
180196///
181197/// let expected_bytes = [
182198/// 0x01, 0x98, // frame control
183199/// 0x00, // sequence number
184200/// 0x34, 0x12, 0x78, 0x56, // PAN identifier and address of destination
185201/// 0x34, 0x12, 0xbc, 0x9a, // PAN identifier and address of source
186202/// 0xde, 0xf0, // payload
187- /// // footer, not written
203+ /// 0x12, 0x34 // footer
188204/// ];
189205/// assert_eq!(bytes[..len], expected_bytes);
190206/// ```
191- /// ## When allocation is not an option
192- ///
193- /// [`BufMut`] is implemented for `&mut [u8]` but there are common problems:
194- /// - panic when try put more data than capacity
195- /// - access to written bytes require some boilerplate
196- ///
197- /// We recommend to use [`SafeBytesSlice`] as wrapper.
198- ///
199- /// ``` rust
200- /// # use ieee802154::mac::{
201- /// # Frame,
202- /// # FrameContent,
203- /// # WriteFooter,
204- /// # Address,
205- /// # ShortAddress,
206- /// # FrameType,
207- /// # FrameVersion,
208- /// # Header,
209- /// # PanId,
210- /// # Security,
211- /// # };
212- /// # use byte::BytesExt;
213- /// #
214- /// # let frame = Frame {
215- /// # header: Header {
216- /// # frame_type: FrameType::Data,
217- /// # security: Security::None,
218- /// # frame_pending: false,
219- /// # ack_request: false,
220- /// # pan_id_compress: false,
221- /// # version: FrameVersion::Ieee802154_2006,
222- /// #
223- /// # seq: 0x00,
224- /// # destination: Some(Address::Short(PanId(0x1234), ShortAddress(0x5678))),
225- /// # source: Some(Address::Short(PanId(0x1234), ShortAddress(0x9abc))),
226- /// # },
227- /// # content: FrameContent::Data,
228- /// # payload: &[0xde, 0xf0],
229- /// # footer: [0x12, 0x34]
230- /// # };
231- /// # let expected_bytes = [
232- /// # 0x01, 0x98, // frame control
233- /// # 0x00, // sequence number
234- /// # 0x34, 0x12, 0x78, 0x56, // PAN identifier and address of destination
235- /// # 0x34, 0x12, 0xbc, 0x9a, // PAN identifier and address of source
236- /// # 0xde, 0xf0, // payload
237- /// # // footer, not written
238- /// # ];
239- ///
240- /// /* Note */
241- /// /* variables `frame` and `expected_bytes` are the same as in example above */
242- ///
243- /// /* Example use raw `&mut [u8]` */
244- /// let mut bytes = [0u8; 64];
245- /// let mut len = 0usize;
246- /// // assume frame is the same as in example above
247- /// bytes.write(&mut len, frame);
248- /// assert_eq!(bytes[..len], expected_bytes);
249- /// ```
250207///
251- /// Tells [`Frame::encode`] whether to write the footer
208+ /// Tells [`Frame::encode`] whether to read/ write the footer
252209///
253210/// Eventually, this should support three options:
254- /// - Don't write the footer
255- /// - Calculate the 2-byte CRC checksum and write that as the footer
256- /// - Write the footer as written into the `footer` field
211+ /// 1. Don't read or write the footer
212+ /// 2. Calculate the 2-byte CRC checksum and write that as the footer or check against read value
213+ /// 3. Read into or write the footer from the `footer` field
257214///
258- /// For now, only not writing the footer is supported.
215+ /// For now, only 1 and 3 are supported.
259216///
260217/// [`Frame::encode`](Frame::encode)
261- pub enum WriteFooter {
262- /// Don't write the footer
263- No ,
218+ pub enum FooterMode {
219+ /// Don't read/write the footer
220+ None ,
221+ /// Read into or write the footer from the `footer` field
222+ Explicit ,
223+ }
224+
225+ impl Default for FooterMode {
226+ fn default ( ) -> Self {
227+ Self :: None
228+ }
264229}
265230
266231/// Content of a frame
@@ -387,10 +352,7 @@ mod tests {
387352 let frame = data. read :: < Frame > ( & mut 0 ) ;
388353 assert ! ( frame. is_err( ) ) ;
389354 if let Err ( e) = frame {
390- assert_eq ! (
391- e,
392- DecodeError :: InvalidAddressMode ( 0 ) . into( )
393- )
355+ assert_eq ! ( e, DecodeError :: InvalidAddressMode ( 0 ) . into( ) )
394356 }
395357 }
396358
0 commit comments