[][src]Struct ieee802154::mac::frame::Frame

pub struct Frame<'p> {
    pub header: Header,
    pub content: FrameContent,
    pub payload: &'p [u8],
    pub footer: [u8; 2],
}

An IEEE 802.15.4 MAC frame

Represents a MAC frame. Can be used to decode a frame from bytes, or encode a frame to bytes.

Fields

header: Header

Header

content: FrameContent

Content

payload: &'p [u8]

Payload

footer: [u8; 2]

Footer

This is a 2-byte CRC checksum.

When creating an instance of this struct for encoding, you don't necessarily need to write an actual CRC checksum here. Frame::encode can omit writing this checksum, for example if the transceiver hardware automatically adds the checksum for you.

Implementations

impl<'p> Frame<'p>[src]

pub fn decode(buf: &'p [u8], contains_footer: bool) -> Result<Self, DecodeError>[src]

Decodes a frame from a byte buffer

Errors

This function returns an error, if the bytes either don't encode a valid IEEE 802.15.4 frame, or encode a frame that is not fully supported by this implementation. Please refer to DecodeError for details.

Example

use ieee802154::mac::frame::{
    Frame,
    header::{
      Address,
      ShortAddress,
      FrameType,
      PanId,
      Security
}};

// Construct a simple MAC frame. The CRC checksum (the last 2 bytes) is
// invalid, for the sake of convenience.
let bytes = [
    0x01, 0x98,             // frame control
    0x00,                   // sequence number
    0x12, 0x34, 0x56, 0x78, // PAN identifier and address of destination
    0x12, 0x34, 0x9a, 0xbc, // PAN identifier and address of source
    0xde, 0xf0,             // payload
    0x12, 0x34,             // footer
];

let frame = Frame::decode(&bytes, true)?;
let header = frame.header;

assert_eq!(frame.header.seq,       0x00);
assert_eq!(header.frame_type,      FrameType::Data);
assert_eq!(header.security,        Security::None);
assert_eq!(header.frame_pending,   false);
assert_eq!(header.ack_request,     false);
assert_eq!(header.pan_id_compress, false);

assert_eq!(
    frame.header.destination,
    Some(Address::Short(PanId(0x3412), ShortAddress(0x7856)))
);
assert_eq!(
    frame.header.source,
    Some(Address::Short(PanId(0x3412), ShortAddress(0xbc9a)))
);

assert_eq!(frame.payload, &[0xde, 0xf0]);
assert_eq!(frame.footer,  [0x12, 0x34]);

pub fn encode(&self, buf: &mut dyn BufMut, write_footer: WriteFooter)[src]

Encodes the frame into a buffer

Example

allocation allowed

use ieee802154::mac::{
  Frame,
  FrameContent,
  WriteFooter,
  Address,
  ShortAddress,
  FrameType,
  FrameVersion,
  Header,
  PanId,
  Security,
};

let frame = Frame {
    header: Header {
        frame_type:      FrameType::Data,
        security:        Security::None,
        frame_pending:   false,
        ack_request:     false,
        pan_id_compress: false,
        version:         FrameVersion::Ieee802154_2006,

        seq:             0x00,
        destination: Some(Address::Short(PanId(0x1234), ShortAddress(0x5678))),
        source:      Some(Address::Short(PanId(0x1234), ShortAddress(0x9abc))),
    },
    content: FrameContent::Data,
    payload: &[0xde, 0xf0],
    footer:  [0x12, 0x34]
};

// Work also with `let mut bytes = Vec::new()`;
let mut bytes = bytes::BytesMut::with_capacity(32);

frame.encode(&mut bytes, WriteFooter::No);
let encoded_bytes = bytes.split().freeze();

let expected_bytes = [
    0x01, 0x98,             // frame control
    0x00,                   // sequence number
    0x34, 0x12, 0x78, 0x56, // PAN identifier and address of destination
    0x34, 0x12, 0xbc, 0x9a, // PAN identifier and address of source
    0xde, 0xf0,             // payload
   // footer, not written
];
assert_eq!(encoded_bytes[..], expected_bytes[..]);

When allocation is not an option

BufMut is implemented for &mut [u8] but there are common problems:

  • panic when try put more data than capacity
  • access to written bytes require some boilerplate

We recommend to use SafeBytesSlice as wrapper.


/* Note */
/* variables `frame` and `expected_bytes` are the same as in example above */

/* Example use raw `&mut [u8]`  */
let mut bytes = [0u8; 64];
let mut slice = &mut bytes[..];
let org_bytes_size = slice.len();
// assume frame is the same as in example above
// This function will panic if encode want to put more than bytes.len() ⚠️
frame.encode(&mut slice, WriteFooter::No);
let written_bytes = org_bytes_size - slice.len();
let encoded_bytes = &bytes[..written_bytes];
assert_eq!(expected_bytes[..], encoded_bytes[..]);

/* Example that use SafeBytesSlice */
use static_bytes::SafeBytesSlice;
use core::mem::MaybeUninit;
// a small optimization. SafeBytesSlice works also with `let mut uninit_bytes = [0u8; 64];`
let mut uninit_bytes: [MaybeUninit<u8>; 64] = unsafe { MaybeUninit::uninit().assume_init() };
let mut safce_slice = SafeBytesSlice::from(&mut uninit_bytes[..]);
frame.encode(&mut safce_slice, WriteFooter::No);
// no panic 🦀
// no manually bytes counting 🦀
match safce_slice.try_into_bytes() {
   Ok(bytes) => assert_eq!(bytes[..], expected_bytes[..]),
   Err(_err) => todo!("handle not enough capacity"),
};

Trait Implementations

impl<'p> Clone for Frame<'p>[src]

impl<'p> Copy for Frame<'p>[src]

impl<'p> Debug for Frame<'p>[src]

impl<'p> Eq for Frame<'p>[src]

impl<'p> Hash for Frame<'p>[src]

impl<'p> PartialEq<Frame<'p>> for Frame<'p>[src]

impl<'p> StructuralEq for Frame<'p>[src]

impl<'p> StructuralPartialEq for Frame<'p>[src]

Auto Trait Implementations

impl<'p> Send for Frame<'p>

impl<'p> Sync for Frame<'p>

impl<'p> Unpin for Frame<'p>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.