embassy/embassy-net/src/device.rs

107 lines
2.9 KiB
Rust
Raw Normal View History

use core::task::Context;
2022-06-12 20:15:44 +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
pub(crate) struct DriverAdapter<'d, 'c, T>
where
T: Driver,
{
// must be Some when actually using this to rx/tx
pub cx: Option<&'d mut Context<'c>>,
pub inner: &'d mut T,
pub medium: Medium,
2021-02-03 04:09:37 +00:00
}
impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T>
where
T: Driver,
{
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<'_>)> {
self.inner
2023-09-02 05:44:10 +00:00
.receive(unwrap!(self.cx.as_deref_mut()))
.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.
fn capabilities(&self) -> phy::DeviceCapabilities {
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 = self.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 14:00:53 +00:00
#[cfg(feature = "proto-ipv4")]
{
smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4);
}
#[cfg(feature = "proto-ipv6")]
{
smolcaps.checksum.icmpv6 = convert(caps.checksum.icmpv6);
}
smolcaps
2021-02-03 04:09:37 +00:00
}
}
pub(crate) struct RxTokenAdapter<T>(T)
where
T: RxToken;
2021-02-03 04:09:37 +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
}
}
pub(crate) struct TxTokenAdapter<T>(T)
where
T: TxToken;
2021-02-03 04:09:37 +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
}
}