veecle_osal_std/net/
tcp.rs1use crate::IntoOsalError;
4use embedded_io_adapters::tokio_1::FromTokio;
5use std::io::ErrorKind;
6use std::net::SocketAddr;
7use tokio::io::AsyncWriteExt;
8use veecle_osal_api::net::tcp::Error;
9
10#[derive(Default)]
15pub struct TcpSocket;
16
17impl TcpSocket {
18 pub fn new() -> Self {
20 Self
21 }
22}
23
24impl core::fmt::Debug for TcpSocket {
25 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26 f.debug_struct("TcpSocket").finish()
27 }
28}
29
30pub struct TcpConnection<'s> {
35 stream: FromTokio<tokio::net::TcpStream>,
36 _socket: &'s mut TcpSocket,
38}
39
40impl<'s> core::fmt::Debug for TcpConnection<'s> {
41 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
42 f.debug_struct("TcpConnection").finish()
43 }
44}
45
46impl<'s> veecle_osal_api::net::tcp::TcpConnection for TcpConnection<'s> {
47 async fn close(self) {
48 let _ = self.stream.into_inner().shutdown().await;
50 }
51}
52
53impl<'s> embedded_io_async::Read for TcpConnection<'s> {
54 async fn read(&mut self, buffer: &mut [u8]) -> Result<usize, Self::Error> {
55 self.stream
56 .read(buffer)
57 .await
58 .map_err(IntoOsalError::into_osal_error)
59 }
60}
61
62impl<'s> embedded_io::ErrorType for TcpConnection<'s> {
63 type Error = Error;
64}
65
66impl<'s> embedded_io_async::Write for TcpConnection<'s> {
67 async fn write(&mut self, buffer: &[u8]) -> Result<usize, Self::Error> {
68 self.stream
69 .write(buffer)
70 .await
71 .map_err(IntoOsalError::into_osal_error)
72 }
73}
74
75impl veecle_osal_api::net::tcp::TcpSocket for TcpSocket {
76 async fn connect(
77 &mut self,
78 address: SocketAddr,
79 ) -> Result<impl veecle_osal_api::net::tcp::TcpConnection, Error> {
80 let stream = tokio::net::TcpStream::connect(address)
81 .await
82 .map_err(IntoOsalError::into_osal_error)?;
83 Ok(TcpConnection {
84 stream: FromTokio::new(stream),
85 _socket: self,
86 })
87 }
88
89 async fn accept(
90 &mut self,
91 address: SocketAddr,
92 ) -> Result<(impl veecle_osal_api::net::tcp::TcpConnection, SocketAddr), Error> {
93 if address.port() == 0 {
95 return Err(Error::InvalidPort);
96 }
97
98 let socket = if address.ip().is_ipv4() {
99 tokio::net::TcpSocket::new_v4().map_err(IntoOsalError::into_osal_error)?
100 } else {
101 tokio::net::TcpSocket::new_v6().map_err(IntoOsalError::into_osal_error)?
102 };
103
104 socket
106 .set_reuseaddr(true)
107 .map_err(IntoOsalError::into_osal_error)?;
108 socket
109 .set_reuseport(true)
110 .map_err(IntoOsalError::into_osal_error)?;
111
112 socket
113 .bind(address)
114 .map_err(IntoOsalError::into_osal_error)?;
115
116 let listener = socket.listen(1).map_err(IntoOsalError::into_osal_error)?;
117
118 let (stream, address) = listener
119 .accept()
120 .await
121 .map_err(IntoOsalError::into_osal_error)?;
122 Ok((
123 TcpConnection {
124 stream: FromTokio::new(stream),
125 _socket: self,
126 },
127 address,
128 ))
129 }
130}
131
132impl IntoOsalError<Error> for std::io::Error {
133 fn into_osal_error(self) -> Error {
134 match self.kind() {
135 ErrorKind::PermissionDenied => Error::PermissionDenied,
136 ErrorKind::ConnectionRefused => Error::ConnectionReset,
137 ErrorKind::ConnectionReset => Error::ConnectionReset,
138 ErrorKind::HostUnreachable => Error::NoRoute,
139 ErrorKind::NetworkUnreachable => Error::NoRoute,
140 ErrorKind::ConnectionAborted => Error::ConnectionReset,
141 ErrorKind::AddrInUse => Error::InvalidAddress,
142 ErrorKind::AddrNotAvailable => Error::InvalidAddress,
143 ErrorKind::NetworkDown => Error::NetworkDown,
144 ErrorKind::TimedOut => Error::TimedOut,
145 _ => Error::Other,
146 }
147 }
148}