embassy/embassy-net/src/device.rs

104 lines
2.5 KiB
Rust
Raw Normal View History

2021-03-02 21:20:00 +01:00
use core::task::Waker;
2021-02-03 05:09:37 +01:00
use smoltcp::phy::Device as SmolDevice;
use smoltcp::phy::DeviceCapabilities;
use smoltcp::time::Instant as SmolInstant;
use crate::packet_pool::PacketBoxExt;
2021-03-02 21:20:00 +01:00
use crate::{Packet, PacketBox, PacketBuf};
2021-02-03 05:09:37 +01:00
#[derive(PartialEq, Eq, Clone, Copy)]
pub enum LinkState {
Down,
Up,
}
pub trait Device {
fn is_transmit_ready(&mut self) -> bool;
fn transmit(&mut self, pkt: PacketBuf);
fn receive(&mut self) -> Option<PacketBuf>;
fn register_waker(&mut self, waker: &Waker);
fn capabilities(&mut self) -> DeviceCapabilities;
fn link_state(&mut self) -> LinkState;
fn ethernet_address(&self) -> [u8; 6];
2021-02-03 05:09:37 +01:00
}
pub struct DeviceAdapter {
pub device: &'static mut dyn Device,
caps: DeviceCapabilities,
}
impl DeviceAdapter {
pub(crate) fn new(device: &'static mut dyn Device) -> Self {
Self {
caps: device.capabilities(),
device,
}
}
}
impl<'a> SmolDevice<'a> for DeviceAdapter {
type RxToken = RxToken;
type TxToken = TxToken<'a>;
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
let tx_pkt = PacketBox::new(Packet::new())?;
2021-02-03 05:09:37 +01:00
let rx_pkt = self.device.receive()?;
let rx_token = RxToken { pkt: rx_pkt };
let tx_token = TxToken {
device: self.device,
pkt: tx_pkt,
};
Some((rx_token, tx_token))
}
/// Construct a transmit token.
fn transmit(&'a mut self) -> Option<Self::TxToken> {
if !self.device.is_transmit_ready() {
return None;
}
let tx_pkt = PacketBox::new(Packet::new())?;
Some(TxToken {
device: self.device,
pkt: tx_pkt,
})
}
/// Get a description of device capabilities.
fn capabilities(&self) -> DeviceCapabilities {
self.caps.clone()
}
}
pub struct RxToken {
pkt: PacketBuf,
}
impl smoltcp::phy::RxToken for RxToken {
2022-05-04 20:48:37 +02:00
fn consume<R, F>(mut self, _timestamp: SmolInstant, f: F) -> smoltcp::Result<R>
2021-02-03 05:09:37 +01:00
where
2022-05-04 20:48:37 +02:00
F: FnOnce(&mut [u8]) -> smoltcp::Result<R>,
2021-02-03 05:09:37 +01:00
{
f(&mut self.pkt)
}
}
pub struct TxToken<'a> {
device: &'a mut dyn Device,
pkt: PacketBox,
}
impl<'a> smoltcp::phy::TxToken for TxToken<'a> {
2022-05-04 20:48:37 +02:00
fn consume<R, F>(self, _timestamp: SmolInstant, len: usize, f: F) -> smoltcp::Result<R>
2021-02-03 05:09:37 +01:00
where
2022-05-04 20:48:37 +02:00
F: FnOnce(&mut [u8]) -> smoltcp::Result<R>,
2021-02-03 05:09:37 +01:00
{
let mut buf = self.pkt.slice(0..len);
let r = f(&mut buf)?;
self.device.transmit(buf);
Ok(r)
}
}