Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement loopback interfaces.
Browse files Browse the repository at this point in the history
This also adds a default implementation of Device::limits.
whitequark committed Jul 14, 2017
1 parent 6bb9200 commit d9567b1
Showing 2 changed files with 78 additions and 2 deletions.
70 changes: 70 additions & 0 deletions src/phy/loopback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use core::mem::swap;
use core::cell::RefCell;
#[cfg(feature = "std")]
use std::rc::Rc;
#[cfg(feature = "alloc")]
use alloc::Rc;
#[cfg(feature = "std")]
use std::vec::Vec;
#[cfg(feature = "std")]
use std::collections::VecDeque;
#[cfg(feature = "collections")]
use collections::{Vec, VecDeque};

use Error;
use super::Device;

/// A loopback interface.
#[derive(Debug)]
pub struct LoopbackInterface(Rc<RefCell<VecDeque<Vec<u8>>>>);

impl LoopbackInterface {
/// Creates a loopback interface.
///
/// Every packet transmitted through this interface will be received through it
/// in FIFO order.
pub fn new() -> LoopbackInterface {
LoopbackInterface(Rc::new(RefCell::new(VecDeque::new())))
}
}

impl Device for LoopbackInterface {
type RxBuffer = Vec<u8>;
type TxBuffer = TxBuffer;

fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
match self.0.borrow_mut().pop_front() {
Some(packet) => Ok(packet),
None => Err(Error::Exhausted)
}
}

fn transmit(&mut self, length: usize) -> Result<Self::TxBuffer, Error> {
Ok(TxBuffer {
queue: self.0.clone(),
buffer: vec![0; length]
})
}
}

#[doc(hidden)]
pub struct TxBuffer {
queue: Rc<RefCell<VecDeque<Vec<u8>>>>,
buffer: Vec<u8>
}

impl AsRef<[u8]> for TxBuffer {
fn as_ref(&self) -> &[u8] { self.buffer.as_ref() }
}

impl AsMut<[u8]> for TxBuffer {
fn as_mut(&mut self) -> &mut [u8] { self.buffer.as_mut() }
}

impl Drop for TxBuffer {
fn drop(&mut self) {
let mut buffer = Vec::new();
swap(&mut buffer, &mut self.buffer);
self.queue.borrow_mut().push_back(buffer)
}
}
10 changes: 8 additions & 2 deletions src/phy/mod.rs
Original file line number Diff line number Diff line change
@@ -103,18 +103,22 @@ impl Drop for EthernetTxBuffer {

use Error;

#[cfg(any(feature = "raw_socket", feature="tap_interface"))]
#[cfg(any(feature = "raw_socket", feature = "tap_interface"))]
mod sys;

mod tracer;
mod fault_injector;
#[cfg(any(feature = "std", feature = "collections"))]
mod loopback;
#[cfg(feature = "raw_socket")]
mod raw_socket;
#[cfg(all(feature = "tap_interface", target_os = "linux"))]
mod tap_interface;

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

/// Get a description of device limitations.
fn limits(&self) -> DeviceLimits;
fn limits(&self) -> DeviceLimits {
DeviceLimits::default()
}

/// Receive a frame.
///

0 comments on commit d9567b1

Please sign in to comment.