Browse Source

Examples for the phy layer!

whitequark 8 years ago
parent
commit
456cfc69ce
4 changed files with 96 additions and 3 deletions
  1. 0 1
      src/iface/arp_cache.rs
  2. 1 1
      src/lib.rs
  3. 94 1
      src/phy/mod.rs
  4. 1 0
      src/wire/mod.rs

+ 0 - 1
src/iface/arp_cache.rs

@@ -31,7 +31,6 @@ pub trait Cache {
 /// let mut arp_cache_storage = [Default::default(); 8]
 /// let mut arp_cache = SliceArpCache::new(&mut arp_cache_storage[..]);
 /// ```
-
 pub struct SliceCache<'a> {
     storage: Managed<'a, [(IpAddress, EthernetAddress, usize)]>,
     counter: usize

+ 1 - 1
src/lib.rs

@@ -31,7 +31,7 @@
 //!
 //! # The physical layer
 //! The physical layer APIs are provided in the module [phy](phy/index.html); currently,
-//! raw socket and TAP interface are provided. In addition, two "middleware" interfaces
+//! raw socket and TAP interface are provided. In addition, two _middleware_ interfaces
 //! are provided: the _tracer device_, which prints a human-readable representation of packets,
 //! and the _fault injector device_, which randomly introduces errors into the transmitted
 //! and received packet sequences.

+ 94 - 1
src/phy/mod.rs

@@ -1,9 +1,102 @@
 //! Access to networking hardware.
 //!
-//! The `phy` module deals with the *network devices*. It provides an interface
+//! The `phy` module deals with the *network devices*. It provides a trait
 //! for transmitting and receiving frames, [Device](trait.Device.html),
 //! as well as an implementations of that trait that uses the host OS,
 //! [RawSocket](struct.RawSocket.html) and [TapInterface](struct.TapInterface.html).
+//!
+//! It also provides the _middleware interfaces_ [Tracer](struct.Tracer.html) and
+//! [FaultInjector](struct.FaultInjector.html), to facilitate debugging.
+//!
+//! # Examples
+//!
+//! An implementation of the [Device](trait.Device.html) trait for a simple hardware
+//! Ethernet controller could look as follows:
+//!
+/*!
+```rust
+use std::slice;
+use smoltcp::Error;
+use smoltcp::phy::Device;
+
+const MTU: usize = 1536;
+const TX_BUFFERS: [*mut u8; 2] = [0x10000000 as *mut u8, 0x10001000 as *mut u8];
+const RX_BUFFERS: [*mut u8; 2] = [0x10002000 as *mut u8, 0x10003000 as *mut u8];
+
+fn rx_full() -> bool {
+    /* platform-specific code to check if an incoming packet has arrived */
+    false
+}
+
+fn rx_setup(buf: *mut u8) {
+    /* platform-specific code to receive a packet into a buffer */
+}
+
+fn tx_empty() -> bool {
+    /* platform-specific code to check if the outgoing packet was sent */
+    false
+}
+
+fn tx_setup(buf: *const u8) {
+    /* platform-specific code to send a buffer with a packet */
+}
+
+struct EthernetDevice {
+    tx_next:    usize,
+    rx_next:    usize
+}
+
+impl Device for EthernetDevice {
+    type RxBuffer = &'static [u8];
+    type TxBuffer = EthernetTxBuffer;
+
+    fn mtu(&self) -> usize { MTU }
+
+    fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
+        if rx_full() {
+            let index = self.rx_next;
+            self.rx_next = (self.rx_next + 1) % RX_BUFFERS.len();
+            rx_setup(RX_BUFFERS[self.rx_next]);
+            Ok(unsafe { slice::from_raw_parts(RX_BUFFERS[index], MTU) })
+        } else {
+            Err(Error::Exhausted)
+        }
+    }
+
+    fn transmit(&mut self, length: usize) -> Result<Self::TxBuffer, Error> {
+        if tx_empty() {
+            let index = self.tx_next;
+            self.tx_next = (self.tx_next + 1) % TX_BUFFERS.len();
+            Ok(EthernetTxBuffer {
+                buffer: unsafe { slice::from_raw_parts_mut(TX_BUFFERS[index], length) },
+                length: length,
+            })
+        } else {
+            Err(Error::Exhausted)
+        }
+    }
+}
+
+struct EthernetTxBuffer {
+    buffer: &'static mut [u8],
+    length: usize
+}
+
+impl AsRef<[u8]> for EthernetTxBuffer {
+    fn as_ref(&self) -> &[u8] { &self.buffer[..self.length] }
+}
+
+impl AsMut<[u8]> for EthernetTxBuffer {
+    fn as_mut(&mut self) -> &mut [u8] { &mut self.buffer[..self.length] }
+}
+
+impl Drop for EthernetTxBuffer {
+    fn drop(&mut self) {
+        tx_setup(self.buffer.as_ptr())
+    }
+}
+```
+*/
 
 use Error;
 

+ 1 - 0
src/wire/mod.rs

@@ -21,6 +21,7 @@
 //! the `Repr` family does.
 //!
 //! # Examples
+//!
 //! To emit an IP packet header into an octet buffer, and then parse it back:
 //!
 /*!