diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-05-19 05:54:15 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-05-19 06:15:01 +0200 |
| commit | e3b8e35498e9ff749db698ef82b3d86a65ba4ffb (patch) | |
| tree | 8951e6907927003d20d4567f500c29bf76009001 /embassy-net/src | |
| parent | 0b2f43c391f1f1f6525484c369a24e72610dd8ef (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.rs | 5 | ||||
| -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.rs | 129 |
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. |
| 9 | pub(crate) mod fmt; | 6 | pub(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 @@ | |||
| 1 | use core::future::Future; | ||
| 1 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 2 | use core::mem; | 3 | use core::mem; |
| 3 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | use futures::future::poll_fn; | ||
| 4 | use smoltcp::iface::{Context as SmolContext, SocketHandle}; | 6 | use smoltcp::iface::{Context as SmolContext, SocketHandle}; |
| 5 | use smoltcp::socket::TcpSocket as SyncTcpSocket; | 7 | use smoltcp::socket::TcpSocket as SyncTcpSocket; |
| 6 | use smoltcp::socket::{TcpSocketBuffer, TcpState}; | 8 | use smoltcp::socket::{TcpSocketBuffer, TcpState}; |
| 7 | use smoltcp::time::Duration; | 9 | use smoltcp::time::Duration; |
| 8 | use smoltcp::wire::IpEndpoint; | 10 | use smoltcp::wire::IpEndpoint; |
| 9 | 11 | ||
| 10 | #[cfg(feature = "nightly")] | ||
| 11 | mod io_impl; | ||
| 12 | |||
| 13 | use super::stack::Stack; | 12 | use 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 | ||
| 223 | impl<'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 | |||
| 251 | impl<'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 | |||
| 224 | impl<'d> embedded_io::Io for TcpReader<'d> { | 285 | impl<'d> embedded_io::Io for TcpReader<'d> { |
| 225 | type Error = Error; | 286 | type Error = Error; |
| 226 | } | 287 | } |
| 227 | 288 | ||
| 289 | impl<'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 | |||
| 228 | impl<'d> embedded_io::Io for TcpWriter<'d> { | 317 | impl<'d> embedded_io::Io for TcpWriter<'d> { |
| 229 | type Error = Error; | 318 | type Error = Error; |
| 230 | } | 319 | } |
| 320 | |||
| 321 | impl<'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 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | use core::task::Poll; | ||
| 3 | use futures::future::poll_fn; | ||
| 4 | |||
| 5 | use super::{with_socket, Error, TcpReader, TcpSocket, TcpWriter}; | ||
| 6 | |||
| 7 | impl<'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 | |||
| 35 | impl<'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 | |||
| 69 | impl<'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 | |||
| 97 | impl<'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 | } | ||
