#![cfg_attr(not(test), no_std)]
#![doc = include_str!("../README.md")]
#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
pub mod config;
mod buf;
mod meta;
#[cfg(feature = "async")]
use core::task::Waker;
pub use buf::PacketBuf;
pub use meta::PacketMeta;
#[cfg(feature = "packetmeta-timestamp")]
pub use meta::{Timestamp, TxTimestamp};
#[cfg(feature = "async")]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub struct NotSupported;
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum LinkState {
Down,
Up,
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[non_exhaustive]
pub enum Medium {
Ethernet,
Ip,
Ieee802154,
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum HardwareAddress {
Ethernet([u8; 6]),
Ip,
Ieee802154([u8; 8]),
}
impl HardwareAddress {
pub const fn medium(&self) -> Medium {
match self {
HardwareAddress::Ethernet(_) => Medium::Ethernet,
HardwareAddress::Ip => Medium::Ip,
HardwareAddress::Ieee802154(_) => Medium::Ieee802154,
}
}
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct ChecksumOffload {
pub rx: bool,
pub tx: bool,
}
impl ChecksumOffload {
pub const NONE: Self = Self { rx: false, tx: false };
pub const BOTH: Self = Self { rx: true, tx: true };
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChecksumCapabilities {
pub ipv4: ChecksumOffload,
pub udp: ChecksumOffload,
pub tcp: ChecksumOffload,
pub icmpv4: ChecksumOffload,
pub icmpv6: ChecksumOffload,
}
impl ChecksumCapabilities {
pub fn all_offloaded() -> Self {
ChecksumCapabilities {
ipv4: ChecksumOffload::BOTH,
udp: ChecksumOffload::BOTH,
tcp: ChecksumOffload::BOTH,
icmpv4: ChecksumOffload::BOTH,
icmpv6: ChecksumOffload::BOTH,
}
}
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct Capabilities {
pub medium: Medium,
pub max_transmission_unit: usize,
pub checksum: ChecksumCapabilities,
}
impl Default for Capabilities {
fn default() -> Self {
Self {
medium: Medium::Ethernet,
max_transmission_unit: 1514,
checksum: ChecksumCapabilities::default(),
}
}
}
pub trait Driver {
fn capabilities(&self) -> Capabilities;
fn hardware_address(&self) -> HardwareAddress;
fn link_state(&mut self) -> LinkState {
LinkState::Up
}
#[cfg(feature = "async")]
fn register_waker(&mut self, waker: &Waker) -> Result<(), NotSupported> {
let _ = waker;
Err(NotSupported)
}
fn receive(&mut self) -> Option<PacketBuf>;
fn can_transmit(&mut self) -> bool;
fn transmit(&mut self, buf: PacketBuf) -> Result<(), PacketBuf>;
#[cfg(feature = "packetmeta-timestamp")]
fn poll_tx_timestamp(&mut self) -> Option<TxTimestamp> {
None
}
fn set_multicast_filter(&mut self, addrs: &[[u8; 6]]) {
let _ = addrs;
}
}
impl<T: Driver + ?Sized> Driver for &mut T {
fn capabilities(&self) -> Capabilities {
T::capabilities(self)
}
fn hardware_address(&self) -> HardwareAddress {
T::hardware_address(self)
}
fn link_state(&mut self) -> LinkState {
T::link_state(self)
}
#[cfg(feature = "async")]
fn register_waker(&mut self, waker: &Waker) -> Result<(), NotSupported> {
T::register_waker(self, waker)
}
fn receive(&mut self) -> Option<PacketBuf> {
T::receive(self)
}
fn can_transmit(&mut self) -> bool {
T::can_transmit(self)
}
fn transmit(&mut self, buf: PacketBuf) -> Result<(), PacketBuf> {
T::transmit(self, buf)
}
#[cfg(feature = "packetmeta-timestamp")]
fn poll_tx_timestamp(&mut self) -> Option<TxTimestamp> {
T::poll_tx_timestamp(self)
}
fn set_multicast_filter(&mut self, addrs: &[[u8; 6]]) {
T::set_multicast_filter(self, addrs)
}
}