| use crate::iface::*; |
| use crate::wire::*; |
| |
| pub(crate) fn setup<'a>(medium: Medium) -> (Interface, SocketSet<'a>, TestingDevice) { |
| let mut device = TestingDevice::new(medium); |
| |
| let config = Config::new(match medium { |
| #[cfg(feature = "medium-ethernet")] |
| Medium::Ethernet => { |
| HardwareAddress::Ethernet(EthernetAddress([0x02, 0x02, 0x02, 0x02, 0x02, 0x02])) |
| } |
| #[cfg(feature = "medium-ip")] |
| Medium::Ip => HardwareAddress::Ip, |
| #[cfg(feature = "medium-ieee802154")] |
| Medium::Ieee802154 => HardwareAddress::Ieee802154(Ieee802154Address::Extended([ |
| 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
| ])), |
| }); |
| |
| let mut iface = Interface::new(config, &mut device, Instant::ZERO); |
| |
| #[cfg(feature = "proto-ipv4")] |
| { |
| iface.update_ip_addrs(|ip_addrs| { |
| ip_addrs |
| .push(IpCidr::new(IpAddress::v4(192, 168, 1, 1), 24)) |
| .unwrap(); |
| ip_addrs |
| .push(IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)) |
| .unwrap(); |
| }); |
| } |
| |
| #[cfg(feature = "proto-ipv6")] |
| { |
| iface.update_ip_addrs(|ip_addrs| { |
| ip_addrs |
| .push(IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 0, 0, 0, 1), 64)) |
| .unwrap(); |
| ip_addrs |
| .push(IpCidr::new(IpAddress::v6(0, 0, 0, 0, 0, 0, 0, 1), 128)) |
| .unwrap(); |
| ip_addrs |
| .push(IpCidr::new(IpAddress::v6(0xfdbe, 0, 0, 0, 0, 0, 0, 1), 64)) |
| .unwrap(); |
| }); |
| } |
| |
| (iface, SocketSet::new(vec![]), device) |
| } |
| |
| use heapless::Deque; |
| use heapless::Vec; |
| |
| use crate::phy::{self, Device, DeviceCapabilities, Medium}; |
| use crate::time::Instant; |
| |
| /// A testing device. |
| #[derive(Debug)] |
| pub struct TestingDevice { |
| pub(crate) queue: Deque<Vec<u8, 1514>, 4>, |
| max_transmission_unit: usize, |
| medium: Medium, |
| } |
| |
| #[allow(clippy::new_without_default)] |
| impl TestingDevice { |
| /// Creates a testing device. |
| /// |
| /// Every packet transmitted through this device will be received through it |
| /// in FIFO order. |
| pub fn new(medium: Medium) -> Self { |
| TestingDevice { |
| queue: Deque::new(), |
| max_transmission_unit: match medium { |
| #[cfg(feature = "medium-ethernet")] |
| Medium::Ethernet => 1514, |
| #[cfg(feature = "medium-ip")] |
| Medium::Ip => 1500, |
| #[cfg(feature = "medium-ieee802154")] |
| Medium::Ieee802154 => 1500, |
| }, |
| medium, |
| } |
| } |
| } |
| |
| impl Device for TestingDevice { |
| type RxToken<'a> = RxToken; |
| type TxToken<'a> = TxToken<'a>; |
| |
| fn capabilities(&self) -> DeviceCapabilities { |
| DeviceCapabilities { |
| medium: self.medium, |
| max_transmission_unit: self.max_transmission_unit, |
| ..DeviceCapabilities::default() |
| } |
| } |
| |
| fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { |
| self.queue.pop_front().map(move |buffer| { |
| let rx = RxToken { buffer }; |
| let tx = TxToken { |
| queue: &mut self.queue, |
| }; |
| (rx, tx) |
| }) |
| } |
| |
| fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> { |
| Some(TxToken { |
| queue: &mut self.queue, |
| }) |
| } |
| } |
| |
| #[doc(hidden)] |
| pub struct RxToken { |
| buffer: Vec<u8, 1514>, |
| } |
| |
| impl phy::RxToken for RxToken { |
| fn consume<R, F>(mut self, f: F) -> R |
| where |
| F: FnOnce(&mut [u8]) -> R, |
| { |
| f(&mut self.buffer) |
| } |
| } |
| |
| #[doc(hidden)] |
| #[derive(Debug)] |
| pub struct TxToken<'a> { |
| queue: &'a mut Deque<Vec<u8, 1514>, 4>, |
| } |
| |
| impl<'a> phy::TxToken for TxToken<'a> { |
| fn consume<R, F>(self, len: usize, f: F) -> R |
| where |
| F: FnOnce(&mut [u8]) -> R, |
| { |
| let mut buffer = Vec::new(); |
| buffer.resize(len, 0).unwrap(); |
| let result = f(&mut buffer); |
| self.queue.push_back(buffer).unwrap(); |
| result |
| } |
| } |