103 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use core::task::Context;
 | |
| 
 | |
| use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken};
 | |
| use smoltcp::phy;
 | |
| use smoltcp::time::Instant;
 | |
| 
 | |
| 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,
 | |
| }
 | |
| 
 | |
| 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;
 | |
| 
 | |
|     fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
 | |
|         self.inner
 | |
|             .receive(self.cx.as_deref_mut().unwrap())
 | |
|             .map(|(rx, tx)| (RxTokenAdapter(rx), TxTokenAdapter(tx)))
 | |
|     }
 | |
| 
 | |
|     /// Construct a transmit token.
 | |
|     fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
 | |
|         self.inner.transmit(self.cx.as_deref_mut().unwrap()).map(TxTokenAdapter)
 | |
|     }
 | |
| 
 | |
|     /// 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);
 | |
|         smolcaps.checksum.tcp = convert(caps.checksum.tcp);
 | |
|         smolcaps.checksum.udp = convert(caps.checksum.udp);
 | |
|         smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4);
 | |
|         #[cfg(feature = "proto-ipv6")]
 | |
|         {
 | |
|             smolcaps.checksum.icmpv6 = convert(caps.checksum.icmpv6);
 | |
|         }
 | |
| 
 | |
|         smolcaps
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub(crate) struct RxTokenAdapter<T>(T)
 | |
| where
 | |
|     T: RxToken;
 | |
| 
 | |
| impl<T> phy::RxToken for RxTokenAdapter<T>
 | |
| where
 | |
|     T: RxToken,
 | |
| {
 | |
|     fn consume<R, F>(self, f: F) -> R
 | |
|     where
 | |
|         F: FnOnce(&mut [u8]) -> R,
 | |
|     {
 | |
|         self.0.consume(|buf| f(buf))
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub(crate) struct TxTokenAdapter<T>(T)
 | |
| where
 | |
|     T: TxToken;
 | |
| 
 | |
| impl<T> phy::TxToken for TxTokenAdapter<T>
 | |
| where
 | |
|     T: TxToken,
 | |
| {
 | |
|     fn consume<R, F>(self, len: usize, f: F) -> R
 | |
|     where
 | |
|         F: FnOnce(&mut [u8]) -> R,
 | |
|     {
 | |
|         self.0.consume(len, |buf| f(buf))
 | |
|     }
 | |
| }
 |