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
fn tcp_connect(
&mut self,
sn: Sn,
port: u16,
addr: &SocketAddrV4
) -> Result<(), Self::Error>
fn tcp_connect(
&mut self,
sn: Sn,
port: u16,
addr: &SocketAddrV4
) -> Result<(), Self::Error>
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:
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
.