Implement loopback interfaces.
This also adds a default implementation of Device::limits.
This commit is contained in:
parent
5556f09351
commit
63ab7d4e7a
|
@ -1,4 +1,5 @@
|
|||
#![cfg_attr(feature = "alloc", feature(alloc))]
|
||||
#![cfg_attr(feature = "collections", feature(collections))]
|
||||
#![no_std]
|
||||
|
||||
//! The _smoltcp_ library is built in a layered structure, with the layers corresponding
|
||||
|
@ -76,6 +77,9 @@ extern crate std;
|
|||
extern crate libc;
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
#[allow(deprecated)]
|
||||
#[cfg(feature = "collections")]
|
||||
extern crate collections;
|
||||
#[cfg(any(test, feature = "log"))]
|
||||
#[macro_use(trace, log, log_enabled)]
|
||||
extern crate log;
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
use core::mem::swap;
|
||||
use core::cell::RefCell;
|
||||
#[cfg(feature = "std")]
|
||||
use std::rc::Rc;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::rc::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> {
|
||||
let mut buffer = Vec::new();
|
||||
buffer.resize(length, 0);
|
||||
Ok(TxBuffer {
|
||||
queue: self.0.clone(),
|
||||
buffer: buffer
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[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)
|
||||
}
|
||||
}
|
|
@ -103,11 +103,13 @@ 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"))]
|
||||
|
@ -115,6 +117,8 @@ 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.
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue