Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ readme = "README.md"
categories = ["embedded", "network-programming", "no-std"]
keywords = ["WPAN"]

[features]


[badges]
travis-ci = { repository = "braun-robotics/ieee802154" }
Expand All @@ -23,7 +25,9 @@ hash32-derive = "0.1"
byte = "0.2.4"
cipher = { version = "0.2", default-features = false }
ccm = {version = "0.3.0", default-features = false}
defmt = { version = "0.2.1", optional = true }

[dev-dependencies]
aes-soft = {version = "0.6.4", default-features = false}
rand = "0.8.3"

8 changes: 8 additions & 0 deletions src/mac/beacon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::mac::{ExtendedAddress, ShortAddress};

/// Beacon order is used to calculate the beacon interval
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum BeaconOrder {
/// Used to calculate at which interval beacons are sent
///
Expand Down Expand Up @@ -41,6 +42,7 @@ impl From<BeaconOrder> for u8 {

/// Superframe order, amount of time during wich this superframe is active
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum SuperframeOrder {
/// Ammount of time that the superframe is active
///
Expand Down Expand Up @@ -75,6 +77,7 @@ impl From<SuperframeOrder> for u8 {
/// The superframe specification describes the organisation of frames in the
/// air when using superframes and/or periodical beacons.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct SuperframeSpecification {
/// Beacon order, 0-15, where 15 is on demand.
///
Expand Down Expand Up @@ -150,6 +153,7 @@ impl TryWrite for SuperframeSpecification {

/// Direction of data
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
enum Direction {
/// Receive data
Receive,
Expand All @@ -159,6 +163,7 @@ enum Direction {

/// Descriptor of the guaranteed time slots (GTSs)
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GuaranteedTimeSlotDescriptor {
/// Device short address used by this slot
short_address: ShortAddress,
Expand Down Expand Up @@ -228,6 +233,7 @@ const PERMIT: u8 = 0b1000_0000;

/// Information of the guaranteed time slots (GTSs)
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GuaranteedTimeSlotInformation {
/// Permit GTS
pub permit: bool,
Expand Down Expand Up @@ -345,6 +351,7 @@ const EXTENDED_MASK: u8 = 0b0111_0000;
/// 0 - 2 3 4 - 6 7 bit
/// ```
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PendingAddress {
short_address_count: usize,
short_addresses: [ShortAddress; 7],
Expand Down Expand Up @@ -429,6 +436,7 @@ impl TryWrite for PendingAddress {

/// Beacon frame
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Beacon {
/// Superframe specification
pub superframe_spec: SuperframeSpecification,
Expand Down
4 changes: 4 additions & 0 deletions src/mac/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const CAP_ALLOCATE_ADDRESS: u8 = 0x80;
///
/// Sent with association request to report the capabilities of the device.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CapabilityInformation {
/// Full-function device (FFD) or a reduced-function device (RFD)
/// RFD and FFD have different function sets.
Expand Down Expand Up @@ -123,6 +124,7 @@ extended_enum!(
///
/// Changes to the PAN sent by the coordinator.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct CoordinatorRealignmentData {
/// PAN id that the coordinator will use
pub pan_id: PanId,
Expand Down Expand Up @@ -183,6 +185,7 @@ const GTSC_ALLOCATION: u8 = 0x20;
///
/// GTS configuration requested with the guaranteed time slot request command.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GuaranteedTimeSlotCharacteristics {
/// Number of slots requested
pub count: u8,
Expand Down Expand Up @@ -219,6 +222,7 @@ impl From<GuaranteedTimeSlotCharacteristics> for u8 {

/// MAC commands
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Command {
/// Association request, request association to a PAN
AssociationRequest(CapabilityInformation),
Expand Down
19 changes: 19 additions & 0 deletions src/mac/frame/frame_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use super::DecodeError;
///
/// [`Header`]: super::header::Header
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FrameType {
/// Beacon
Beacon = 0b000,
Expand All @@ -20,6 +21,15 @@ pub enum FrameType {

/// MAC command
MacCommand = 0b011,

/// Multipurpose
Multipurpose = 0b101,

/// Fragment of Fragment Ack
FragOrFragAck = 0b110,

/// Extended
Extended = 0b111,
}

impl FrameType {
Expand All @@ -41,13 +51,17 @@ impl FrameType {
0b001 => Some(FrameType::Data),
0b010 => Some(FrameType::Acknowledgement),
0b011 => Some(FrameType::MacCommand),
0b101 => Some(FrameType::Multipurpose),
0b110 => Some(FrameType::FragOrFragAck),
0b111 => Some(FrameType::Extended),
_ => None,
}
}
}

/// Defines version information for a frame
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FrameVersion {
/// A frame conforming to the 802.15.4-2003 standard
Ieee802154_2003 = 0b00,
Expand Down Expand Up @@ -92,6 +106,7 @@ impl FrameVersion {
/// assert_eq!(address_mode, AddressMode::Short);
/// ```
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum AddressMode {
/// PAN identifier and address field are not present
None = 0b00,
Expand Down Expand Up @@ -150,6 +165,8 @@ pub mod offset {
pub const PENDING: u16 = 4;
pub const ACK: u16 = 5;
pub const PAN_ID_COMPRESS: u16 = 6;
pub const SEQ_NO_SUPPRESS: u16 = 8;
pub const IE_PRESENT: u16 = 9;
pub const DEST_ADDR_MODE: u16 = 10;
pub const VERSION: u16 = 12;
pub const SRC_ADDR_MODE: u16 = 14u16;
Expand All @@ -161,6 +178,8 @@ pub mod mask {
pub const PENDING: u16 = 0x0010;
pub const ACK: u16 = 0x0020;
pub const PAN_ID_COMPRESS: u16 = 0x0040;
pub const SEQ_NO_SUPPRESS: u16 = 0x0100;
pub const IE_PRESENT: u16 = 0x0200;
pub const DEST_ADDR_MODE: u16 = 0x0C00;
pub const VERSION: u16 = 0x3000;
pub const SRC_ADDR_MODE: u16 = 0xC000;
Expand Down
19 changes: 19 additions & 0 deletions src/mac/frame/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use super::{security::AuxiliarySecurityHeader, EncodeError};
///
/// [MAC frame format start at 5.2]: http://ecee.colorado.edu/~liue/teaching/comm_standards/2015S_zigbee/802.15.4-2011.pdf
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Header {
// * Frame Control Field * /
/// Frame Type
Expand Down Expand Up @@ -51,6 +52,12 @@ pub struct Header {
/// present.
pub pan_id_compress: bool,

/// Suppress sequence number
pub seq_no_suppress: bool,

/// Information element present
pub ie_present: bool,

/// Frame version
pub version: FrameVersion,

Expand Down Expand Up @@ -120,6 +127,9 @@ impl TryRead<'_> for Header {
let ack_request = ((bits & mask::ACK) >> offset::ACK) as u8;
let pan_id_compress = ((bits & mask::PAN_ID_COMPRESS) >> offset::PAN_ID_COMPRESS) as u8;

let seq_no_suppress = ((bits & mask::SEQ_NO_SUPPRESS) >> offset::SEQ_NO_SUPPRESS) as u8;
let ie_present = ((bits & mask::IE_PRESENT) >> offset::IE_PRESENT) as u8;

let dest_addr_mode = ((bits & mask::DEST_ADDR_MODE) >> offset::DEST_ADDR_MODE) as u8;
let version = ((bits & mask::VERSION) >> offset::VERSION) as u8;
let src_addr_mode = ((bits & mask::SRC_ADDR_MODE) >> offset::SRC_ADDR_MODE) as u8;
Expand All @@ -136,6 +146,8 @@ impl TryRead<'_> for Header {
let frame_pending = frame_pending > 0;
let ack_request = ack_request > 0;
let pan_id_compress = pan_id_compress > 0;
let seq_no_suppress = seq_no_suppress > 0;
let ie_present = ie_present > 0;

/* Decode header depending on Frame Control Fields */

Expand Down Expand Up @@ -189,6 +201,8 @@ impl TryRead<'_> for Header {
frame_pending,
ack_request,
pan_id_compress,
seq_no_suppress,
ie_present,
version,
seq,
destination,
Expand Down Expand Up @@ -278,6 +292,7 @@ where
/// let pan_id = PanId(0x0123);
/// ```
#[derive(Clone, Copy, Debug, Eq, Hash, Hash32, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PanId(pub u16);

impl PanId {
Expand Down Expand Up @@ -315,6 +330,7 @@ impl TryRead<'_> for PanId {
/// let short_address = ShortAddress(0x0123);
/// ```
#[derive(Clone, Copy, Debug, Eq, Hash, Hash32, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ShortAddress(pub u16);

impl ShortAddress {
Expand Down Expand Up @@ -354,6 +370,7 @@ impl TryRead<'_> for ShortAddress {
/// let ext_address = ExtendedAddress(0x0123456789abcdef);
/// ```
#[derive(Clone, Copy, Debug, Eq, Hash, Hash32, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ExtendedAddress(pub u64);

impl ExtendedAddress {
Expand Down Expand Up @@ -383,6 +400,7 @@ impl TryRead<'_> for ExtendedAddress {

/// An address that might contain an PAN ID and address
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Address {
/// Short (16-bit) address and PAN ID (16-bit)
Short(PanId, ShortAddress),
Expand All @@ -391,6 +409,7 @@ pub enum Address {
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
enum AddressEncoding {
Normal,
Compressed,
Expand Down
18 changes: 17 additions & 1 deletion src/mac/frame/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ use self::security::{
/// [decode]: #method.try_read
/// [encode]: #method.try_write
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Frame<'p> {
/// Header
pub header: Header,
Expand Down Expand Up @@ -367,6 +368,7 @@ impl<'a> TryRead<'a, FooterMode> for Frame<'a> {
///
/// [`Frame::try_write`](Frame::try_write)
#[derive(Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FooterMode {
/// Don't read/write the footer
None,
Expand All @@ -382,6 +384,7 @@ impl Default for FooterMode {

/// Content of a frame
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FrameContent {
/// Beacon frame content
Beacon(Beacon),
Expand All @@ -391,15 +394,23 @@ pub enum FrameContent {
Acknowledgement,
/// MAC command frame
Command(Command),
/// Multipurpose frame
Multipurpose,

/// Fragment of Fragment Ack frame
FragOrFragAck,

/// Extended frame
Extended,
}

impl TryWrite for FrameContent {
fn try_write(self, bytes: &mut [u8], _ctx: ()) -> byte::Result<usize> {
let offset = &mut 0;
match self {
FrameContent::Beacon(beacon) => bytes.write(offset, beacon)?,
FrameContent::Data | FrameContent::Acknowledgement => (),
FrameContent::Command(command) => bytes.write(offset, command)?,
_ => (),
};
Ok(*offset)
}
Expand All @@ -414,6 +425,9 @@ impl TryRead<'_, &Header> for FrameContent {
FrameType::Data => FrameContent::Data,
FrameType::Acknowledgement => FrameContent::Acknowledgement,
FrameType::MacCommand => FrameContent::Command(bytes.read(offset)?),
FrameType::Multipurpose => FrameContent::Multipurpose,
FrameType::FragOrFragAck => FrameContent::FragOrFragAck,
FrameType::Extended => FrameContent::Extended,
},
*offset,
))
Expand All @@ -422,6 +436,7 @@ impl TryRead<'_, &Header> for FrameContent {

/// Signals an error that occured while decoding bytes
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum DecodeError {
/// Buffer does not contain enough bytes
NotEnoughBytes,
Expand Down Expand Up @@ -491,6 +506,7 @@ impl From<DecodeError> for byte::Error {

/// Errors that can occur while securing or unsecuring a frame
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum EncodeError {
/// Something went wrong while writing a frame's bytes to the destination
WriteError,
Expand Down
3 changes: 3 additions & 0 deletions src/mac/frame/security/auxiliary_security_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use cipher::{consts::U16, BlockCipher, NewBlockCipher};
///
/// See: section 7.4
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct AuxiliarySecurityHeader {
/// The control field in the Auxiliary Security Header
pub control: SecurityControl,
Expand Down Expand Up @@ -147,6 +148,7 @@ where

/// A key identifier
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct KeyIdentifier {
/// The key source to be used for determining a key from this key identifier (if any)
pub key_source: Option<KeySource>,
Expand All @@ -173,6 +175,7 @@ impl TryWrite for KeyIdentifier {

/// A key source
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum KeySource {
/// A key source that is 4 octets long
Short(u32),
Expand Down
1 change: 1 addition & 0 deletions src/mac/frame/security/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ pub enum AddressingMode {
}

#[derive(Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// A partial device descriptor
pub struct DeviceDescriptor {
/// The frame counter associated with this device
Expand Down
Loading