1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
//! # embedded-nal - A Network Abstraction Layer for Embedded Systems #![doc(html_root_url = "https://docs.rs/embedded-nal/0.2.0")] #![no_std] #![deny(missing_docs)] #![deny(unsafe_code)] pub use nb; mod dns; pub use dns::{AddrType, Dns}; pub use no_std_net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; /// This trait is implemented by TCP/IP stacks. You could, for example, have an implementation /// which knows how to send AT commands to an ESP8266 WiFi module. You could have another implementation /// which knows how to driver the Rust Standard Library's `std::net` module. Given this trait, you can how /// write a portable HTTP client which can work with either implementation. pub trait TcpClient { /// The type returned when we create a new TCP socket type TcpSocket; /// The type returned when we have an error type Error: core::fmt::Debug; /// Open a socket for usage as a TCP client. /// /// The socket must be connected before it can be used. /// /// Returns `Ok(socket)` if the socket was successfully created. fn socket(&self) -> Result<Self::TcpSocket, Self::Error>; /// Connect to the given remote host and port. /// /// Returns `Ok` if the connection was successful. Otherwise, if the connection could not be /// completed immediately, this function should return [`nb::Error::WouldBlock`]. fn connect( &self, socket: &mut Self::TcpSocket, remote: SocketAddr, ) -> nb::Result<(), Self::Error>; /// Check if this socket is connected fn is_connected(&self, socket: &Self::TcpSocket) -> Result<bool, Self::Error>; /// Write to the stream. /// /// Returns the number of bytes written (which may be less than `buffer.len()`) or an error. fn send(&self, socket: &mut Self::TcpSocket, buffer: &[u8]) -> nb::Result<usize, Self::Error>; /// Receive data 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. If a packet has /// not been received when called, then [`nb::Error::WouldBlock`] /// should be returned. fn receive( &self, socket: &mut Self::TcpSocket, buffer: &mut [u8], ) -> nb::Result<usize, Self::Error>; /// Close an existing TCP socket. fn close(&self, socket: Self::TcpSocket) -> Result<(), Self::Error>; } /// This trait is implemented by TCP/IP stacks that expose TCP server functionality. TCP servers /// may listen for connection requests to establish multiple unique TCP connections with various /// clients. pub trait TcpServer: TcpClient { /// Create a new TCP socket and bind it to the specified local port. /// /// Returns `Ok` when a socket is successfully bound to the specified local port. Otherwise, an /// `Err(e)` variant is returned. fn bind(&self, socket: &mut Self::TcpSocket, local_port: u16) -> Result<(), Self::Error>; /// Begin listening for connection requests on a previously-bound socket. /// /// Returns `Ok` if the socket was successfully transitioned to the listening state. Otherwise, /// an `Err(e)` variant is returned. fn listen(&self, socket: &mut Self::TcpSocket) -> Result<(), Self::Error>; /// Accept an active connection request on a listening socket. /// /// Returns `Ok(connection)` if a new connection was created. If no pending connections are /// available, this function should return [`nb::Error::WouldBlock`]. fn accept( &self, socket: &mut Self::TcpSocket, ) -> nb::Result<(Self::TcpSocket, SocketAddr), Self::Error>; } /// This trait is implemented by UDP/IP stacks. You could, for example, have /// an implementation which knows how to send AT commands to an ESP8266 WiFi /// module. You could have another implementation which knows how to driver the /// Rust Standard Library's `std::net` module. Given this trait, you can how /// write a portable CoAP client which can work with either implementation. pub trait UdpClient { /// The type returned when we create a new UDP socket type UdpSocket; /// The type returned when we have an error type Error: core::fmt::Debug; /// Allocate a socket for further use. fn socket(&self) -> Result<Self::UdpSocket, Self::Error>; /// Connect a UDP socket with a peer using a dynamically selected port. /// /// Selects a port number automatically and initializes for read/writing. fn connect(&self, socket: &mut Self::UdpSocket, remote: SocketAddr) -> Result<(), Self::Error>; /// Send a datagram to the remote host. /// /// The remote host used is either the one specified in `UdpStack::connect` /// or the last one used in `UdpServerStack::write_to`. fn send(&self, socket: &mut Self::UdpSocket, buffer: &[u8]) -> nb::Result<(), Self::Error>; /// Read a datagram the remote host has sent to us. /// /// Returns `Ok((n, remote))`, which means a datagram of size `n` has been /// received from `remote` and been placed in `&buffer[0..n]`, or an error. /// If a packet has not been received when called, then [`nb::Error::WouldBlock`] /// should be returned. fn receive( &self, socket: &mut Self::UdpSocket, buffer: &mut [u8], ) -> nb::Result<(usize, SocketAddr), Self::Error>; /// Close an existing UDP socket. fn close(&self, socket: Self::UdpSocket) -> Result<(), Self::Error>; } /// This trait is implemented by UDP/IP stacks. It provides the ability to /// listen for packets on a specified port and send replies. pub trait UdpServer: UdpClient { /// Bind a UDP socket with a specified port fn bind(&self, socket: &mut Self::UdpSocket, local_port: u16) -> Result<(), Self::Error>; /// Send a packet to a remote host/port. fn send_to( &self, socket: &mut Self::UdpSocket, remote: SocketAddr, buffer: &[u8], ) -> nb::Result<(), Self::Error>; }