2017-07-14 09:05:05 +08:00
|
|
|
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;
|
2017-07-14 10:06:31 +08:00
|
|
|
use super::{Device, DeviceLimits};
|
2017-07-14 09:05:05 +08:00
|
|
|
|
2017-07-23 20:50:26 +08:00
|
|
|
/// A loopback device.
|
2017-07-14 09:05:05 +08:00
|
|
|
#[derive(Debug)]
|
2017-07-14 09:17:06 +08:00
|
|
|
pub struct Loopback(Rc<RefCell<VecDeque<Vec<u8>>>>);
|
2017-07-14 09:05:05 +08:00
|
|
|
|
2017-07-14 09:17:06 +08:00
|
|
|
impl Loopback {
|
2017-07-23 20:50:26 +08:00
|
|
|
/// Creates a loopback device.
|
2017-07-14 09:05:05 +08:00
|
|
|
///
|
2017-07-23 20:50:26 +08:00
|
|
|
/// Every packet transmitted through this device will be received through it
|
2017-07-14 09:05:05 +08:00
|
|
|
/// in FIFO order.
|
2017-07-14 09:17:06 +08:00
|
|
|
pub fn new() -> Loopback {
|
|
|
|
Loopback(Rc::new(RefCell::new(VecDeque::new())))
|
2017-07-14 09:05:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-14 09:17:06 +08:00
|
|
|
impl Device for Loopback {
|
2017-07-14 09:05:05 +08:00
|
|
|
type RxBuffer = Vec<u8>;
|
|
|
|
type TxBuffer = TxBuffer;
|
|
|
|
|
2017-07-14 10:06:31 +08:00
|
|
|
fn limits(&self) -> DeviceLimits {
|
|
|
|
DeviceLimits {
|
|
|
|
max_transmission_unit: 65535,
|
|
|
|
..DeviceLimits::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-23 17:44:54 +08:00
|
|
|
fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer, Error> {
|
2017-07-14 09:05:05 +08:00
|
|
|
match self.0.borrow_mut().pop_front() {
|
|
|
|
Some(packet) => Ok(packet),
|
|
|
|
None => Err(Error::Exhausted)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-23 17:44:54 +08:00
|
|
|
fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer, Error> {
|
2017-07-14 09:05:05 +08:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|