2022-12-07 15:55:46 +01:00
|
|
|
use core::task::Context;
|
2022-06-12 22:15:44 +02:00
|
|
|
|
2022-12-26 03:33:49 +01:00
|
|
|
use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken};
|
2022-12-07 15:55:46 +01:00
|
|
|
use smoltcp::phy;
|
2023-01-18 09:56:38 +01:00
|
|
|
use smoltcp::time::Instant;
|
2021-02-03 05:09:37 +01:00
|
|
|
|
2022-12-26 03:33:49 +01:00
|
|
|
pub(crate) struct DriverAdapter<'d, 'c, T>
|
2022-12-07 15:55:46 +01:00
|
|
|
where
|
2022-12-26 03:33:49 +01:00
|
|
|
T: Driver,
|
2022-12-07 15:55:46 +01:00
|
|
|
{
|
|
|
|
// must be Some when actually using this to rx/tx
|
|
|
|
pub cx: Option<&'d mut Context<'c>>,
|
|
|
|
pub inner: &'d mut T,
|
2021-02-03 05:09:37 +01:00
|
|
|
}
|
|
|
|
|
2022-12-26 03:33:49 +01:00
|
|
|
impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T>
|
2022-12-07 15:55:46 +01:00
|
|
|
where
|
2022-12-26 03:33:49 +01:00
|
|
|
T: Driver,
|
2022-12-07 15:55:46 +01:00
|
|
|
{
|
|
|
|
type RxToken<'a> = RxTokenAdapter<T::RxToken<'a>> where Self: 'a;
|
|
|
|
type TxToken<'a> = TxTokenAdapter<T::TxToken<'a>> where Self: 'a;
|
2021-02-03 05:09:37 +01:00
|
|
|
|
2023-01-18 09:56:38 +01:00
|
|
|
fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
|
2022-12-07 15:55:46 +01:00
|
|
|
self.inner
|
|
|
|
.receive(self.cx.as_deref_mut().unwrap())
|
|
|
|
.map(|(rx, tx)| (RxTokenAdapter(rx), TxTokenAdapter(tx)))
|
2021-02-03 05:09:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Construct a transmit token.
|
2023-01-18 09:56:38 +01:00
|
|
|
fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
|
2022-12-07 15:55:46 +01:00
|
|
|
self.inner.transmit(self.cx.as_deref_mut().unwrap()).map(TxTokenAdapter)
|
2021-02-03 05:09:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get a description of device capabilities.
|
2022-12-07 15:55:46 +01:00
|
|
|
fn capabilities(&self) -> phy::DeviceCapabilities {
|
2022-12-26 03:33:49 +01:00
|
|
|
fn convert(c: Checksum) -> phy::Checksum {
|
|
|
|
match c {
|
|
|
|
Checksum::Both => phy::Checksum::Both,
|
|
|
|
Checksum::Tx => phy::Checksum::Tx,
|
|
|
|
Checksum::Rx => phy::Checksum::Rx,
|
|
|
|
Checksum::None => phy::Checksum::None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let caps: Capabilities = self.inner.capabilities();
|
|
|
|
let mut smolcaps = phy::DeviceCapabilities::default();
|
|
|
|
|
|
|
|
smolcaps.max_transmission_unit = caps.max_transmission_unit;
|
|
|
|
smolcaps.max_burst_size = caps.max_burst_size;
|
|
|
|
smolcaps.medium = match caps.medium {
|
|
|
|
#[cfg(feature = "medium-ethernet")]
|
|
|
|
Medium::Ethernet => phy::Medium::Ethernet,
|
|
|
|
#[cfg(feature = "medium-ip")]
|
|
|
|
Medium::Ip => phy::Medium::Ip,
|
2023-06-26 01:59:25 +02:00
|
|
|
#[allow(unreachable_patterns)]
|
2022-12-26 03:33:49 +01:00
|
|
|
_ => panic!(
|
2023-06-26 01:59:25 +02:00
|
|
|
"Unsupported medium {:?}. Make sure to enable it in embassy-net's Cargo features.",
|
2022-12-26 03:33:49 +01:00
|
|
|
caps.medium
|
|
|
|
),
|
|
|
|
};
|
|
|
|
smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4);
|
|
|
|
smolcaps.checksum.tcp = convert(caps.checksum.tcp);
|
|
|
|
smolcaps.checksum.udp = convert(caps.checksum.udp);
|
2023-06-05 16:00:53 +02:00
|
|
|
#[cfg(feature = "proto-ipv4")]
|
|
|
|
{
|
|
|
|
smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4);
|
|
|
|
}
|
2023-01-24 09:57:26 +01:00
|
|
|
#[cfg(feature = "proto-ipv6")]
|
|
|
|
{
|
|
|
|
smolcaps.checksum.icmpv6 = convert(caps.checksum.icmpv6);
|
|
|
|
}
|
2022-12-26 03:33:49 +01:00
|
|
|
|
|
|
|
smolcaps
|
2021-02-03 05:09:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 15:55:46 +01:00
|
|
|
pub(crate) struct RxTokenAdapter<T>(T)
|
|
|
|
where
|
|
|
|
T: RxToken;
|
2021-02-03 05:09:37 +01:00
|
|
|
|
2022-12-07 15:55:46 +01:00
|
|
|
impl<T> phy::RxToken for RxTokenAdapter<T>
|
|
|
|
where
|
|
|
|
T: RxToken,
|
|
|
|
{
|
2023-01-18 09:56:38 +01:00
|
|
|
fn consume<R, F>(self, f: F) -> R
|
2021-02-03 05:09:37 +01:00
|
|
|
where
|
2023-01-18 09:56:38 +01:00
|
|
|
F: FnOnce(&mut [u8]) -> R,
|
2021-02-03 05:09:37 +01:00
|
|
|
{
|
2022-12-07 15:55:46 +01:00
|
|
|
self.0.consume(|buf| f(buf))
|
2021-02-03 05:09:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 15:55:46 +01:00
|
|
|
pub(crate) struct TxTokenAdapter<T>(T)
|
|
|
|
where
|
|
|
|
T: TxToken;
|
2021-02-03 05:09:37 +01:00
|
|
|
|
2022-12-07 15:55:46 +01:00
|
|
|
impl<T> phy::TxToken for TxTokenAdapter<T>
|
|
|
|
where
|
|
|
|
T: TxToken,
|
|
|
|
{
|
2023-01-18 09:56:38 +01:00
|
|
|
fn consume<R, F>(self, len: usize, f: F) -> R
|
2021-02-03 05:09:37 +01:00
|
|
|
where
|
2023-01-18 09:56:38 +01:00
|
|
|
F: FnOnce(&mut [u8]) -> R,
|
2021-02-03 05:09:37 +01:00
|
|
|
{
|
2022-12-07 15:55:46 +01:00
|
|
|
self.0.consume(len, |buf| f(buf))
|
2021-02-03 05:09:37 +01:00
|
|
|
}
|
|
|
|
}
|