smoltcp/phy/
loopback.rs

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