embedded_mqttc/network/
std.rs

1extern crate std;
2
3// #[cfg(all(feature = "defmt", feature = "std"))]
4// compile_error!("std cannot be logged with defmt!");
5
6use embedded_io_async::Write;
7use embedded_io_async::{ErrorKind, ErrorType, Read};
8use tokio::net::{TcpStream, ToSocketAddrs};
9use tokio::io::AsyncReadExt;
10use tokio::io::AsyncWriteExt;
11
12use crate::fmt::Debug2Format;
13
14use super::NetworkError;
15
16pub struct StdNetworkConnection<T: ToSocketAddrs> {
17    stream: Option<TcpStream>,
18    addr: T
19}
20
21impl <T: ToSocketAddrs> StdNetworkConnection<T> {
22    pub fn new(addr: T) -> Self {
23        Self {
24            stream: None,
25            addr
26        }
27    }
28}
29
30impl <T: ToSocketAddrs> Unpin for StdNetworkConnection<T> {}
31
32impl <T: ToSocketAddrs> ErrorType for StdNetworkConnection<T> {
33    type Error = embedded_io_async::ErrorKind;
34}
35
36impl <T: ToSocketAddrs> super::TryRead for StdNetworkConnection<T> {
37    async fn try_read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
38        let result = self.stream.as_mut().ok_or(ErrorKind::Other)?
39            .try_read(buf);
40
41        match result {
42            Ok(n) => {
43                if n == 0 && ! buf.is_empty(){
44                    warn!("std net try_read: read 0 bytes");
45                    Err(ErrorKind::ConnectionReset)
46                } else {
47                    Ok(n)
48                }
49            },
50            Err(e) => {
51                if e.kind() == tokio::io::ErrorKind::WouldBlock {
52                    trace!("try_read: network would block");
53                    Ok(0) 
54                } else { 
55                    error!("error try_reading from std net: {}", Debug2Format(e));
56                    Err(ErrorKind::Other) 
57                }
58            }
59        }
60    }
61}
62
63impl <T: ToSocketAddrs> super::TryWrite for StdNetworkConnection<T> {
64    async fn try_write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
65        let result = self.stream.as_mut().ok_or(ErrorKind::Other)?
66            .try_write(buf);
67
68        match result {
69            Ok(n) => {
70                if n == 0 && ! buf.is_empty(){
71                    warn!("std net try_write: 0 written bytes");
72                    Err(ErrorKind::ConnectionReset)
73                } else {
74                    Ok(n)
75                }
76            },
77            Err(e) => {
78                if e.kind() == tokio::io::ErrorKind::WouldBlock {
79                    trace!("try_write: network would block");
80                    Ok(0) 
81                } else { 
82                    error!("error try_writing to std net: {:?}", Debug2Format(e));
83                    Err(ErrorKind::Other) 
84                }
85            }
86        }
87    }
88}
89
90impl <T: ToSocketAddrs> Read for StdNetworkConnection<T> {
91    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
92        self.stream.as_ref().ok_or(ErrorKind::Other)?.readable().await
93        .map_err(|e| {
94            error!("error waiting for std net to be readable: {}", Debug2Format(e));
95            ErrorKind::Other
96        })?;
97
98        let n = self.stream.as_mut().ok_or(ErrorKind::Other)?
99            .read(buf).await
100            .map_err(|e| {
101                error!("error reading from std net: {}", Debug2Format(e));
102                ErrorKind::Other
103            })?;
104
105        if n == 0 && ! buf.is_empty(){
106            warn!("std net read: read 0 bytes");
107            return Err(ErrorKind::ConnectionReset);
108        }
109        Ok(n)
110    }
111}
112
113impl <T: ToSocketAddrs> Write for StdNetworkConnection<T> {
114    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
115        let n = self.stream.as_mut().ok_or(ErrorKind::Other)?
116            .write(buf).await
117            .map_err(|e| {
118                error!("error writing to std net: {}", Debug2Format(e));
119                ErrorKind::Other
120            })?;
121
122        if n == 0 && ! buf.is_empty(){
123            warn!("std net write: 0 written bytes");
124            return Err(ErrorKind::ConnectionReset);
125        }
126        Ok(n)
127    }
128}
129
130impl <T: ToSocketAddrs> super::NetworkConnection for StdNetworkConnection<T> {
131    async fn connect(&mut self) -> Result<(), NetworkError> {
132        let stream: TcpStream = TcpStream::connect(&self.addr).await
133            .map_err(|_| NetworkError::ConnectionFailed)?;
134        self.stream = Some(stream);
135        Ok(())
136    }
137}