Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d9567b1

Browse files
committedJul 14, 2017
Implement loopback interfaces.
This also adds a default implementation of Device::limits.
1 parent 6bb9200 commit d9567b1

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed
 

‎src/phy/loopback.rs

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use core::mem::swap;
2+
use core::cell::RefCell;
3+
#[cfg(feature = "std")]
4+
use std::rc::Rc;
5+
#[cfg(feature = "alloc")]
6+
use alloc::Rc;
7+
#[cfg(feature = "std")]
8+
use std::vec::Vec;
9+
#[cfg(feature = "std")]
10+
use std::collections::VecDeque;
11+
#[cfg(feature = "collections")]
12+
use collections::{Vec, VecDeque};
13+
14+
use Error;
15+
use super::Device;
16+
17+
/// A loopback interface.
18+
#[derive(Debug)]
19+
pub struct LoopbackInterface(Rc<RefCell<VecDeque<Vec<u8>>>>);
20+
21+
impl LoopbackInterface {
22+
/// Creates a loopback interface.
23+
///
24+
/// Every packet transmitted through this interface will be received through it
25+
/// in FIFO order.
26+
pub fn new() -> LoopbackInterface {
27+
LoopbackInterface(Rc::new(RefCell::new(VecDeque::new())))
28+
}
29+
}
30+
31+
impl Device for LoopbackInterface {
32+
type RxBuffer = Vec<u8>;
33+
type TxBuffer = TxBuffer;
34+
35+
fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
36+
match self.0.borrow_mut().pop_front() {
37+
Some(packet) => Ok(packet),
38+
None => Err(Error::Exhausted)
39+
}
40+
}
41+
42+
fn transmit(&mut self, length: usize) -> Result<Self::TxBuffer, Error> {
43+
Ok(TxBuffer {
44+
queue: self.0.clone(),
45+
buffer: vec![0; length]
46+
})
47+
}
48+
}
49+
50+
#[doc(hidden)]
51+
pub struct TxBuffer {
52+
queue: Rc<RefCell<VecDeque<Vec<u8>>>>,
53+
buffer: Vec<u8>
54+
}
55+
56+
impl AsRef<[u8]> for TxBuffer {
57+
fn as_ref(&self) -> &[u8] { self.buffer.as_ref() }
58+
}
59+
60+
impl AsMut<[u8]> for TxBuffer {
61+
fn as_mut(&mut self) -> &mut [u8] { self.buffer.as_mut() }
62+
}
63+
64+
impl Drop for TxBuffer {
65+
fn drop(&mut self) {
66+
let mut buffer = Vec::new();
67+
swap(&mut buffer, &mut self.buffer);
68+
self.queue.borrow_mut().push_back(buffer)
69+
}
70+
}

‎src/phy/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,22 @@ impl Drop for EthernetTxBuffer {
103103

104104
use Error;
105105

106-
#[cfg(any(feature = "raw_socket", feature="tap_interface"))]
106+
#[cfg(any(feature = "raw_socket", feature = "tap_interface"))]
107107
mod sys;
108108

109109
mod tracer;
110110
mod fault_injector;
111+
#[cfg(any(feature = "std", feature = "collections"))]
112+
mod loopback;
111113
#[cfg(feature = "raw_socket")]
112114
mod raw_socket;
113115
#[cfg(all(feature = "tap_interface", target_os = "linux"))]
114116
mod tap_interface;
115117

116118
pub use self::tracer::Tracer;
117119
pub use self::fault_injector::FaultInjector;
120+
#[cfg(any(feature = "std", feature = "collections"))]
121+
pub use self::loopback::LoopbackInterface;
118122
#[cfg(any(feature = "raw_socket"))]
119123
pub use self::raw_socket::RawSocket;
120124
#[cfg(all(feature = "tap_interface", target_os = "linux"))]
@@ -158,7 +162,9 @@ pub trait Device {
158162
type TxBuffer: AsRef<[u8]> + AsMut<[u8]>;
159163

160164
/// Get a description of device limitations.
161-
fn limits(&self) -> DeviceLimits;
165+
fn limits(&self) -> DeviceLimits {
166+
DeviceLimits::default()
167+
}
162168

163169
/// Receive a frame.
164170
///

0 commit comments

Comments
 (0)