use embedded_nal::{TcpStack, Mode, SocketAddr}; use embedded_nal::SocketAddr::{V4, V6}; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder}; use smoltcp::socket::SocketSet; use smoltcp::socket::{SocketHandle, TcpSocket, TcpSocketBuffer}; use smoltcp::time::{Duration, Instant}; use smoltcp::Error; use nb::Error as nbError; use core::cell; const BUFFER_SIZE: usize = 2048; pub static mut TX_STORAGE: &'static mut [u8] = &mut [0; BUFFER_SIZE]; pub static mut RX_STORAGE: &'static mut [u8] = &mut [0; BUFFER_SIZE]; /* * Struct for a TCP socket * TODO: Consider handling all sockets in this struct */ pub struct NalTcpClient {} // impl NalTcpClient { // pub fn new(socket: &'a mut TcpSocket<'a>) -> Self { // NalTcpClient { // socket, // } // } // } impl<'a> TcpStack for &'a NalTcpClient{ // The type returned when we create a new TCP socket type TcpSocket = smoltcp::socket::TcpSocket<'a>; // The type returned when we have an error type Error = Error; // Open a new TCP socket. The socket starts in the unconnected state. fn open(&self, mode: Mode) -> Result { let tx_buffer = unsafe { TcpSocketBuffer::new(&mut TX_STORAGE[..]) }; let rx_buffer = unsafe { TcpSocketBuffer::new(&mut RX_STORAGE[..]) }; let mut socket = TcpSocket::new(rx_buffer, tx_buffer); if let Mode::Timeout(dur) = mode { socket.set_timeout(Some(Duration::from_millis(dur.into()))); } Ok(socket) } // Connect to the given remote host and port. fn connect( &self, mut socket: Self::TcpSocket, remote: SocketAddr, ) -> Result { let result = match remote { V4(v4_addr) => { let ip_addr = v4_addr.ip().octets(); socket.connect((IpAddress::v4(ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]), v4_addr.port()), 49500) }, V6(v6_addr) => { let ip_addr = v6_addr.ip().segments(); socket.connect((IpAddress::v6(ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]), v6_addr.port()), 49500) } }; match result { Ok(_) => Ok(socket), Err(_e) => Err(_e), } } /// Check if this socket is connected fn is_connected(&self, socket: &Self::TcpSocket) -> Result { Ok(socket.is_active()) } /// Write to the stream. Returns the number of bytes written is returned /// (which may be less than `buffer.len()`), or an error. fn write(&self, socket: &mut Self::TcpSocket, buffer: &[u8]) -> nb::Result { if socket.can_send() { socket.send_slice(buffer).map_err(nbError::Other) } else { Err(nbError::Other(Error::Illegal)) } } /// Read from the stream. Returns `Ok(n)`, which means `n` bytes of /// data have been received and they have been placed in /// `&buffer[0..n]`, or an error. fn read( &self, socket: &mut Self::TcpSocket, buffer: &mut [u8], ) -> nb::Result { if socket.can_recv() { socket.recv_slice(buffer).map_err(nbError::Other) } else { Err(nbError::Other(Error::Illegal)) } } /// Close an existing TCP socket. fn close(&self, mut socket: Self::TcpSocket) -> Result<(), Self::Error> { socket.close(); Ok(()) } }