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#[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 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}