aboutsummaryrefslogtreecommitdiff
path: root/embassy-net/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-05-19 05:54:15 +0200
committerDario Nieuwenhuis <[email protected]>2022-05-19 06:15:01 +0200
commite3b8e35498e9ff749db698ef82b3d86a65ba4ffb (patch)
tree8951e6907927003d20d4567f500c29bf76009001 /embassy-net/src
parent0b2f43c391f1f1f6525484c369a24e72610dd8ef (diff)
Make embassy-net nightly-only.
It's useless without async traits, so juggling the `nightly` feature around is not worth the pain.
Diffstat (limited to 'embassy-net/src')
-rw-r--r--embassy-net/src/lib.rs5
-rw-r--r--embassy-net/src/tcp.rs (renamed from embassy-net/src/tcp/mod.rs)129
-rw-r--r--embassy-net/src/tcp/io_impl.rs129
3 files changed, 127 insertions, 136 deletions
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index ded841909..18dc1ef61 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -1,9 +1,6 @@
1#![cfg_attr(not(feature = "std"), no_std)] 1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(clippy::new_without_default)] 2#![allow(clippy::new_without_default)]
3#![cfg_attr( 3#![feature(generic_associated_types, type_alias_impl_trait)]
4 feature = "nightly",
5 feature(generic_associated_types, type_alias_impl_trait)
6)]
7 4
8// This mod MUST go first, so that the others see its macros. 5// This mod MUST go first, so that the others see its macros.
9pub(crate) mod fmt; 6pub(crate) mod fmt;
diff --git a/embassy-net/src/tcp/mod.rs b/embassy-net/src/tcp.rs
index 425e6acbc..c18651b93 100644
--- a/embassy-net/src/tcp/mod.rs
+++ b/embassy-net/src/tcp.rs
@@ -1,15 +1,14 @@
1use core::future::Future;
1use core::marker::PhantomData; 2use core::marker::PhantomData;
2use core::mem; 3use core::mem;
3use core::task::Poll; 4use core::task::Poll;
5use futures::future::poll_fn;
4use smoltcp::iface::{Context as SmolContext, SocketHandle}; 6use smoltcp::iface::{Context as SmolContext, SocketHandle};
5use smoltcp::socket::TcpSocket as SyncTcpSocket; 7use smoltcp::socket::TcpSocket as SyncTcpSocket;
6use smoltcp::socket::{TcpSocketBuffer, TcpState}; 8use smoltcp::socket::{TcpSocketBuffer, TcpState};
7use smoltcp::time::Duration; 9use smoltcp::time::Duration;
8use smoltcp::wire::IpEndpoint; 10use smoltcp::wire::IpEndpoint;
9 11
10#[cfg(feature = "nightly")]
11mod io_impl;
12
13use super::stack::Stack; 12use super::stack::Stack;
14 13
15#[derive(PartialEq, Eq, Clone, Copy, Debug)] 14#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@@ -221,10 +220,134 @@ impl<'d> embedded_io::Io for TcpSocket<'d> {
221 type Error = Error; 220 type Error = Error;
222} 221}
223 222
223impl<'d> embedded_io::asynch::Read for TcpSocket<'d> {
224 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
225 where
226 Self: 'a;
227
228 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
229 poll_fn(move |cx| {
230 // CAUTION: smoltcp semantics around EOF are different to what you'd expect
231 // from posix-like IO, so we have to tweak things here.
232 with_socket(self.handle, |s, _| match s.recv_slice(buf) {
233 // No data ready
234 Ok(0) => {
235 s.register_recv_waker(cx.waker());
236 Poll::Pending
237 }
238 // Data ready!
239 Ok(n) => Poll::Ready(Ok(n)),
240 // EOF
241 Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
242 // Connection reset. TODO: this can also be timeouts etc, investigate.
243 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
244 // smoltcp returns no errors other than the above.
245 Err(_) => unreachable!(),
246 })
247 })
248 }
249}
250
251impl<'d> embedded_io::asynch::Write for TcpSocket<'d> {
252 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
253 where
254 Self: 'a;
255
256 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
257 poll_fn(move |cx| {
258 with_socket(self.handle, |s, _| match s.send_slice(buf) {
259 // Not ready to send (no space in the tx buffer)
260 Ok(0) => {
261 s.register_send_waker(cx.waker());
262 Poll::Pending
263 }
264 // Some data sent
265 Ok(n) => Poll::Ready(Ok(n)),
266 // Connection reset. TODO: this can also be timeouts etc, investigate.
267 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
268 // smoltcp returns no errors other than the above.
269 Err(_) => unreachable!(),
270 })
271 })
272 }
273
274 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
275 where
276 Self: 'a;
277
278 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
279 poll_fn(move |_| {
280 Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
281 })
282 }
283}
284
224impl<'d> embedded_io::Io for TcpReader<'d> { 285impl<'d> embedded_io::Io for TcpReader<'d> {
225 type Error = Error; 286 type Error = Error;
226} 287}
227 288
289impl<'d> embedded_io::asynch::Read for TcpReader<'d> {
290 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
291 where
292 Self: 'a;
293
294 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
295 poll_fn(move |cx| {
296 // CAUTION: smoltcp semantics around EOF are different to what you'd expect
297 // from posix-like IO, so we have to tweak things here.
298 with_socket(self.handle, |s, _| match s.recv_slice(buf) {
299 // No data ready
300 Ok(0) => {
301 s.register_recv_waker(cx.waker());
302 Poll::Pending
303 }
304 // Data ready!
305 Ok(n) => Poll::Ready(Ok(n)),
306 // EOF
307 Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
308 // Connection reset. TODO: this can also be timeouts etc, investigate.
309 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
310 // smoltcp returns no errors other than the above.
311 Err(_) => unreachable!(),
312 })
313 })
314 }
315}
316
228impl<'d> embedded_io::Io for TcpWriter<'d> { 317impl<'d> embedded_io::Io for TcpWriter<'d> {
229 type Error = Error; 318 type Error = Error;
230} 319}
320
321impl<'d> embedded_io::asynch::Write for TcpWriter<'d> {
322 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
323 where
324 Self: 'a;
325
326 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
327 poll_fn(move |cx| {
328 with_socket(self.handle, |s, _| match s.send_slice(buf) {
329 // Not ready to send (no space in the tx buffer)
330 Ok(0) => {
331 s.register_send_waker(cx.waker());
332 Poll::Pending
333 }
334 // Some data sent
335 Ok(n) => Poll::Ready(Ok(n)),
336 // Connection reset. TODO: this can also be timeouts etc, investigate.
337 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
338 // smoltcp returns no errors other than the above.
339 Err(_) => unreachable!(),
340 })
341 })
342 }
343
344 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
345 where
346 Self: 'a;
347
348 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
349 poll_fn(move |_| {
350 Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
351 })
352 }
353}
diff --git a/embassy-net/src/tcp/io_impl.rs b/embassy-net/src/tcp/io_impl.rs
deleted file mode 100644
index b30c920b8..000000000
--- a/embassy-net/src/tcp/io_impl.rs
+++ /dev/null
@@ -1,129 +0,0 @@
1use core::future::Future;
2use core::task::Poll;
3use futures::future::poll_fn;
4
5use super::{with_socket, Error, TcpReader, TcpSocket, TcpWriter};
6
7impl<'d> embedded_io::asynch::Read for TcpSocket<'d> {
8 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
9 where
10 Self: 'a;
11
12 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
13 poll_fn(move |cx| {
14 // CAUTION: smoltcp semantics around EOF are different to what you'd expect
15 // from posix-like IO, so we have to tweak things here.
16 with_socket(self.handle, |s, _| match s.recv_slice(buf) {
17 // No data ready
18 Ok(0) => {
19 s.register_recv_waker(cx.waker());
20 Poll::Pending
21 }
22 // Data ready!
23 Ok(n) => Poll::Ready(Ok(n)),
24 // EOF
25 Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
26 // Connection reset. TODO: this can also be timeouts etc, investigate.
27 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
28 // smoltcp returns no errors other than the above.
29 Err(_) => unreachable!(),
30 })
31 })
32 }
33}
34
35impl<'d> embedded_io::asynch::Write for TcpSocket<'d> {
36 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
37 where
38 Self: 'a;
39
40 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
41 poll_fn(move |cx| {
42 with_socket(self.handle, |s, _| match s.send_slice(buf) {
43 // Not ready to send (no space in the tx buffer)
44 Ok(0) => {
45 s.register_send_waker(cx.waker());
46 Poll::Pending
47 }
48 // Some data sent
49 Ok(n) => Poll::Ready(Ok(n)),
50 // Connection reset. TODO: this can also be timeouts etc, investigate.
51 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
52 // smoltcp returns no errors other than the above.
53 Err(_) => unreachable!(),
54 })
55 })
56 }
57
58 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
59 where
60 Self: 'a;
61
62 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
63 poll_fn(move |_| {
64 Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
65 })
66 }
67}
68
69impl<'d> embedded_io::asynch::Read for TcpReader<'d> {
70 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
71 where
72 Self: 'a;
73
74 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
75 poll_fn(move |cx| {
76 // CAUTION: smoltcp semantics around EOF are different to what you'd expect
77 // from posix-like IO, so we have to tweak things here.
78 with_socket(self.handle, |s, _| match s.recv_slice(buf) {
79 // No data ready
80 Ok(0) => {
81 s.register_recv_waker(cx.waker());
82 Poll::Pending
83 }
84 // Data ready!
85 Ok(n) => Poll::Ready(Ok(n)),
86 // EOF
87 Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
88 // Connection reset. TODO: this can also be timeouts etc, investigate.
89 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
90 // smoltcp returns no errors other than the above.
91 Err(_) => unreachable!(),
92 })
93 })
94 }
95}
96
97impl<'d> embedded_io::asynch::Write for TcpWriter<'d> {
98 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
99 where
100 Self: 'a;
101
102 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
103 poll_fn(move |cx| {
104 with_socket(self.handle, |s, _| match s.send_slice(buf) {
105 // Not ready to send (no space in the tx buffer)
106 Ok(0) => {
107 s.register_send_waker(cx.waker());
108 Poll::Pending
109 }
110 // Some data sent
111 Ok(n) => Poll::Ready(Ok(n)),
112 // Connection reset. TODO: this can also be timeouts etc, investigate.
113 Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
114 // smoltcp returns no errors other than the above.
115 Err(_) => unreachable!(),
116 })
117 })
118 }
119
120 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
121 where
122 Self: 'a;
123
124 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
125 poll_fn(move |_| {
126 Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
127 })
128 }
129}