From 790e4e1594d455d06c7303a628172244e78af0da Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Tue, 13 Dec 2022 16:18:16 +0100 Subject: examples/std: update to new embassy-net trait. --- examples/std/src/tuntap.rs | 113 +++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 55 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/tuntap.rs b/examples/std/src/tuntap.rs index a0cace7f7..bb3e194cc 100644 --- a/examples/std/src/tuntap.rs +++ b/examples/std/src/tuntap.rs @@ -1,8 +1,10 @@ use std::io; use std::io::{Read, Write}; use std::os::unix::io::{AsRawFd, RawFd}; +use std::task::Context; use async_io::Async; +use embassy_net::device::{self, Device, DeviceCapabilities, LinkState}; use log::*; pub const SIOCGIFMTU: libc::c_ulong = 0x8921; @@ -125,54 +127,35 @@ impl io::Write for TunTap { pub struct TunTapDevice { device: Async, - waker: Option, } impl TunTapDevice { pub fn new(name: &str) -> io::Result { Ok(Self { device: Async::new(TunTap::new(name)?)?, - waker: None, }) } } -use core::task::Waker; -use std::task::Context; - -use embassy_net::{Device, DeviceCapabilities, LinkState, Packet, PacketBox, PacketBoxExt, PacketBuf}; - impl Device for TunTapDevice { - fn is_transmit_ready(&mut self) -> bool { - true - } + type RxToken<'a> = RxToken where Self: 'a; + type TxToken<'a> = TxToken<'a> where Self: 'a; - fn transmit(&mut self, pkt: PacketBuf) { - // todo handle WouldBlock - match self.device.get_mut().write(&pkt) { - Ok(_) => {} - Err(e) if e.kind() == io::ErrorKind::WouldBlock => { - info!("transmit WouldBlock"); - } - Err(e) => panic!("transmit error: {:?}", e), - } - } - - fn receive(&mut self) -> Option { - let mut pkt = PacketBox::new(Packet::new()).unwrap(); + fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { + let mut buf = vec![0; self.device.get_ref().mtu]; loop { - match self.device.get_mut().read(&mut pkt[..]) { + match self.device.get_mut().read(&mut buf) { Ok(n) => { - return Some(pkt.slice(0..n)); + buf.truncate(n); + return Some(( + RxToken { buffer: buf }, + TxToken { + device: &mut self.device, + }, + )); } Err(e) if e.kind() == io::ErrorKind::WouldBlock => { - let ready = if let Some(w) = self.waker.as_ref() { - let mut cx = Context::from_waker(w); - self.device.poll_readable(&mut cx).is_ready() - } else { - false - }; - if !ready { + if !self.device.poll_readable(cx).is_ready() { return None; } } @@ -181,28 +164,10 @@ impl Device for TunTapDevice { } } - fn register_waker(&mut self, w: &Waker) { - match self.waker { - // Optimization: If both the old and new Wakers wake the same task, we can simply - // keep the old waker, skipping the clone. (In most executor implementations, - // cloning a waker is somewhat expensive, comparable to cloning an Arc). - Some(ref w2) if (w2.will_wake(w)) => {} - _ => { - // clone the new waker and store it - if let Some(old_waker) = core::mem::replace(&mut self.waker, Some(w.clone())) { - // We had a waker registered for another task. Wake it, so the other task can - // reregister itself if it's still interested. - // - // If two tasks are waiting on the same thing concurrently, this will cause them - // to wake each other in a loop fighting over this WakerRegistration. This wastes - // CPU but things will still work. - // - // If the user wants to have two tasks waiting on the same thing they should use - // a more appropriate primitive that can store multiple wakers. - old_waker.wake() - } - } - } + fn transmit(&mut self, _cx: &mut Context) -> Option> { + Some(TxToken { + device: &mut self.device, + }) } fn capabilities(&self) -> DeviceCapabilities { @@ -211,7 +176,7 @@ impl Device for TunTapDevice { caps } - fn link_state(&mut self) -> LinkState { + fn link_state(&mut self, _cx: &mut Context) -> LinkState { LinkState::Up } @@ -219,3 +184,41 @@ impl Device for TunTapDevice { [0x02, 0x03, 0x04, 0x05, 0x06, 0x07] } } + +#[doc(hidden)] +pub struct RxToken { + buffer: Vec, +} + +impl device::RxToken for RxToken { + fn consume(mut self, f: F) -> R + where + F: FnOnce(&mut [u8]) -> R, + { + f(&mut self.buffer) + } +} + +#[doc(hidden)] +pub struct TxToken<'a> { + device: &'a mut Async, +} + +impl<'a> device::TxToken for TxToken<'a> { + fn consume(self, len: usize, f: F) -> R + where + F: FnOnce(&mut [u8]) -> R, + { + let mut buffer = vec![0; len]; + let result = f(&mut buffer); + + // todo handle WouldBlock with async + match self.device.get_mut().write(&buffer) { + Ok(_) => {} + Err(e) if e.kind() == io::ErrorKind::WouldBlock => info!("transmit WouldBlock"), + Err(e) => panic!("transmit error: {:?}", e), + } + + result + } +} -- cgit From 1f033d509afb4e590a81896de66af683fda4e706 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 26 Dec 2022 03:33:49 +0100 Subject: net: split driver trait to a separate crate. --- examples/std/src/tuntap.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/tuntap.rs b/examples/std/src/tuntap.rs index bb3e194cc..d918a2e62 100644 --- a/examples/std/src/tuntap.rs +++ b/examples/std/src/tuntap.rs @@ -4,7 +4,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; use std::task::Context; use async_io::Async; -use embassy_net::device::{self, Device, DeviceCapabilities, LinkState}; +use embassy_net_driver::{self, Capabilities, Driver, LinkState}; use log::*; pub const SIOCGIFMTU: libc::c_ulong = 0x8921; @@ -137,7 +137,7 @@ impl TunTapDevice { } } -impl Device for TunTapDevice { +impl Driver for TunTapDevice { type RxToken<'a> = RxToken where Self: 'a; type TxToken<'a> = TxToken<'a> where Self: 'a; @@ -170,8 +170,8 @@ impl Device for TunTapDevice { }) } - fn capabilities(&self) -> DeviceCapabilities { - let mut caps = DeviceCapabilities::default(); + fn capabilities(&self) -> Capabilities { + let mut caps = Capabilities::default(); caps.max_transmission_unit = self.device.get_ref().mtu; caps } @@ -190,7 +190,7 @@ pub struct RxToken { buffer: Vec, } -impl device::RxToken for RxToken { +impl embassy_net_driver::RxToken for RxToken { fn consume(mut self, f: F) -> R where F: FnOnce(&mut [u8]) -> R, @@ -204,7 +204,7 @@ pub struct TxToken<'a> { device: &'a mut Async, } -impl<'a> device::TxToken for TxToken<'a> { +impl<'a> embassy_net_driver::TxToken for TxToken<'a> { fn consume(self, len: usize, f: F) -> R where F: FnOnce(&mut [u8]) -> R, -- cgit From 8f4fae9b36f017a8ab65491ef49b72499a9486dc Mon Sep 17 00:00:00 2001 From: Paweł Jan Czochański Date: Wed, 18 Jan 2023 10:10:33 +0100 Subject: Add smoltcp dhcp socket configuration --- examples/std/src/bin/net.rs | 15 ++++++--------- examples/std/src/bin/net_udp.rs | 13 ++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 9b1450b72..1ae39cace 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -1,9 +1,11 @@ #![feature(type_alias_impl_trait)] +use std::default::Default; + use clap::Parser; use embassy_executor::{Executor, Spawner}; use embassy_net::tcp::TcpSocket; -use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, Stack, StackResources}; +use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; use embedded_io::asynch::Write; use heapless::Vec; use log::*; @@ -48,13 +50,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - ConfigStrategy::Static(embassy_net::Config { + Config::Static(embassy_net::StaticConfig { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - ConfigStrategy::Dhcp + Config::Dhcp(Default::default()) }; // Generate random seed @@ -63,12 +65,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index 392a97f0d..d1a8fe1e0 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -3,7 +3,7 @@ use clap::Parser; use embassy_executor::{Executor, Spawner}; use embassy_net::udp::UdpSocket; -use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources}; +use embassy_net::{Config, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources}; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; @@ -47,13 +47,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - ConfigStrategy::Static(embassy_net::Config { + Config::Static(embassy_net::StaticConfig { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - ConfigStrategy::Dhcp + Config::Dhcp(Default::default()) }; // Generate random seed @@ -62,12 +62,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); -- cgit From fe15a7beee5f948b1e4c1cb8ab8e5cc85efb4662 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 19 Jan 2023 14:40:58 +0100 Subject: net: allocate space for 2 sockets, needed for dhcp. --- examples/std/src/bin/net.rs | 2 +- examples/std/src/bin/net_udp.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 1ae39cace..451850d99 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -65,7 +65,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index d1a8fe1e0..f1923f180 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -62,7 +62,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); -- cgit From 9cfea693edec5af17ba698f64b3f0a168ad92944 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 31 Jan 2023 22:06:41 +0100 Subject: Add DNS socket to embassy-net --- examples/std/src/bin/net_dns.rs | 102 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 examples/std/src/bin/net_dns.rs (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs new file mode 100644 index 000000000..6203f8370 --- /dev/null +++ b/examples/std/src/bin/net_dns.rs @@ -0,0 +1,102 @@ +#![feature(type_alias_impl_trait)] + +use std::default::Default; + +use clap::Parser; +use embassy_executor::{Executor, Spawner}; +use embassy_net::dns::{DnsQueryType, DnsSocket}; +use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; +use heapless::Vec; +use log::*; +use rand_core::{OsRng, RngCore}; +use static_cell::StaticCell; + +#[path = "../tuntap.rs"] +mod tuntap; + +use crate::tuntap::TunTapDevice; + +macro_rules! singleton { + ($val:expr) => {{ + type T = impl Sized; + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) + }}; +} + +#[derive(Parser)] +#[clap(version = "1.0")] +struct Opts { + /// TAP device name + #[clap(long, default_value = "tap0")] + tap: String, + /// use a static IP instead of DHCP + #[clap(long)] + static_ip: bool, +} + +#[embassy_executor::task] +async fn net_task(stack: &'static Stack) -> ! { + stack.run().await +} + +#[embassy_executor::task] +async fn main_task(spawner: Spawner) { + let opts: Opts = Opts::parse(); + + // Init network device + let device = TunTapDevice::new(&opts.tap).unwrap(); + + // Choose between dhcp or static ip + let config = if opts.static_ip { + Config::Static(embassy_net::StaticConfig { + address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 1), 24), + dns_servers: Vec::from_slice(&[Ipv4Address::new(8, 8, 4, 4).into(), Ipv4Address::new(8, 8, 8, 8).into()]) + .unwrap(), + gateway: Some(Ipv4Address::new(192, 168, 69, 100)), + }) + } else { + Config::Dhcp(Default::default()) + }; + + // Generate random seed + let mut seed = [0; 8]; + OsRng.fill_bytes(&mut seed); + let seed = u64::from_le_bytes(seed); + + // Init network stack + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); + + // Launch network task + spawner.spawn(net_task(stack)).unwrap(); + + // Then we can use it! + + let mut socket = DnsSocket::new(stack, vec![]); + + let host = "example.com"; + info!("querying host {:?}...", host); + match socket.query(host, DnsQueryType::A).await { + Ok(r) => { + info!("query response: {:?}", r); + } + Err(e) => { + warn!("query error: {:?}", e); + } + }; +} + +static EXECUTOR: StaticCell = StaticCell::new(); + +fn main() { + env_logger::builder() + .filter_level(log::LevelFilter::Debug) + .filter_module("async_io", log::LevelFilter::Info) + .format_timestamp_nanos() + .init(); + + let executor = EXECUTOR.init(Executor::new()); + executor.run(|spawner| { + spawner.spawn(main_task(spawner)).unwrap(); + }); +} -- cgit From cd440a49d677f7dfc09e405d99b87a49fba9ba31 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Fri, 10 Feb 2023 17:43:23 +0100 Subject: Rewrite to use a single socket --- examples/std/src/bin/net_dns.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index 6203f8370..e787cb823 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -71,8 +71,7 @@ async fn main_task(spawner: Spawner) { spawner.spawn(net_task(stack)).unwrap(); // Then we can use it! - - let mut socket = DnsSocket::new(stack, vec![]); + let socket = DnsSocket::new(stack); let host = "example.com"; info!("querying host {:?}...", host); -- cgit From a509af4bc00ae6945e568b268731e854e8ae3994 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 10 Feb 2023 23:00:16 +0100 Subject: exmaples/dns: don't use the socket. --- examples/std/src/bin/net_dns.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index e787cb823..e1cc45a38 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -4,7 +4,7 @@ use std::default::Default; use clap::Parser; use embassy_executor::{Executor, Spawner}; -use embassy_net::dns::{DnsQueryType, DnsSocket}; +use embassy_net::dns::DnsQueryType; use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; use heapless::Vec; use log::*; @@ -65,17 +65,14 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); + let stack: &Stack<_> = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); - // Then we can use it! - let socket = DnsSocket::new(stack); - let host = "example.com"; info!("querying host {:?}...", host); - match socket.query(host, DnsQueryType::A).await { + match stack.dns_query(host, DnsQueryType::A).await { Ok(r) => { info!("query response: {:?}", r); } -- cgit From bc71230cd07296468f2e03c00f9ceddbab67c9d9 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 26 Feb 2023 21:50:12 +0100 Subject: examples/std: fix net running out of sockets. --- examples/std/src/bin/net.rs | 2 +- examples/std/src/bin/net_dns.rs | 2 +- examples/std/src/bin/net_udp.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 451850d99..e018e18c9 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -65,7 +65,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index e1cc45a38..d1e1f8212 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -65,7 +65,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack: &Stack<_> = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); + let stack: &Stack<_> = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index f1923f180..328a0536c 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -62,7 +62,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); -- cgit From 26d7610554f262c2c25f99fb441e6dbd6abec61f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 15 May 2023 00:38:58 +0200 Subject: net: do not use smoltcp Instant/Duration in public API. --- examples/std/src/bin/net.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index e018e18c9..d93616254 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -6,6 +6,7 @@ use clap::Parser; use embassy_executor::{Executor, Spawner}; use embassy_net::tcp::TcpSocket; use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; +use embassy_time::Duration; use embedded_io::asynch::Write; use heapless::Vec; use log::*; @@ -75,7 +76,7 @@ async fn main_task(spawner: Spawner) { let mut tx_buffer = [0; 4096]; let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); - socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); + socket.set_timeout(Some(Duration::from_secs(10))); let remote_endpoint = (Ipv4Address::new(192, 168, 69, 100), 8000); info!("connecting to {:?}...", remote_endpoint); -- cgit From 62857bdb2d0c34aa2ee9e82454ee0182139bab2c Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 15 May 2023 00:55:34 +0200 Subject: net: reexport UDP PacketMetadata under the udp module. --- examples/std/src/bin/net_udp.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index 328a0536c..4df23edf6 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -2,8 +2,8 @@ use clap::Parser; use embassy_executor::{Executor, Spawner}; -use embassy_net::udp::UdpSocket; -use embassy_net::{Config, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources}; +use embassy_net::udp::{PacketMetadata, UdpSocket}; +use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; -- cgit From 373eb973574ac9390f8b4b19c2de486b1b38101a Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Thu, 25 May 2023 19:36:45 +0800 Subject: Add std example of a TCP listener This also demonstrates calling .abort() on a TCP socket and ensuring that the reset packet is sent out. --- examples/std/src/bin/tcp_accept.rs | 133 +++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 examples/std/src/bin/tcp_accept.rs (limited to 'examples/std/src') diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs new file mode 100644 index 000000000..97ce77f42 --- /dev/null +++ b/examples/std/src/bin/tcp_accept.rs @@ -0,0 +1,133 @@ +#![feature(type_alias_impl_trait)] + +use core::fmt::Write as _; +use std::default::Default; + +use clap::Parser; +use embassy_executor::{Executor, Spawner}; +use embassy_net::tcp::TcpSocket; +use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; +use embassy_time::{Duration, Timer}; +use embedded_io::asynch::Write as _; +use heapless::Vec; +use log::*; +use rand_core::{OsRng, RngCore}; +use static_cell::StaticCell; + +#[path = "../tuntap.rs"] +mod tuntap; + +use crate::tuntap::TunTapDevice; + +macro_rules! singleton { + ($val:expr) => {{ + type T = impl Sized; + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) + }}; +} + +#[derive(Parser)] +#[clap(version = "1.0")] +struct Opts { + /// TAP device name + #[clap(long, default_value = "tap0")] + tap: String, + /// use a static IP instead of DHCP + #[clap(long)] + static_ip: bool, +} + +#[embassy_executor::task] +async fn net_task(stack: &'static Stack) -> ! { + stack.run().await +} + +#[derive(Default)] +struct StrWrite(pub heapless::Vec); + +impl core::fmt::Write for StrWrite { + fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { + self.0.extend_from_slice(s.as_bytes()).unwrap(); + Ok(()) + } +} + +#[embassy_executor::task] +async fn main_task(spawner: Spawner) { + let opts: Opts = Opts::parse(); + + // Init network device + let device = TunTapDevice::new(&opts.tap).unwrap(); + + // Choose between dhcp or static ip + let config = if opts.static_ip { + Config::Static(embassy_net::StaticConfig { + address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), + dns_servers: Vec::new(), + gateway: Some(Ipv4Address::new(192, 168, 69, 1)), + }) + } else { + Config::Dhcp(Default::default()) + }; + + // Generate random seed + let mut seed = [0; 8]; + OsRng.fill_bytes(&mut seed); + let seed = u64::from_le_bytes(seed); + + // Init network stack + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed)); + + // Launch network task + spawner.spawn(net_task(stack)).unwrap(); + + // Then we can use it! + let mut rx_buffer = [0; 4096]; + let mut tx_buffer = [0; 4096]; + + loop { + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + info!("Listening on TCP:9999..."); + if let Err(_) = socket.accept(9999).await { + warn!("accept error"); + continue; + } + + info!("Accepted a connection"); + + // Write some quick output + for i in 1..=5 { + let mut w = StrWrite::default(); + write!(w, "{}! ", i).unwrap(); + let r = socket.write_all(&w.0).await; + if let Err(e) = r { + warn!("write error: {:?}", e); + return; + } + + Timer::after(Duration::from_millis(500)).await; + } + info!("Closing the connection"); + socket.abort(); + info!("Flushing the RST out..."); + socket.flush().await; + info!("Finished with the socket"); + } +} + +static EXECUTOR: StaticCell = StaticCell::new(); + +fn main() { + env_logger::builder() + .filter_level(log::LevelFilter::Debug) + .filter_module("async_io", log::LevelFilter::Info) + .format_timestamp_nanos() + .init(); + + let executor = EXECUTOR.init(Executor::new()); + executor.run(|spawner| { + spawner.spawn(main_task(spawner)).unwrap(); + }); +} -- cgit From 1d8321b821d114b369d5a087a1a7a6600228b032 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 1 Jun 2023 01:32:11 +0200 Subject: Use make_static! from static-cell v1.1 --- examples/std/src/bin/net.rs | 18 +++++++----------- examples/std/src/bin/net_dns.rs | 18 +++++++----------- examples/std/src/bin/net_udp.rs | 18 +++++++----------- examples/std/src/bin/tcp_accept.rs | 18 +++++++----------- 4 files changed, 28 insertions(+), 44 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index d93616254..b42bfc13b 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -11,21 +11,12 @@ use embedded_io::asynch::Write; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; -use static_cell::StaticCell; +use static_cell::{make_static, StaticCell}; #[path = "../tuntap.rs"] mod tuntap; use crate::tuntap::TunTapDevice; - -macro_rules! singleton { - ($val:expr) => {{ - type T = impl Sized; - static STATIC_CELL: StaticCell = StaticCell::new(); - STATIC_CELL.init_with(move || $val) - }}; -} - #[derive(Parser)] #[clap(version = "1.0")] struct Opts { @@ -66,7 +57,12 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed)); + let stack = &*make_static!(Stack::new( + device, + config, + make_static!(StackResources::<3>::new()), + seed + )); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index d1e1f8212..932ac5831 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -9,21 +9,12 @@ use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; -use static_cell::StaticCell; +use static_cell::{make_static, StaticCell}; #[path = "../tuntap.rs"] mod tuntap; use crate::tuntap::TunTapDevice; - -macro_rules! singleton { - ($val:expr) => {{ - type T = impl Sized; - static STATIC_CELL: StaticCell = StaticCell::new(); - STATIC_CELL.init_with(move || $val) - }}; -} - #[derive(Parser)] #[clap(version = "1.0")] struct Opts { @@ -65,7 +56,12 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack: &Stack<_> = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed)); + let stack: &Stack<_> = &*make_static!(Stack::new( + device, + config, + make_static!(StackResources::<3>::new()), + seed + )); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index 4df23edf6..d89ec7643 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -7,21 +7,12 @@ use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; -use static_cell::StaticCell; +use static_cell::{make_static, StaticCell}; #[path = "../tuntap.rs"] mod tuntap; use crate::tuntap::TunTapDevice; - -macro_rules! singleton { - ($val:expr) => {{ - type T = impl Sized; - static STATIC_CELL: StaticCell = StaticCell::new(); - STATIC_CELL.init_with(move || $val) - }}; -} - #[derive(Parser)] #[clap(version = "1.0")] struct Opts { @@ -62,7 +53,12 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed)); + let stack = &*make_static!(Stack::new( + device, + config, + make_static!(StackResources::<3>::new()), + seed + )); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 97ce77f42..d24e218dc 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -12,21 +12,12 @@ use embedded_io::asynch::Write as _; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; -use static_cell::StaticCell; +use static_cell::{make_static, StaticCell}; #[path = "../tuntap.rs"] mod tuntap; use crate::tuntap::TunTapDevice; - -macro_rules! singleton { - ($val:expr) => {{ - type T = impl Sized; - static STATIC_CELL: StaticCell = StaticCell::new(); - STATIC_CELL.init_with(move || $val) - }}; -} - #[derive(Parser)] #[clap(version = "1.0")] struct Opts { @@ -77,7 +68,12 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<3>::new()), seed)); + let stack = &*make_static!(Stack::new( + device, + config, + make_static!(StackResources::<3>::new()), + seed + )); // Launch network task spawner.spawn(net_task(stack)).unwrap(); -- cgit From 404aa292890503806a32eac5ae518dbeeadd60eb Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 1 Jun 2023 02:22:46 +0200 Subject: cortex-m: remove owned interrupts. --- examples/std/src/bin/tcp_accept.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index d24e218dc..01695baea 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -108,7 +108,7 @@ async fn main_task(spawner: Spawner) { info!("Closing the connection"); socket.abort(); info!("Flushing the RST out..."); - socket.flush().await; + _ = socket.flush().await; info!("Finished with the socket"); } } -- cgit From 54bab33c7342510be538bc6d8545fe50146557cf Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 5 Jun 2023 14:57:17 +0200 Subject: Rename StaticConfig to StaticConfigV4 --- examples/std/src/bin/net.rs | 2 +- examples/std/src/bin/net_dns.rs | 2 +- examples/std/src/bin/net_udp.rs | 2 +- examples/std/src/bin/tcp_accept.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index b42bfc13b..14cf3f25b 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -42,7 +42,7 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::Static(embassy_net::StaticConfig { + Config::StaticV4(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index 932ac5831..0a479a744 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -40,7 +40,7 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::Static(embassy_net::StaticConfig { + Config::StaticV4(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 1), 24), dns_servers: Vec::from_slice(&[Ipv4Address::new(8, 8, 4, 4).into(), Ipv4Address::new(8, 8, 8, 8).into()]) .unwrap(), diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index d89ec7643..0ede5d998 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -38,7 +38,7 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::Static(embassy_net::StaticConfig { + Config::StaticV4(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 01695baea..4379d0439 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -53,7 +53,7 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::Static(embassy_net::StaticConfig { + Config::StaticV4(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), -- cgit From 352f0b6c3823797576c36f417d6be40189bca5d5 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Wed, 7 Jun 2023 12:04:15 +0200 Subject: net: Support dual stack IP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/std/src/bin/net.rs | 4 ++-- examples/std/src/bin/net_dns.rs | 4 ++-- examples/std/src/bin/net_udp.rs | 4 ++-- examples/std/src/bin/tcp_accept.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'examples/std/src') diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 14cf3f25b..3aadb029d 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -42,13 +42,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::StaticV4(embassy_net::StaticConfigV4 { + Config::ipv4_static(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - Config::Dhcp(Default::default()) + Config::dhcpv4(Default::default()) }; // Generate random seed diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs index 0a479a744..65b5a2cd9 100644 --- a/examples/std/src/bin/net_dns.rs +++ b/examples/std/src/bin/net_dns.rs @@ -40,14 +40,14 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::StaticV4(embassy_net::StaticConfigV4 { + Config::ipv4_static(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 1), 24), dns_servers: Vec::from_slice(&[Ipv4Address::new(8, 8, 4, 4).into(), Ipv4Address::new(8, 8, 8, 8).into()]) .unwrap(), gateway: Some(Ipv4Address::new(192, 168, 69, 100)), }) } else { - Config::Dhcp(Default::default()) + Config::dhcpv4(Default::default()) }; // Generate random seed diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index 0ede5d998..3fc46156c 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -38,13 +38,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::StaticV4(embassy_net::StaticConfigV4 { + Config::ipv4_static(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - Config::Dhcp(Default::default()) + Config::dhcpv4(Default::default()) }; // Generate random seed diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs index 4379d0439..df09986ac 100644 --- a/examples/std/src/bin/tcp_accept.rs +++ b/examples/std/src/bin/tcp_accept.rs @@ -53,13 +53,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - Config::StaticV4(embassy_net::StaticConfigV4 { + Config::ipv4_static(embassy_net::StaticConfigV4 { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - Config::Dhcp(Default::default()) + Config::dhcpv4(Default::default()) }; // Generate random seed -- cgit