Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: d5638f469fb2
Choose a base ref
...
head repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0dedbaf597c9
Choose a head ref
  • 3 commits
  • 4 files changed
  • 1 contributor

Commits on Jan 12, 2017

  1. Allow copying socket set handles.

    Trying to keep them unique was kind of a losing battle anyway.
    whitequark committed Jan 12, 2017
    Copy the full SHA
    0293008 View commit details
  2. Copy the full SHA
    8bff18c View commit details
  3. impl Debug for SocketSet.

    whitequark committed Jan 12, 2017
    Copy the full SHA
    0dedbaf View commit details
Showing with 33 additions and 37 deletions.
  1. +4 −11 examples/server.rs
  2. +1 −0 src/socket/mod.rs
  3. +6 −5 src/socket/set.rs
  4. +22 −21 src/socket/udp.rs
15 changes: 4 additions & 11 deletions examples/server.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ use std::time::{Instant, SystemTime, UNIX_EPOCH};
use log::{LogLevelFilter, LogRecord};
use env_logger::{LogBuilder};

use smoltcp::Error;
use smoltcp::phy::{Tracer, FaultInjector, TapInterface};
use smoltcp::wire::{EthernetFrame, EthernetAddress, IpAddress};
use smoltcp::wire::PrettyPrinter;
@@ -95,7 +94,7 @@ fn main() {
loop {
// udp:6969: respond "yo dawg"
{
let socket: &mut UdpSocket = sockets.get_mut(&udp_handle).as_socket();
let socket: &mut UdpSocket = sockets.get_mut(udp_handle).as_socket();
if socket.endpoint().is_unspecified() {
socket.bind(6969)
}
@@ -106,13 +105,7 @@ fn main() {
str::from_utf8(data.as_ref()).unwrap(), endpoint);
Some(endpoint)
}
Err(Error::Exhausted) => {
None
}
Err(e) => {
debug!("udp:6969 recv error: {}", e);
None
}
Err(_) => None
};
if let Some(endpoint) = client {
let data = b"yo dawg\n";
@@ -124,7 +117,7 @@ fn main() {

// tcp:6969: respond "yo dawg"
{
let socket: &mut TcpSocket = sockets.get_mut(&tcp1_handle).as_socket();
let socket: &mut TcpSocket = sockets.get_mut(tcp1_handle).as_socket();
if !socket.is_open() {
socket.listen(6969).unwrap();
}
@@ -141,7 +134,7 @@ fn main() {

// tcp:6970: echo with reverse
{
let socket: &mut TcpSocket = sockets.get_mut(&tcp2_handle).as_socket();
let socket: &mut TcpSocket = sockets.get_mut(tcp2_handle).as_socket();
if !socket.is_open() {
socket.listen(6970).unwrap()
}
1 change: 1 addition & 0 deletions src/socket/mod.rs
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ pub use self::set::{Iter as SocketSetIter, IterMut as SocketSetIterMut};
/// which is rather inelegant. Conversely, when `dispatch` is called, the packet length is
/// not yet known and the packet storage has to be allocated; but the `&PacketRepr` is sufficient
/// since the lower layers treat the packet as an opaque octet sequence.
#[derive(Debug)]
pub enum Socket<'a, 'b: 'a> {
Udp(UdpSocket<'a, 'b>),
Tcp(TcpSocket<'a>),
11 changes: 6 additions & 5 deletions src/socket/set.rs
Original file line number Diff line number Diff line change
@@ -4,12 +4,13 @@ use core::slice;
use super::Socket;

/// A handle, identifying a socket in a set.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
pub struct Handle {
index: usize
}

/// An extensible set of sockets, with stable numeric identifiers.
#[derive(Debug)]
pub struct Set<'a, 'b: 'a, 'c: 'a + 'b> {
sockets: ManagedSlice<'a, Option<Socket<'b, 'c>>>
}
@@ -51,20 +52,20 @@ impl<'a, 'b: 'a, 'c: 'a + 'b> Set<'a, 'b, 'c> {
///
/// # Panics
/// This function may panic if the handle does not belong to this socket set.
pub fn get(&self, handle: &Handle) -> &Socket<'b, 'c> {
pub fn get(&self, handle: Handle) -> &Socket<'b, 'c> {
self.sockets[handle.index]
.as_ref()
.expect("handle does not contain a valid socket index")
.expect("handle does not refer to a valid socket")
}

/// Get a socket from the set by its handle, as mutable.
///
/// # Panics
/// This function may panic if the handle does not belong to this socket set.
pub fn get_mut(&mut self, handle: &Handle) -> &mut Socket<'b, 'c> {
pub fn get_mut(&mut self, handle: Handle) -> &mut Socket<'b, 'c> {
self.sockets[handle.index]
.as_mut()
.expect("handle does not contain a valid socket index")
.expect("handle does not refer to a valid socket")
}

/// Remove a socket from the set, without changing its state.
43 changes: 22 additions & 21 deletions src/socket/udp.rs
Original file line number Diff line number Diff line change
@@ -66,19 +66,21 @@ impl<'a, 'b> SocketBuffer<'a, 'b> {
self.mask(index + 1)
}

fn empty(&self) -> bool {
/// Query whether the buffer is empty.
pub fn empty(&self) -> bool {
self.length == 0
}

fn full(&self) -> bool {
/// Query whether the buffer is full.
pub fn full(&self) -> bool {
self.length == self.storage.len()
}

/// Enqueue an element into the buffer, and return a pointer to it, or return
/// `Err(Error::Exhausted)` if the buffer is full.
pub fn enqueue(&mut self) -> Result<&mut PacketBuffer<'b>, Error> {
/// `Err(())` if the buffer is full.
pub fn enqueue(&mut self) -> Result<&mut PacketBuffer<'b>, ()> {
if self.full() {
Err(Error::Exhausted)
Err(())
} else {
let index = self.mask(self.read_at + self.length);
let result = &mut self.storage[index];
@@ -88,10 +90,10 @@ impl<'a, 'b> SocketBuffer<'a, 'b> {
}

/// Dequeue an element from the buffer, and return a pointer to it, or return
/// `Err(Error::Exhausted)` if the buffer is empty.
pub fn dequeue(&mut self) -> Result<&PacketBuffer<'b>, Error> {
/// `Err(())` if the buffer is empty.
pub fn dequeue(&mut self) -> Result<&PacketBuffer<'b>, ()> {
if self.empty() {
Err(Error::Exhausted)
Err(())
} else {
self.length -= 1;
let result = &self.storage[self.read_at];
@@ -105,6 +107,7 @@ impl<'a, 'b> SocketBuffer<'a, 'b> {
///
/// An UDP socket is bound to a specific endpoint, and owns transmit and receive
/// packet buffers.
#[derive(Debug)]
pub struct UdpSocket<'a, 'b: 'a> {
endpoint: IpEndpoint,
rx_buffer: SocketBuffer<'a, 'b>,
@@ -141,9 +144,9 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
/// Enqueue a packet to be sent to a given remote endpoint, and return a pointer
/// to its payload.
///
/// This function returns `Err(Error::Exhausted)` if the size is greater than what
/// This function returns `Err(())` if the size is greater than what
/// the transmit buffer can accomodate.
pub fn send(&mut self, size: usize, endpoint: IpEndpoint) -> Result<&mut [u8], Error> {
pub fn send(&mut self, size: usize, endpoint: IpEndpoint) -> Result<&mut [u8], ()> {
let packet_buf = try!(self.tx_buffer.enqueue());
packet_buf.endpoint = endpoint;
packet_buf.size = size;
@@ -155,7 +158,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
/// Enqueue a packet to be sent to a given remote endpoint, and fill it from a slice.
///
/// See also [send](#method.send).
pub fn send_slice(&mut self, data: &[u8], endpoint: IpEndpoint) -> Result<usize, Error> {
pub fn send_slice(&mut self, data: &[u8], endpoint: IpEndpoint) -> Result<usize, ()> {
let buffer = try!(self.send(data.len(), endpoint));
let data = &data[..buffer.len()];
buffer.copy_from_slice(data);
@@ -170,8 +173,8 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
/// Dequeue a packet received from a remote endpoint, and return the endpoint as well
/// as a pointer to the payload.
///
/// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
pub fn recv(&mut self) -> Result<(&[u8], IpEndpoint), Error> {
/// This function returns `Err(())` if the receive buffer is empty.
pub fn recv(&mut self) -> Result<(&[u8], IpEndpoint), ()> {
let packet_buf = try!(self.rx_buffer.dequeue());
net_trace!("udp:{}:{}: receive {} buffered octets",
self.endpoint, packet_buf.endpoint, packet_buf.size);
@@ -181,11 +184,9 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
/// Dequeue a packet received from a remote endpoint, and return the endpoint as well
/// as copy the payload into the given slice.
///
/// This function returns `Err(Error::Exhausted)` if the received packet has payload
/// larger than the provided slice. See also [recv](#method.recv).
pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, IpEndpoint), Error> {
/// See also [recv](#method.recv).
pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, IpEndpoint), ()> {
let (buffer, endpoint) = try!(self.recv());
if data.len() < buffer.len() { return Err(Error::Exhausted) }
data[..buffer.len()].copy_from_slice(buffer);
Ok((buffer.len(), endpoint))
}
@@ -203,7 +204,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
if self.endpoint.addr != ip_repr.dst_addr() { return Err(Error::Rejected) }
}

let packet_buf = try!(self.rx_buffer.enqueue());
let packet_buf = try!(self.rx_buffer.enqueue().map_err(|()| Error::Exhausted));
packet_buf.endpoint = IpEndpoint { addr: ip_repr.src_addr(), port: repr.src_port };
packet_buf.size = repr.payload.len();
packet_buf.as_mut()[..repr.payload.len()].copy_from_slice(repr.payload);
@@ -215,7 +216,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
/// See [Socket::dispatch](enum.Socket.html#method.dispatch).
pub fn dispatch<F, R>(&mut self, _timestamp: u64, emit: &mut F) -> Result<R, Error>
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
let packet_buf = try!(self.tx_buffer.dequeue());
let packet_buf = try!(self.tx_buffer.dequeue().map_err(|()| Error::Exhausted));
net_trace!("udp:{}:{}: sending {} octets",
self.endpoint, packet_buf.endpoint, packet_buf.size);
let ip_repr = IpRepr::Unspecified {
@@ -268,15 +269,15 @@ mod test {
buffer.enqueue().unwrap().size = 5;
buffer.enqueue().unwrap().size = 6;
buffer.enqueue().unwrap().size = 7;
assert_eq!(buffer.enqueue().unwrap_err(), Error::Exhausted);
assert_eq!(buffer.enqueue().unwrap_err(), ());
assert_eq!(buffer.empty(), false);
assert_eq!(buffer.full(), true);
assert_eq!(buffer.dequeue().unwrap().size, 3);
assert_eq!(buffer.dequeue().unwrap().size, 4);
assert_eq!(buffer.dequeue().unwrap().size, 5);
assert_eq!(buffer.dequeue().unwrap().size, 6);
assert_eq!(buffer.dequeue().unwrap().size, 7);
assert_eq!(buffer.dequeue().unwrap_err(), Error::Exhausted);
assert_eq!(buffer.dequeue().unwrap_err(), ());
assert_eq!(buffer.empty(), true);
assert_eq!(buffer.full(), false);
}