Trait w5500_hl::Udp[][src]

pub trait Udp<E>: Registers<Error = E> {
    fn udp_bind(&mut self, socket: Socket, port: u16) -> Result<(), E> { ... }
fn udp_recv_from(
        &mut self,
        socket: Socket,
        buf: &mut [u8]
    ) -> Result<(usize, SocketAddrV4), E> { ... }
fn udp_peek_from(
        &mut self,
        socket: Socket,
        buf: &mut [u8]
    ) -> Result<(usize, SocketAddrV4), E> { ... }
fn udp_peek_from_header(
        &mut self,
        socket: Socket
    ) -> Result<(usize, SocketAddrV4), E> { ... }
fn udp_send_to(
        &mut self,
        socket: Socket,
        buf: &[u8],
        addr: &SocketAddrV4
    ) -> Result<usize, E> { ... }
fn udp_send(&mut self, socket: Socket, buf: &[u8]) -> Result<usize, E> { ... } }

A W5500 UDP socket trait.

After creating a UdpSocket by binding it to a socket address, data can be sent to and received from any other socket address.

As stated in the User Datagram Protocol’s specification in IETF RFC 768, UDP is an unordered, unreliable protocol; refer to Tcp for the TCP trait.

Comparison to std::net::UdpSocket

  • Everything is non-blocking.
  • There is no socket struct, you must pass a socket number as the first argument to the methods. This was simply the cleanest solution to the ownership problem after some experimentation; though it certainly is not the safest.

Provided methods

fn udp_bind(&mut self, socket: Socket, port: u16) -> Result<(), E>[src]

Binds the socket to the given port.

This will close the socket, which will reset the RX and TX buffers.

Comparison to std::net::UdpSocket::bind

This method accepts a port instead of a net::SocketAddrV4, this is because the IP address is global for the device, set by the source IP register, and cannot be set on a per-socket basis.

Additionally you can only provide one port, instead of iterable addresses to bind.

Panics

  • (debug) The port must not be in use by any other socket on the W5500.

Example

Bind the first socket to port 8080.

use w5500_hl::ll::{Registers, Socket::Socket0};
use w5500_hl::Udp;

w5500.udp_bind(Socket0, 8080)?;

fn udp_recv_from(
    &mut self,
    socket: Socket,
    buf: &mut [u8]
) -> Result<(usize, SocketAddrV4), E>
[src]

Receives a single datagram message on the socket. On success, returns the number of bytes read and the origin.

The function must be called with valid byte array buf of sufficient size to hold the message bytes. If a message is too long to fit in the supplied buffer, excess bytes will be discarded.

Comparison to std::net::UdpSocket::recv_from

  • This method will always discard excess bytes from the socket buffer.
  • This method is non-blocking, use nb::block to treat it as blocking.

Panics

  • (debug) The socket must be opened as a UDP socket.

Example

use nb::block;
use w5500_hl::{
    ll::{Registers, Socket::Socket0},
    Udp,
};

w5500.udp_bind(Socket0, 8080)?;
let mut buf = [0; 10];
let (number_of_bytes, src_addr) = block!(w5500.udp_recv_from(Socket0, &mut buf))?;

// panics if bytes were discarded
assert!(
    number_of_bytes < buf.len(),
    "Buffer was too small to receive all data"
);

let filled_buf = &mut buf[..number_of_bytes];

fn udp_peek_from(
    &mut self,
    socket: Socket,
    buf: &mut [u8]
) -> Result<(usize, SocketAddrV4), E>
[src]

Receives a single datagram message on the socket, without removing it from the queue. On success, returns the number of bytes read and the origin.

Comparison to std::net::UdpSocket::peek_from

  • This method will never discard excess bytes from the socket buffer.
  • This method is non-blocking, use nb::block to treat it as blocking.

Panics

  • (debug) The socket must be opened as a UDP socket.

Example

use nb::block;
use w5500_hl::{
    ll::{Registers, Socket::Socket0},
    Udp,
};

w5500.udp_bind(Socket0, 8080)?;
let mut buf = [0; 10];
let (number_of_bytes, src_addr) = block!(w5500.udp_peek_from(Socket0, &mut buf))?;

// panics if buffer was too small
assert!(
    number_of_bytes > buf.len(),
    "Buffer was too small to receive all data"
);

let filled_buf = &mut buf[..number_of_bytes];

fn udp_peek_from_header(
    &mut self,
    socket: Socket
) -> Result<(usize, SocketAddrV4), E>
[src]

Receives the origin and size of the next datagram avaliable on the socket, without removing it from the queue.

There is no std::net equivalent for this method.

Panics

  • (debug) The socket must be opened as a UDP socket.

Example

use nb::block;
use w5500_hl::{
    ll::{Registers, Socket::Socket0},
    Udp,
};
// global_allocator is currently avaliable on nightly for embedded rust
extern crate alloc;
use alloc::vec::{self, Vec};

w5500.udp_bind(Socket0, 8080)?;
let (bytes_to_allocate, _) = block!(w5500.udp_peek_from_header(Socket0))?;

let mut buf: Vec<u8> = vec![0; bytes_to_allocate];
let (number_of_bytes, source) = block!(w5500.udp_recv_from(Socket0, &mut buf))?;
debug_assert_eq!(bytes_to_allocate, number_of_bytes);

fn udp_send_to(
    &mut self,
    socket: Socket,
    buf: &[u8],
    addr: &SocketAddrV4
) -> Result<usize, E>
[src]

Sends data on the socket to the given address. On success, returns the number of bytes written.

Comparison to std::net::UdpSocket::send_to

  • You cannot transmit more than u16::MAX bytes at once.
  • You can only provide one destination.

Panics

  • (debug) The socket must be opened as a UDP socket.

Example

use w5500_hl::{
    ll::{Registers, Socket::Socket0},
    net::{Ipv4Addr, SocketAddrV4},
    Udp,
};

const DEST: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::new(192, 0, 2, 1), 8081);

w5500.udp_bind(Socket0, 8080)?;
let buf: [u8; 10] = [0; 10];
let tx_bytes = w5500.udp_send_to(Socket0, &buf, &DEST)?;
assert_eq!(tx_bytes, buf.len());

fn udp_send(&mut self, socket: Socket, buf: &[u8]) -> Result<usize, E>[src]

Sends data to the currently configured destination.

The destination is set by the last call to set_sn_dest or send_to.

Panics

  • (debug) The socket must be opened as a UDP socket.

Example

use w5500_hl::{
    ll::{Registers, Socket::Socket0},
    net::{Ipv4Addr, SocketAddrV4},
    Udp,
};

const DEST: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::new(192, 0, 2, 1), 8081);

w5500.udp_bind(Socket0, 8080)?;
let buf: [u8; 10] = [0; 10];
let tx_bytes = w5500.udp_send_to(Socket0, &buf, &DEST)?;
assert_eq!(tx_bytes, buf.len());
// send the same to the same destination
let tx_bytes = w5500.udp_send(Socket0, &buf)?;
assert_eq!(tx_bytes, buf.len());
Loading content...

Implementors

impl<T, E> Udp<E> for T where
    T: Registers<Error = E>, 
[src]

Implement the UDP trait for any structure that implements w5500_ll::Registers.

Loading content...