ts_netstack_smoltcp_socket/
create_socket.rs1use alloc::vec::Vec;
2use core::net::SocketAddr;
3
4use netcore::{Command, HasChannel, raw, smoltcp::wire, tcp, udp};
5
6use crate::{RawSocket, TcpListener, TcpStream, UdpSocket};
7
8pub trait CreateSocket {
10 fn udp_bind_blocking(&self, endpoint: SocketAddr) -> Result<UdpSocket, netcore::Error>;
12 fn udp_bind(
14 &self,
15 endpoint: SocketAddr,
16 ) -> impl Future<Output = Result<UdpSocket, netcore::Error>> + Send;
17
18 fn tcp_listen_blocking(
20 &self,
21 local_endpoint: SocketAddr,
22 ) -> Result<TcpListener, netcore::Error>;
23 fn tcp_listen(
25 &self,
26 local_endpoint: SocketAddr,
27 ) -> impl Future<Output = Result<TcpListener, netcore::Error>> + Send;
28
29 fn bound_tcp_ports_blocking(&self) -> Result<Vec<u16>, netcore::Error>;
35 fn bound_tcp_ports(&self) -> impl Future<Output = Result<Vec<u16>, netcore::Error>> + Send;
38
39 fn tcp_connect_blocking(
44 &self,
45 local_endpoint: SocketAddr,
46 remote_endpoint: SocketAddr,
47 ) -> Result<TcpStream, netcore::Error>;
48 fn tcp_connect(
53 &self,
54 local_endpoint: SocketAddr,
55 remote_endpoint: SocketAddr,
56 ) -> impl Future<Output = Result<TcpStream, netcore::Error>> + Send;
57
58 fn raw_open_blocking(
62 &self,
63 ipv4: bool,
64 ip_protocol: wire::IpProtocol,
65 ) -> Result<RawSocket, netcore::Error>;
66 fn raw_open(
70 &self,
71 ipv4: bool,
72 ip_protocol: wire::IpProtocol,
73 ) -> impl Future<Output = Result<RawSocket, netcore::Error>> + Send;
74}
75
76impl<T> CreateSocket for T
77where
78 T: HasChannel + Sync,
79{
80 fn udp_bind_blocking(&self, endpoint: SocketAddr) -> Result<UdpSocket, netcore::Error> {
81 let resp = self.request_blocking(None, udp::Command::Bind { endpoint })?;
82
83 netcore::try_response_as!(resp, udp::Response::Bound { local, handle });
84
85 Ok(UdpSocket {
86 sender: self.command_channel(),
87 local,
88 handle,
89 })
90 }
91
92 async fn udp_bind(&self, endpoint: SocketAddr) -> Result<UdpSocket, netcore::Error> {
93 let resp = self.request(None, udp::Command::Bind { endpoint }).await?;
94
95 netcore::try_response_as!(resp, udp::Response::Bound { local, handle });
96
97 Ok(UdpSocket {
98 sender: self.command_channel(),
99 local,
100 handle,
101 })
102 }
103
104 fn tcp_listen_blocking(
105 &self,
106 local_endpoint: SocketAddr,
107 ) -> Result<TcpListener, netcore::Error> {
108 let resp = self.request_blocking(None, tcp::listen::Command::Listen { local_endpoint })?;
109
110 netcore::try_response_as!(resp, tcp::listen::Response::Listening { handle });
111
112 Ok(TcpListener {
113 sender: self.command_channel(),
114 handle,
115 endpoint: local_endpoint,
116 })
117 }
118
119 async fn tcp_listen(&self, local_endpoint: SocketAddr) -> Result<TcpListener, netcore::Error> {
120 let resp = self
121 .request(None, tcp::listen::Command::Listen { local_endpoint })
122 .await?;
123
124 netcore::try_response_as!(resp, tcp::listen::Response::Listening { handle });
125
126 Ok(TcpListener {
127 sender: self.command_channel(),
128 handle,
129 endpoint: local_endpoint,
130 })
131 }
132
133 fn bound_tcp_ports_blocking(&self) -> Result<Vec<u16>, netcore::Error> {
134 let resp = self.request_blocking(None, tcp::listen::Command::BoundPorts)?;
135
136 netcore::try_response_as!(resp, tcp::listen::Response::BoundPorts { ports });
137
138 Ok(ports)
139 }
140
141 async fn bound_tcp_ports(&self) -> Result<Vec<u16>, netcore::Error> {
142 let resp = self.request(None, tcp::listen::Command::BoundPorts).await?;
143
144 netcore::try_response_as!(resp, tcp::listen::Response::BoundPorts { ports });
145
146 Ok(ports)
147 }
148
149 fn tcp_connect_blocking(
150 &self,
151 local_endpoint: SocketAddr,
152 remote_endpoint: SocketAddr,
153 ) -> Result<TcpStream, netcore::Error> {
154 let resp = self.request_blocking(
155 None,
156 tcp::stream::Command::Connect {
157 remote_endpoint,
158 local_endpoint,
159 },
160 )?;
161
162 netcore::try_response_as!(resp, tcp::stream::Response::Connected { handle });
163
164 Ok(TcpStream::new(
165 self.command_channel(),
166 handle,
167 remote_endpoint,
168 local_endpoint,
169 ))
170 }
171
172 async fn tcp_connect(
173 &self,
174 local_endpoint: SocketAddr,
175 remote_endpoint: SocketAddr,
176 ) -> Result<TcpStream, netcore::Error> {
177 let resp = self
178 .request(
179 None,
180 tcp::stream::Command::Connect {
181 remote_endpoint,
182 local_endpoint,
183 },
184 )
185 .await?;
186
187 netcore::try_response_as!(resp, tcp::stream::Response::Connected { handle });
188
189 Ok(TcpStream::new(
190 self.command_channel(),
191 handle,
192 remote_endpoint,
193 local_endpoint,
194 ))
195 }
196
197 fn raw_open_blocking(
198 &self,
199 ipv4: bool,
200 ip_protocol: wire::IpProtocol,
201 ) -> Result<RawSocket, netcore::Error> {
202 let ip_version = if ipv4 {
203 wire::IpVersion::Ipv4
204 } else {
205 wire::IpVersion::Ipv6
206 };
207
208 let resp = self.request_blocking(
209 None,
210 Command::Raw(raw::Command::Open {
211 ip_version,
212 protocol: ip_protocol,
213 }),
214 )?;
215
216 netcore::try_response_as!(resp, raw::Response::Opened { handle });
217
218 Ok(RawSocket::new(
219 self.command_channel(),
220 handle,
221 ip_protocol,
222 ip_version,
223 ))
224 }
225
226 async fn raw_open(
227 &self,
228 ipv4: bool,
229 ip_protocol: wire::IpProtocol,
230 ) -> Result<RawSocket, netcore::Error> {
231 let ip_version = if ipv4 {
232 wire::IpVersion::Ipv4
233 } else {
234 wire::IpVersion::Ipv6
235 };
236
237 let resp = self
238 .request(
239 None,
240 Command::Raw(raw::Command::Open {
241 ip_version,
242 protocol: ip_protocol,
243 }),
244 )
245 .await?;
246
247 netcore::try_response_as!(resp, raw::Response::Opened { handle });
248
249 Ok(RawSocket::new(
250 self.command_channel(),
251 handle,
252 ip_protocol,
253 ip_version,
254 ))
255 }
256}