Trait w5500_hl::Tcp[][src]

pub trait Tcp: Registers {
    fn tcp_connect(
        &mut self,
        sn: Sn,
        port: u16,
        addr: &SocketAddrV4
    ) -> Result<(), Self::Error> { ... }
fn tcp_listen(&mut self, sn: Sn, port: u16) -> Result<(), Self::Error> { ... }
fn tcp_read(&mut self, sn: Sn, buf: &mut [u8]) -> Result<usize, Self::Error> { ... }
fn tcp_write(&mut self, sn: Sn, buf: &[u8]) -> Result<usize, Self::Error> { ... }
fn tcp_disconnect(&mut self, sn: Sn) -> Result<(), Self::Error> { ... } }
Expand description

A W5500 TCP trait.

Provided methods

Starts the 3-way TCP handshake with the remote host.

This method is used to create and interact with a TCP stream between a local host and a remote socket.

After initiating a connection with tcp_connect and recieving the con interrupt data can be transmitting by using tcp_read and tcp_write.

Calling this method does not mean the socket will be connected afterwards, this simply starts the three way handshake.

After calling this method you will eventually get one of 3 interrupts on the socket:

  1. con
  2. discon
  3. timeout
Arguments
  • socket - The socket number to use for this TCP stream.
  • port - The local port to use for the TCP connection.
  • addr - Address of the remote host to connect to.
Panics
  • (debug) The port must not be in use by any other socket on the W5500.
Example
use w5500_hl::{
    ll::{Registers, Sn, SocketInterrupt},
    net::{Ipv4Addr, SocketAddrV4},
    Tcp,
};

const MQTT_SOCKET: Sn = Sn::Sn0;
const MQTT_SOURCE_PORT: u16 = 33650;
const MQTT_SERVER: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 2, 10), 1883);

w5500.tcp_connect(MQTT_SOCKET, MQTT_SOURCE_PORT, &MQTT_SERVER)?;

// wait for a socket interrupt
// you should use the actual interrupt pin, polling is just for demonstration
loop {
    let sn_ir: SocketInterrupt = w5500.sn_ir(MQTT_SOCKET)?;

    // in reality you will want to handle disconnections gracefully with retries
    assert!(!sn_ir.discon_raised());
    assert!(!sn_ir.timeout_raised());

    // connection succeded
    if sn_ir.con_raised() {
        break;
    }
}

Open a TCP listener on the given port.

After opening a listener with tcp_listen and recieving the con interrupt data can be transmitting by using tcp_read and tcp_write.

Arguments
  • socket - The socket number to use for this TCP listener.
  • port - The local port to listen for remote connections on.
Panics
  • (debug) The port must not be in use by any other socket on the W5500.
Example

Create an HTTP server.

use w5500_hl::{
    ll::{Registers, Sn, SocketInterrupt},
    net::{Ipv4Addr, SocketAddrV4},
    Tcp,
};
// global_allocator is currently avaliable on nightly for embedded rust
extern crate alloc;
use alloc::vec::{self, Vec};

const HTTP_SOCKET: Sn = Sn::Sn1;
const HTTP_PORT: u16 = 80;

// start serving
w5500.tcp_listen(HTTP_SOCKET, HTTP_PORT)?;

// wait for the RECV interrupt, indicating there is data to read from a client
loop {
    let sn_ir = w5500.sn_ir(HTTP_SOCKET).unwrap();
    if sn_ir.recv_raised() {
        w5500.set_sn_ir(HTTP_SOCKET, sn_ir).unwrap();
        break;
    }
    if sn_ir.discon_raised() | sn_ir.timeout_raised() {
        panic!("Socket disconnected while waiting for RECV");
    }
}

let mut buf: Vec<u8> = vec![0; 256];
let rx_bytes: usize = w5500.tcp_read(HTTP_SOCKET, &mut buf).unwrap();
// Truncate the buffer to the number of bytes read
// Safety: BUF is only borrowed mutably in one location
let filled_buf: &[u8] = &buf[..rx_bytes];

// parse HTTP request here using filled_buf

Read data from the remote host, returning the number of bytes read.

You should wait for the socket recv interrupt before calling this method.

Panics
  • (debug) The socket must be an Established TCP socket.
Example

Send a MQTT CONNECT packet and read a CONNACK.

use w5500_hl::{
    ll::{Registers, Sn, SocketInterrupt},
    net::{Ipv4Addr, SocketAddrV4},
    Tcp,
};

const MQTT_SOCKET: Sn = Sn::Sn0;
const MQTT_SOURCE_PORT: u16 = 33650;
const MQTT_SERVER: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 2, 10), 1883);

w5500.tcp_connect(MQTT_SOCKET, MQTT_SOURCE_PORT, &MQTT_SERVER)?;

// ... wait for a CON interrupt

const CONNECT: [u8; 14] = [
    0x10, 0x0C, 0x00, 0x04, b'M', b'Q', b'T', b'T', 0x04, 0x02, 0x0E, 0x10, 0x00, 0x00,
];
let tx_bytes: usize = w5500.tcp_write(MQTT_SOCKET, &CONNECT)?;
assert_eq!(tx_bytes, CONNECT.len());

// ... wait for a RECV interrupt

let mut buf = [0; 10];
let rx_bytes: usize = w5500.tcp_read(MQTT_SOCKET, &mut buf)?;
let filled_buf = &buf[..rx_bytes];

Send data to the remote host, returning the number of bytes written.

Panics
  • (debug) The socket must be an Established TCP socket.
Example

Send a MQTT CONNECT packet.

use w5500_hl::{
    ll::{Registers, Sn, SocketInterrupt},
    net::{Ipv4Addr, SocketAddrV4},
    Tcp,
};

const MQTT_SOCKET: Sn = Sn::Sn0;
const MQTT_SOURCE_PORT: u16 = 33650;
const MQTT_SERVER: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 2, 10), 1883);

w5500.tcp_connect(MQTT_SOCKET, MQTT_SOURCE_PORT, &MQTT_SERVER)?;

// ... wait for a CON interrupt

const CONNECT: [u8; 14] = [
    0x10, 0x0C, 0x00, 0x04, b'M', b'Q', b'T', b'T', 0x04, 0x02, 0x0E, 0x10, 0x00, 0x00,
];
let tx_bytes: usize = w5500.tcp_write(MQTT_SOCKET, &CONNECT)?;
assert_eq!(tx_bytes, CONNECT.len());

Disconnect from the peer.

If the disconnect is successful (FIN/ACK packet is received) the socket status changes to Closed, otherwise TCPTO occurs, the timeout interrupt is raised, and the socket status changes to Closed.

Panics
  • (debug) The socket must be an Established TCP socket.
Example

Connect and disconnect from a MQTT server.

use w5500_hl::{
    ll::{Registers, Sn, SocketInterrupt},
    net::{Ipv4Addr, SocketAddrV4},
    Tcp,
};

const MQTT_SOCKET: Sn = Sn::Sn0;
const MQTT_SOURCE_PORT: u16 = 33650;
const MQTT_SERVER: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 2, 10), 1883);

w5500.tcp_connect(MQTT_SOCKET, MQTT_SOURCE_PORT, &MQTT_SERVER)?;

// ... wait for a CON interrupt

w5500.tcp_disconnect(MQTT_SOCKET)?;

Implementors

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