2022-12-07 14:55:46 +00:00
|
|
|
use core::task::Context;
|
2022-06-12 20:15:44 +00:00
|
|
|
|
2023-10-16 21:41:58 +00:00
|
|
|
use embassy_net_driver::{Capabilities, Checksum, Driver, RxToken, TxToken};
|
|
|
|
use smoltcp::phy::{self, Medium};
|
2023-01-18 08:56:38 +00:00
|
|
|
use smoltcp::time::Instant;
|
2021-02-03 04:09:37 +00:00
|
|
|
|
2022-12-26 02:33:49 +00:00
|
|
|
pub(crate) struct DriverAdapter<'d, 'c, T>
|
2022-12-07 14:55:46 +00:00
|
|
|
where
|
2022-12-26 02:33:49 +00:00
|
|
|
T: Driver,
|
2022-12-07 14:55:46 +00:00
|
|
|
{
|
|
|
|
// must be Some when actually using this to rx/tx
|
|
|
|
pub cx: Option<&'d mut Context<'c>>,
|
|
|
|
pub inner: &'d mut T,
|
2023-10-16 21:41:58 +00:00
|
|
|
pub medium: Medium,
|
2021-02-03 04:09:37 +00:00
|
|
|
}
|
|
|
|
|
2022-12-26 02:33:49 +00:00
|
|
|
impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T>
|
2022-12-07 14:55:46 +00:00
|
|
|
where
|
2022-12-26 02:33:49 +00:00
|
|
|
T: Driver,
|
2022-12-07 14:55:46 +00:00
|
|
|
{
|
|
|
|
type RxToken<'a> = RxTokenAdapter<T::RxToken<'a>> where Self: 'a;
|
|
|
|
type TxToken<'a> = TxTokenAdapter<T::TxToken<'a>> where Self: 'a;
|
2021-02-03 04:09:37 +00:00
|
|
|
|
2023-01-18 08:56:38 +00:00
|
|
|
fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
|
2022-12-07 14:55:46 +00:00
|
|
|
self.inner
|
2023-09-02 05:44:10 +00:00
|
|
|
.receive(unwrap!(self.cx.as_deref_mut()))
|
2022-12-07 14:55:46 +00:00
|
|
|
.map(|(rx, tx)| (RxTokenAdapter(rx), TxTokenAdapter(tx)))
|
2021-02-03 04:09:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Construct a transmit token.
|
2023-01-18 08:56:38 +00:00
|
|
|
fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
|
2023-09-02 05:44:10 +00:00
|
|
|
self.inner.transmit(unwrap!(self.cx.as_deref_mut())).map(TxTokenAdapter)
|
2021-02-03 04:09:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get a description of device capabilities.
|
2022-12-07 14:55:46 +00:00
|
|
|
fn capabilities(&self) -> phy::DeviceCapabilities {
|
2022-12-26 02:33:49 +00: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;
|
2023-10-16 21:41:58 +00:00
|
|
|
smolcaps.medium = self.medium;
|
2022-12-26 02:33:49 +00:00
|
|
|
smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4);
|
|
|
|
smolcaps.checksum.tcp = convert(caps.checksum.tcp);
|
|
|
|
smolcaps.checksum.udp = convert(caps.checksum.udp);
|
2023-06-05 14:00:53 +00:00
|
|
|
#[cfg(feature = "proto-ipv4")]
|
|
|
|
{
|
|
|
|
smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4);
|
|
|
|
}
|
2023-01-24 08:57:26 +00:00
|
|
|
#[cfg(feature = "proto-ipv6")]
|
|
|
|
{
|
|
|
|
smolcaps.checksum.icmpv6 = convert(caps.checksum.icmpv6);
|
|
|
|
}
|
2022-12-26 02:33:49 +00:00
|
|
|
|
|
|
|
smolcaps
|
2021-02-03 04:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 14:55:46 +00:00
|
|
|
pub(crate) struct RxTokenAdapter<T>(T)
|
|
|
|
where
|
|
|
|
T: RxToken;
|
2021-02-03 04:09:37 +00:00
|
|
|
|
2022-12-07 14:55:46 +00:00
|
|
|
impl<T> phy::RxToken for RxTokenAdapter<T>
|
|
|
|
where
|
|
|
|
T: RxToken,
|
|
|
|
{
|
2023-01-18 08:56:38 +00:00
|
|
|
fn consume<R, F>(self, f: F) -> R
|
2021-02-03 04:09:37 +00:00
|
|
|
where
|
2023-01-18 08:56:38 +00:00
|
|
|
F: FnOnce(&mut [u8]) -> R,
|
2021-02-03 04:09:37 +00:00
|
|
|
{
|
2024-01-10 13:06:15 +00:00
|
|
|
self.0.consume(|buf| {
|
|
|
|
#[cfg(feature = "packet-trace")]
|
|
|
|
trace!("rx: {:?}", buf);
|
|
|
|
f(buf)
|
|
|
|
})
|
2021-02-03 04:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 14:55:46 +00:00
|
|
|
pub(crate) struct TxTokenAdapter<T>(T)
|
|
|
|
where
|
|
|
|
T: TxToken;
|
2021-02-03 04:09:37 +00:00
|
|
|
|
2022-12-07 14:55:46 +00:00
|
|
|
impl<T> phy::TxToken for TxTokenAdapter<T>
|
|
|
|
where
|
|
|
|
T: TxToken,
|
|
|
|
{
|
2023-01-18 08:56:38 +00:00
|
|
|
fn consume<R, F>(self, len: usize, f: F) -> R
|
2021-02-03 04:09:37 +00:00
|
|
|
where
|
2023-01-18 08:56:38 +00:00
|
|
|
F: FnOnce(&mut [u8]) -> R,
|
2021-02-03 04:09:37 +00:00
|
|
|
{
|
2024-01-10 13:06:15 +00:00
|
|
|
self.0.consume(len, |buf| {
|
|
|
|
let r = f(buf);
|
|
|
|
#[cfg(feature = "packet-trace")]
|
|
|
|
trace!("tx: {:?}", buf);
|
|
|
|
r
|
|
|
|
})
|
2021-02-03 04:09:37 +00:00
|
|
|
}
|
|
|
|
}
|