2021-03-02 21:20:00 +01:00
|
|
|
use core::task::Waker;
|
2022-06-12 22:15:44 +02:00
|
|
|
|
|
|
|
use smoltcp::phy::{Device as SmolDevice, DeviceCapabilities};
|
2021-02-03 05:09:37 +01:00
|
|
|
use smoltcp::time::Instant as SmolInstant;
|
|
|
|
|
2021-04-07 19:06:45 +02:00
|
|
|
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);
|
2022-05-23 03:50:43 +02:00
|
|
|
fn capabilities(&self) -> DeviceCapabilities;
|
2021-02-03 05:09:37 +01:00
|
|
|
fn link_state(&mut self) -> LinkState;
|
2022-05-02 16:15:05 +02:00
|
|
|
fn ethernet_address(&self) -> [u8; 6];
|
2021-02-03 05:09:37 +01:00
|
|
|
}
|
|
|
|
|
2022-12-07 00:28:38 +01:00
|
|
|
impl<T: ?Sized + Device> Device for &mut T {
|
2022-05-23 03:50:43 +02:00
|
|
|
fn is_transmit_ready(&mut self) -> bool {
|
|
|
|
T::is_transmit_ready(self)
|
|
|
|
}
|
|
|
|
fn transmit(&mut self, pkt: PacketBuf) {
|
|
|
|
T::transmit(self, pkt)
|
|
|
|
}
|
|
|
|
fn receive(&mut self) -> Option<PacketBuf> {
|
|
|
|
T::receive(self)
|
|
|
|
}
|
|
|
|
fn register_waker(&mut self, waker: &Waker) {
|
|
|
|
T::register_waker(self, waker)
|
|
|
|
}
|
|
|
|
fn capabilities(&self) -> DeviceCapabilities {
|
|
|
|
T::capabilities(self)
|
|
|
|
}
|
|
|
|
fn link_state(&mut self) -> LinkState {
|
|
|
|
T::link_state(self)
|
|
|
|
}
|
|
|
|
fn ethernet_address(&self) -> [u8; 6] {
|
|
|
|
T::ethernet_address(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct DeviceAdapter<D: Device> {
|
|
|
|
pub device: D,
|
2021-02-03 05:09:37 +01:00
|
|
|
caps: DeviceCapabilities,
|
|
|
|
}
|
|
|
|
|
2022-05-23 03:50:43 +02:00
|
|
|
impl<D: Device> DeviceAdapter<D> {
|
|
|
|
pub(crate) fn new(device: D) -> Self {
|
2021-02-03 05:09:37 +01:00
|
|
|
Self {
|
|
|
|
caps: device.capabilities(),
|
|
|
|
device,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 00:28:38 +01:00
|
|
|
impl<D: Device> SmolDevice for DeviceAdapter<D> {
|
|
|
|
type RxToken<'a> = RxToken where Self: 'a;
|
|
|
|
type TxToken<'a> = TxToken<'a, D> where Self: 'a;
|
2021-02-03 05:09:37 +01:00
|
|
|
|
2022-12-07 00:28:38 +01:00
|
|
|
fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
|
2021-06-14 23:06:12 +02:00
|
|
|
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 {
|
2022-05-23 03:50:43 +02:00
|
|
|
device: &mut self.device,
|
2021-02-03 05:09:37 +01:00
|
|
|
pkt: tx_pkt,
|
|
|
|
};
|
|
|
|
|
|
|
|
Some((rx_token, tx_token))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Construct a transmit token.
|
2022-12-07 00:28:38 +01:00
|
|
|
fn transmit(&mut self) -> Option<Self::TxToken<'_>> {
|
2021-02-03 05:09:37 +01:00
|
|
|
if !self.device.is_transmit_ready() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
let tx_pkt = PacketBox::new(Packet::new())?;
|
|
|
|
Some(TxToken {
|
2022-05-23 03:50:43 +02:00
|
|
|
device: &mut self.device,
|
2021-02-03 05:09:37 +01:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-23 03:50:43 +02:00
|
|
|
pub struct TxToken<'a, D: Device> {
|
|
|
|
device: &'a mut D,
|
2021-02-03 05:09:37 +01:00
|
|
|
pkt: PacketBox,
|
|
|
|
}
|
|
|
|
|
2022-05-23 03:50:43 +02:00
|
|
|
impl<'a, D: Device> smoltcp::phy::TxToken for TxToken<'a, D> {
|
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)
|
|
|
|
}
|
|
|
|
}
|