drogue_network/tcp.rs
1
2use crate::addr::HostSocketAddr;
3
4use core::fmt::Debug;
5
6/// Whether a socket should block when a read/write can't be performed, or return early.
7pub enum Mode {
8 /// The function call will wait as long as necessary to complete the operation
9 Blocking,
10 /// The function call will not wait at all to complete the operation, and only do what it can.
11 NonBlocking,
12 /// The function call will wait only up the given number of milliseconds to complete the operation.
13 Timeout(u16),
14}
15
16/// Network errors
17#[non_exhaustive]
18#[derive(Debug)]
19pub enum TcpError {
20 NoAvailableSockets,
21 ConnectionRefused,
22 SocketNotOpen,
23 WriteError,
24 ReadError,
25 Timeout,
26 Busy,
27 Impl(TcpImplError),
28}
29
30#[non_exhaustive]
31#[derive(Debug)]
32pub enum TcpImplError {
33 InitializationError,
34 ErrorCode(u32),
35 Unknown,
36}
37
38/// This trait is implemented by TCP/IP stacks. You could, for example, have an implementation
39/// which knows how to send AT commands to an ESP8266 WiFi module. You could have another implemenation
40/// which knows how to driver the Rust Standard Library's `std::net` module. Given this trait, you can how
41/// write a portable HTTP client which can work with either implementation.
42pub trait TcpStack {
43 /// The type returned when we create a new TCP socket
44 type TcpSocket;
45 /// The type returned when we have an error
46 type Error: Into<TcpError> + Debug;
47
48 /// Open a new TCP socket. The socket starts in the unconnected state.
49 fn open(&self, mode: Mode) -> Result<Self::TcpSocket, Self::Error>;
50
51 /// Connect to the given remote host and port.
52 fn connect(
53 &self,
54 socket: Self::TcpSocket,
55 remote: HostSocketAddr,
56 ) -> Result<Self::TcpSocket, Self::Error>;
57
58 /// Check if this socket is connected
59 fn is_connected(&self, socket: &Self::TcpSocket) -> Result<bool, Self::Error>;
60
61 /// Write to the stream. Returns the number of bytes written is returned
62 /// (which may be less than `buffer.len()`), or an error.
63 fn write(&self, socket: &mut Self::TcpSocket, buffer: &[u8]) -> nb::Result<usize, Self::Error>;
64
65 /// Read from the stream. Returns `Ok(n)`, which means `n` bytes of
66 /// data have been received and they have been placed in
67 /// `&buffer[0..n]`, or an error.
68 fn read(
69 &self,
70 socket: &mut Self::TcpSocket,
71 buffer: &mut [u8],
72 ) -> nb::Result<usize, Self::Error>;
73
74 /// Close an existing TCP socket.
75 fn close(&self, socket: Self::TcpSocket) -> Result<(), Self::Error>;
76}
77