smoltcp/phy/
loopback.rs

1use alloc::collections::VecDeque;
2use alloc::vec::Vec;
3
4use crate::phy::{self, Device, DeviceCapabilities, Medium};
5use crate::time::Instant;
6
7/// A loopback device.
8#[derive(Debug)]
9pub struct Loopback {
10    pub(crate) queue: VecDeque<Vec<u8>>,
11    medium: Medium,
12}
13
14#[allow(clippy::new_without_default)]
15impl Loopback {
16    /// Creates a loopback device.
17    ///
18    /// Every packet transmitted through this device will be received through it
19    /// in FIFO order.
20    pub fn new(medium: Medium) -> Loopback {
21        Loopback {
22            queue: VecDeque::new(),
23            medium,
24        }
25    }
26}
27
28impl Device for Loopback {
29    type RxToken<'a> = RxToken;
30    type TxToken<'a> = TxToken<'a>;
31
32    fn capabilities(&self) -> DeviceCapabilities {
33        DeviceCapabilities {
34            max_transmission_unit: 65535,
35            medium: self.medium,
36            ..DeviceCapabilities::default()
37        }
38    }
39
40    fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
41        self.queue.pop_front().map(move |buffer| {
42            let rx = RxToken { buffer };
43            let tx = TxToken {
44                queue: &mut self.queue,
45            };
46            (rx, tx)
47        })
48    }
49
50    fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
51        Some(TxToken {
52            queue: &mut self.queue,
53        })
54    }
55}
56
57#[doc(hidden)]
58pub struct RxToken {
59    buffer: Vec<u8>,
60}
61
62impl phy::RxToken for RxToken {
63    fn consume<R, F>(mut self, f: F) -> R
64    where
65        F: FnOnce(&mut [u8]) -> R,
66    {
67        f(&mut self.buffer)
68    }
69}
70
71#[doc(hidden)]
72#[derive(Debug)]
73pub struct TxToken<'a> {
74    queue: &'a mut VecDeque<Vec<u8>>,
75}
76
77impl<'a> phy::TxToken for TxToken<'a> {
78    fn consume<R, F>(self, len: usize, f: F) -> R
79    where
80        F: FnOnce(&mut [u8]) -> R,
81    {
82        let mut buffer = Vec::new();
83        buffer.resize(len, 0);
84        let result = f(&mut buffer);
85        self.queue.push_back(buffer);
86        result
87    }
88}