embassy/embassy-net/src/device.rs

102 lines
3.0 KiB
Rust
Raw Normal View History

use core::task::Context;
2022-06-12 22:15:44 +02:00
use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken};
use smoltcp::phy;
2021-02-03 05:09:37 +01: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,
2021-02-03 05:09:37 +01: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 05:09:37 +01:00
2022-12-07 00:28:38 +01:00
fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
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.
2022-12-07 00:28:38 +01:00
fn transmit(&mut self) -> Option<Self::TxToken<'_>> {
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.
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 = match caps.medium {
#[cfg(feature = "medium-ethernet")]
Medium::Ethernet => phy::Medium::Ethernet,
#[cfg(feature = "medium-ip")]
Medium::Ip => phy::Medium::Ip,
_ => panic!(
"Unsupported medium {:?}. MAke sure to enable it in embassy-net's Cargo features.",
caps.medium
),
};
smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4);
#[cfg(feature = "proto-ipv6")]
{
smolcaps.checksum.ipv6 = convert(caps.checksum.ipv6);
}
smolcaps.checksum.tcp = convert(caps.checksum.tcp);
smolcaps.checksum.udp = convert(caps.checksum.udp);
smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4);
smolcaps
2021-02-03 05:09:37 +01:00
}
}
pub(crate) struct RxTokenAdapter<T>(T)
where
T: RxToken;
2021-02-03 05:09:37 +01:00
impl<T> phy::RxToken for RxTokenAdapter<T>
where
T: RxToken,
{
fn consume<R, F>(self, _timestamp: smoltcp::time::Instant, 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
{
self.0.consume(|buf| f(buf))
2021-02-03 05:09:37 +01:00
}
}
pub(crate) struct TxTokenAdapter<T>(T)
where
T: TxToken;
2021-02-03 05:09:37 +01:00
impl<T> phy::TxToken for TxTokenAdapter<T>
where
T: TxToken,
{
fn consume<R, F>(self, _timestamp: smoltcp::time::Instant, 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
{
self.0.consume(len, |buf| f(buf))
2021-02-03 05:09:37 +01:00
}
}