pub struct Frame<'p> {
pub header: Header,
pub content: FrameContent,
pub payload: &'p [u8],
pub footer: [u8; 2],
}
Expand description
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.
Decode 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,
Address,
ShortAddress,
FrameType,
FooterMode,
PanId,
FrameSerDesContext,
};
use byte::BytesExt;
// Construct a simple MAC frame. The CRC checksum (the last 2 bytes) is
// invalid, for the sake of convenience.
let bytes = [
0x01u8, 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, // payload
];
let frame: Frame = bytes.read_with(&mut 0, FooterMode::Explicit).unwrap();
let header = frame.header;
assert_eq!(frame.header.seq, 0x00);
assert_eq!(header.frame_type, FrameType::Data);
assert_eq!(header.has_security(), false);
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]);
Encodes the frame into a buffer
Example
allocation allowed
use ieee802154::mac::{
Frame,
FrameContent,
FooterMode,
Address,
ShortAddress,
FrameType,
FrameVersion,
Header,
PanId,
FrameSerDesContext,
};
use byte::BytesExt;
let frame = Frame {
header: Header {
ie_present: false,
seq_no_suppress: false,
frame_type: FrameType::Data,
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))),
auxiliary_security_header: None,
},
content: FrameContent::Data,
payload: &[0xde, 0xf0],
footer: [0x12, 0x34]
};
// Work also with `let mut bytes = Vec::new()`;
let mut bytes = [0u8; 32];
let mut len = 0usize;
bytes.write_with(&mut len, frame, &mut FrameSerDesContext::no_security(FooterMode::Explicit)).unwrap();
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
0x12, 0x34 // footer
];
assert_eq!(bytes[..len], expected_bytes);
Fields
header: Header
Header
content: FrameContent
Content
payload: &'p [u8]
Payload
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::try_write
can omit writing this checksum, for example if the transceiver hardware
automatically adds the checksum for you.
Implementations
sourceimpl<'a> Frame<'a>
impl<'a> Frame<'a>
sourcepub fn try_read_and_unsecure<AEADBLKCIPH, KEYDESCLO, DEVDESCLO>(
buf: &'a mut [u8],
ctx: &mut FrameSerDesContext<'_, AEADBLKCIPH, KEYDESCLO>,
dev_desc_lo: &mut DEVDESCLO
) -> Result<(Frame<'a>, usize), SecurityError> where
AEADBLKCIPH: NewBlockCipher + BlockCipher<BlockSize = U16> + BlockEncrypt,
KEYDESCLO: KeyDescriptorLookup<AEADBLKCIPH::KeySize>,
DEVDESCLO: DeviceDescriptorLookup,
pub fn try_read_and_unsecure<AEADBLKCIPH, KEYDESCLO, DEVDESCLO>(
buf: &'a mut [u8],
ctx: &mut FrameSerDesContext<'_, AEADBLKCIPH, KEYDESCLO>,
dev_desc_lo: &mut DEVDESCLO
) -> Result<(Frame<'a>, usize), SecurityError> where
AEADBLKCIPH: NewBlockCipher + BlockCipher<BlockSize = U16> + BlockEncrypt,
KEYDESCLO: KeyDescriptorLookup<AEADBLKCIPH::KeySize>,
DEVDESCLO: DeviceDescriptorLookup,
Try to read a frame. If the frame is secured, it will be unsecured
Currently, this function does not support the explicit footer mode, as the FCS has to be calculated over the payload before it is unsecured, which isn’t implemented yet
Use FrameSerDesContext::no_security
and/or Unimplemented
if you
do not want to use any security, or simply Frame::try_read
Trait Implementations
sourceimpl<'p> PartialEq<Frame<'p>> for Frame<'p>
impl<'p> PartialEq<Frame<'p>> for Frame<'p>
sourcefn try_read(bytes: &'a [u8], mode: FooterMode) -> Result<(Self, usize)>
fn try_read(bytes: &'a [u8], mode: FooterMode) -> Result<(Self, usize)>
Try to read a frame
Frames that have security enabled can not be processed by this function, and an
error will be returned if the frame contained in bytes
does have it enabled.
If you expect to receive secured frames, use Frame::try_read_and_unsecure
instead,
sourceimpl<AEADBLKCIPH, KEYDESCLO> TryWrite<&mut FrameSerDesContext<'_, AEADBLKCIPH, KEYDESCLO>> for Frame<'_> where
AEADBLKCIPH: NewBlockCipher + BlockCipher<BlockSize = U16> + BlockEncrypt,
KEYDESCLO: KeyDescriptorLookup<AEADBLKCIPH::KeySize>,
impl<AEADBLKCIPH, KEYDESCLO> TryWrite<&mut FrameSerDesContext<'_, AEADBLKCIPH, KEYDESCLO>> for Frame<'_> where
AEADBLKCIPH: NewBlockCipher + BlockCipher<BlockSize = U16> + BlockEncrypt,
KEYDESCLO: KeyDescriptorLookup<AEADBLKCIPH::KeySize>,
impl<'p> Copy for Frame<'p>
impl<'p> Eq for Frame<'p>
impl<'p> StructuralEq for Frame<'p>
impl<'p> StructuralPartialEq for Frame<'p>
Auto Trait Implementations
impl<'p> RefUnwindSafe for Frame<'p>
impl<'p> Send for Frame<'p>
impl<'p> Sync for Frame<'p>
impl<'p> Unpin for Frame<'p>
impl<'p> UnwindSafe for Frame<'p>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more