aboutsummaryrefslogtreecommitdiff
path: root/examples/std
diff options
context:
space:
mode:
Diffstat (limited to 'examples/std')
-rw-r--r--examples/std/Cargo.toml20
-rw-r--r--examples/std/README.md125
-rw-r--r--examples/std/src/bin/net.rs30
-rw-r--r--examples/std/src/bin/net_dns.rs22
-rw-r--r--examples/std/src/bin/net_ppp.rs85
-rw-r--r--examples/std/src/bin/net_udp.rs22
-rw-r--r--examples/std/src/bin/serial.rs2
-rw-r--r--examples/std/src/bin/tcp_accept.rs39
-rw-r--r--examples/std/src/bin/tick.rs2
-rw-r--r--examples/std/tap.sh7
10 files changed, 192 insertions, 162 deletions
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index 58ea894f3..6dc6a353d 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -1,16 +1,17 @@
1[package] 1[package]
2edition = "2021" 2edition = "2024"
3name = "embassy-std-examples" 3name = "embassy-std-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6publish = false
6 7
7[dependencies] 8[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["log"] } 9embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["log"] }
9embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-std", "executor-thread", "log", "integrated-timers"] } 10embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log"] }
10embassy-time = { version = "0.3.1", path = "../../embassy-time", features = ["log", "std", ] } 11embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["log", "std", ] }
11embassy-net = { version = "0.4.0", path = "../../embassy-net", features=[ "std", "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] } 12embassy-net = { version = "0.7.1", path = "../../embassy-net", features=[ "log", "medium-ethernet", "medium-ip", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6"] }
12embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" } 13embassy-net-tuntap = { version = "0.1.0", path = "../../embassy-net-tuntap" }
13embassy-net-ppp = { version = "0.1.0", path = "../../embassy-net-ppp", features = ["log"]} 14embassy-net-ppp = { version = "0.2.1", path = "../../embassy-net-ppp", features = ["log"]}
14embedded-io-async = { version = "0.6.1" } 15embedded-io-async = { version = "0.6.1" }
15embedded-io-adapters = { version = "0.6.1", features = ["futures-03"] } 16embedded-io-adapters = { version = "0.6.1", features = ["futures-03"] }
16critical-section = { version = "1.1", features = ["std"] } 17critical-section = { version = "1.1", features = ["std"] }
@@ -21,9 +22,14 @@ futures = { version = "0.3.17" }
21log = "0.4.14" 22log = "0.4.14"
22nix = "0.26.2" 23nix = "0.26.2"
23clap = { version = "3.0.0-beta.5", features = ["derive"] } 24clap = { version = "3.0.0-beta.5", features = ["derive"] }
24rand_core = { version = "0.6.3", features = ["std"] } 25rand_core = { version = "0.9.1", features = ["std", "os_rng"] }
25heapless = { version = "0.8", default-features = false } 26heapless = { version = "0.8", default-features = false }
26static_cell = "2" 27static_cell = "2"
27 28
28[profile.release] 29[profile.release]
29debug = 2 30debug = 2
31
32[package.metadata.embassy]
33build = [
34 { artifact-dir = "out/examples/std" }
35]
diff --git a/examples/std/README.md b/examples/std/README.md
index e3a59d6ea..ac2c2a1a6 100644
--- a/examples/std/README.md
+++ b/examples/std/README.md
@@ -1,23 +1,128 @@
1 1
2## Running the `embassy-net` examples 2## Running the `embassy-net` examples
3 3
4First, create the tap0 interface. You only need to do this once. 4To run `net`, `tcp_accept`, `net_udp` and `net_dns` examples you will need a tap interface. Before running these examples, create the tap99 interface. (The number was chosen to
5hopefully not collide with anything.) You only need to do this once every time you reboot your computer.
5 6
6```sh 7```sh
7sudo ip tuntap add name tap0 mode tap user $USER 8cd $EMBASSY_ROOT/examples/std/
8sudo ip link set tap0 up 9sudo sh tap.sh
9sudo ip addr add 192.168.69.100/24 dev tap0
10sudo ip -6 addr add fe80::100/64 dev tap0
11sudo ip -6 addr add fdaa::100/64 dev tap0
12sudo ip -6 route add fe80::/64 dev tap0
13sudo ip -6 route add fdaa::/64 dev tap0
14``` 10```
15 11
16Second, have something listening there. For example `nc -lp 8000` 12The example `net_ppp` requires different steps that are detailed in its section.
13
14### `net` example
15
16For this example, you need to have something listening in the correct port. For example `nc -lp 8000`.
17 17
18Then run the example located in the `examples` folder: 18Then run the example located in the `examples` folder:
19 19
20```sh 20```sh
21cd $EMBASSY_ROOT/examples/std/ 21cd $EMBASSY_ROOT/examples/std/
22cargo run --bin net -- --static-ip 22cargo run --bin net -- --tap tap99 --static-ip
23```
24### `tcp_accept` example
25
26This example listen for a tcp connection.
27
28First run the example located in the `examples` folder:
29
30```sh
31cd $EMBASSY_ROOT/examples/std/
32cargo run --bin tcp_accept -- --tap tap99 --static-ip
33```
34
35Then open a connection to the port. For example `nc 192.168.69.2 9999`.
36
37### `net_udp` example
38
39This example listen for a udp connection.
40
41First run the example located in the `examples` folder:
42
43```sh
44cd $EMBASSY_ROOT/examples/std/
45cargo run --bin net_udp -- --tap tap99 --static-ip
46```
47
48Then open a connection to the port. For example `nc -u 192.168.69.2 9400`.
49
50### `net_dns` example
51
52This example queries a `DNS` for the IP address of `www.example.com`.
53
54In order to achieve this, the `tap99` interface requires configuring tap99 as a gateway device temporarily.
55
56For example, in Ubuntu you can do this by:
57
581. Identifying your default route device. In the next example `eth0`
59
60```sh
61ip r | grep "default"
62default via 192.168.2.1 dev eth0 proto kernel metric 35
63```
64
652. Enabling temporarily IP Forwarding:
66
67```sh
68sudo sysctl -w net.ipv4.ip_forward=1
69```
70
713. Configuring NAT to mascarade traffic from `tap99` to `eth0`
72
73```sh
74sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
75sudo iptables -A FORWARD -i tap99 -j ACCEPT
76sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
77```
78
794. Then you can run the example located in the `examples` folder:
80
81```sh
82cd $EMBASSY_ROOT/examples/std/
83cargo run --bin net_dns -- --tap tap99 --static-ip
84```
85
86### `net_ppp` example
87
88This example establish a Point-to-Point Protocol (PPP) connection that can be used, for example, for connecting to internet through a 4G modem via a serial channel.
89
90The example creates a PPP bridge over a virtual serial channel between `pty1` and `pty2` for the example code and a PPP server running on the same computer.
91
92To run this example you will need:
93- ppp (pppd server)
94- socat (socket CAT)
95
96To run the examples you may follow the next steps:
97
981. Save the PPP server configuration:
99```sh
100sudo sh -c 'echo "myuser $(hostname) mypass 192.168.7.10" >> /etc/ppp/pap-secrets'
101```
102
1032. Create a files `pty1` and `pty2` and link them
104```sh
105cd $EMBASSY_ROOT/examples/std/
106socat -v -x PTY,link=pty1,rawer PTY,link=pty2,rawer
107```
108
1093. open a second terminal and start the PPP server:
110```sh
111cd $EMBASSY_ROOT/examples/std/
112sudo pppd $PWD/pty1 115200 192.168.7.1: ms-dns 8.8.4.4 ms-dns 8.8.8.8 nodetach debug local persist silent
113```
114
1154. Open a third terminal and run the example
116```sh
117cd $EMBASSY_ROOT/examples/std/
118RUST_LOG=trace cargo run --bin net_ppp -- --device pty2
119```
1205. Observe the output in the second and third terminal
1216. Open one last terminal to interact with `net_ppp` example through the PPP connection
122```sh
123# ping the net_ppp client
124ping 192.168.7.10
125# open an tcp connection
126nc 192.168.7.10 1234
127# Type anything and observe the output in the different terminals
23``` 128```
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs
index 59813d8cb..fd7b6c930 100644
--- a/examples/std/src/bin/net.rs
+++ b/examples/std/src/bin/net.rs
@@ -1,13 +1,15 @@
1use core::fmt::Write as _;
2
1use clap::Parser; 3use clap::Parser;
2use embassy_executor::{Executor, Spawner}; 4use embassy_executor::{Executor, Spawner};
3use embassy_net::tcp::TcpSocket; 5use embassy_net::tcp::TcpSocket;
4use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 6use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
5use embassy_net_tuntap::TunTapDevice; 7use embassy_net_tuntap::TunTapDevice;
6use embassy_time::Duration; 8use embassy_time::Duration;
7use embedded_io_async::Write; 9use embedded_io_async::Write;
8use heapless::Vec; 10use heapless::Vec;
9use log::*; 11use log::*;
10use rand_core::{OsRng, RngCore}; 12use rand_core::{OsRng, TryRngCore};
11use static_cell::StaticCell; 13use static_cell::StaticCell;
12 14
13#[derive(Parser)] 15#[derive(Parser)]
@@ -22,8 +24,8 @@ struct Opts {
22} 24}
23 25
24#[embassy_executor::task] 26#[embassy_executor::task]
25async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! { 27async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
26 stack.run().await 28 runner.run().await
27} 29}
28 30
29#[embassy_executor::task] 31#[embassy_executor::task]
@@ -46,21 +48,15 @@ async fn main_task(spawner: Spawner) {
46 48
47 // Generate random seed 49 // Generate random seed
48 let mut seed = [0; 8]; 50 let mut seed = [0; 8];
49 OsRng.fill_bytes(&mut seed); 51 OsRng.try_fill_bytes(&mut seed).unwrap();
50 let seed = u64::from_le_bytes(seed); 52 let seed = u64::from_le_bytes(seed);
51 53
52 // Init network stack 54 // Init network stack
53 static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
54 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); 55 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
55 let stack = &*STACK.init(Stack::new( 56 let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
56 device,
57 config,
58 RESOURCES.init(StackResources::<3>::new()),
59 seed,
60 ));
61 57
62 // Launch network task 58 // Launch network task
63 spawner.spawn(net_task(stack)).unwrap(); 59 spawner.spawn(net_task(runner).unwrap());
64 60
65 // Then we can use it! 61 // Then we can use it!
66 let mut rx_buffer = [0; 4096]; 62 let mut rx_buffer = [0; 4096];
@@ -77,8 +73,10 @@ async fn main_task(spawner: Spawner) {
77 return; 73 return;
78 } 74 }
79 info!("connected!"); 75 info!("connected!");
80 loop { 76 for i in 0.. {
81 let r = socket.write_all(b"Hello!\n").await; 77 let mut buf = heapless::String::<100>::new();
78 write!(buf, "Hello! ({})\r\n", i).unwrap();
79 let r = socket.write_all(buf.as_bytes()).await;
82 if let Err(e) = r { 80 if let Err(e) = r {
83 warn!("write error: {:?}", e); 81 warn!("write error: {:?}", e);
84 return; 82 return;
@@ -97,6 +95,6 @@ fn main() {
97 95
98 let executor = EXECUTOR.init(Executor::new()); 96 let executor = EXECUTOR.init(Executor::new());
99 executor.run(|spawner| { 97 executor.run(|spawner| {
100 spawner.spawn(main_task(spawner)).unwrap(); 98 spawner.spawn(main_task(spawner).unwrap());
101 }); 99 });
102} 100}
diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs
index 3b6a3de37..dff704b86 100644
--- a/examples/std/src/bin/net_dns.rs
+++ b/examples/std/src/bin/net_dns.rs
@@ -1,11 +1,11 @@
1use clap::Parser; 1use clap::Parser;
2use embassy_executor::{Executor, Spawner}; 2use embassy_executor::{Executor, Spawner};
3use embassy_net::dns::DnsQueryType; 3use embassy_net::dns::DnsQueryType;
4use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 4use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
5use embassy_net_tuntap::TunTapDevice; 5use embassy_net_tuntap::TunTapDevice;
6use heapless::Vec; 6use heapless::Vec;
7use log::*; 7use log::*;
8use rand_core::{OsRng, RngCore}; 8use rand_core::{OsRng, TryRngCore};
9use static_cell::StaticCell; 9use static_cell::StaticCell;
10 10
11#[derive(Parser)] 11#[derive(Parser)]
@@ -20,8 +20,8 @@ struct Opts {
20} 20}
21 21
22#[embassy_executor::task] 22#[embassy_executor::task]
23async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! { 23async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
24 stack.run().await 24 runner.run().await
25} 25}
26 26
27#[embassy_executor::task] 27#[embassy_executor::task]
@@ -45,21 +45,15 @@ async fn main_task(spawner: Spawner) {
45 45
46 // Generate random seed 46 // Generate random seed
47 let mut seed = [0; 8]; 47 let mut seed = [0; 8];
48 OsRng.fill_bytes(&mut seed); 48 OsRng.try_fill_bytes(&mut seed).unwrap();
49 let seed = u64::from_le_bytes(seed); 49 let seed = u64::from_le_bytes(seed);
50 50
51 // Init network stack 51 // Init network stack
52 static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
53 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); 52 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
54 let stack: &Stack<_> = &*STACK.init(Stack::new( 53 let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
55 device,
56 config,
57 RESOURCES.init(StackResources::<3>::new()),
58 seed,
59 ));
60 54
61 // Launch network task 55 // Launch network task
62 spawner.spawn(net_task(stack)).unwrap(); 56 spawner.spawn(net_task(runner).unwrap());
63 57
64 let host = "example.com"; 58 let host = "example.com";
65 info!("querying host {:?}...", host); 59 info!("querying host {:?}...", host);
@@ -84,6 +78,6 @@ fn main() {
84 78
85 let executor = EXECUTOR.init(Executor::new()); 79 let executor = EXECUTOR.init(Executor::new());
86 executor.run(|spawner| { 80 executor.run(|spawner| {
87 spawner.spawn(main_task(spawner)).unwrap(); 81 spawner.spawn(main_task(spawner).unwrap());
88 }); 82 });
89} 83}
diff --git a/examples/std/src/bin/net_ppp.rs b/examples/std/src/bin/net_ppp.rs
index 9ec0ea91f..82272c798 100644
--- a/examples/std/src/bin/net_ppp.rs
+++ b/examples/std/src/bin/net_ppp.rs
@@ -16,14 +16,14 @@ use async_io::Async;
16use clap::Parser; 16use clap::Parser;
17use embassy_executor::{Executor, Spawner}; 17use embassy_executor::{Executor, Spawner};
18use embassy_net::tcp::TcpSocket; 18use embassy_net::tcp::TcpSocket;
19use embassy_net::{Config, ConfigV4, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 19use embassy_net::{Config, ConfigV4, Ipv4Cidr, Stack, StackResources};
20use embassy_net_ppp::Runner; 20use embassy_net_ppp::Runner;
21use embedded_io_async::Write; 21use embedded_io_async::Write;
22use futures::io::BufReader; 22use futures::io::BufReader;
23use heapless::Vec; 23use heapless::Vec;
24use log::*; 24use log::*;
25use nix::sys::termios; 25use nix::sys::termios;
26use rand_core::{OsRng, RngCore}; 26use rand_core::{OsRng, TryRngCore};
27use static_cell::StaticCell; 27use static_cell::StaticCell;
28 28
29use crate::serial_port::SerialPort; 29use crate::serial_port::SerialPort;
@@ -37,19 +37,15 @@ struct Opts {
37} 37}
38 38
39#[embassy_executor::task] 39#[embassy_executor::task]
40async fn net_task(stack: &'static Stack<embassy_net_ppp::Device<'static>>) -> ! { 40async fn net_task(mut runner: embassy_net::Runner<'static, embassy_net_ppp::Device<'static>>) -> ! {
41 stack.run().await 41 runner.run().await
42} 42}
43 43
44#[embassy_executor::task] 44#[embassy_executor::task]
45async fn ppp_task( 45async fn ppp_task(stack: Stack<'static>, mut runner: Runner<'static>, port: SerialPort) -> ! {
46 stack: &'static Stack<embassy_net_ppp::Device<'static>>,
47 mut runner: Runner<'static>,
48 port: SerialPort,
49) -> ! {
50 let port = Async::new(port).unwrap(); 46 let port = Async::new(port).unwrap();
51 let port = BufReader::new(port); 47 let port = BufReader::new(port);
52 let port = adapter::FromFutures::new(port); 48 let port = embedded_io_adapters::futures_03::FromFutures::new(port);
53 49
54 let config = embassy_net_ppp::Config { 50 let config = embassy_net_ppp::Config {
55 username: b"myuser", 51 username: b"myuser",
@@ -64,10 +60,10 @@ async fn ppp_task(
64 }; 60 };
65 let mut dns_servers = Vec::new(); 61 let mut dns_servers = Vec::new();
66 for s in ipv4.dns_servers.iter().flatten() { 62 for s in ipv4.dns_servers.iter().flatten() {
67 let _ = dns_servers.push(Ipv4Address::from_bytes(&s.0)); 63 let _ = dns_servers.push(*s);
68 } 64 }
69 let config = ConfigV4::Static(embassy_net::StaticConfigV4 { 65 let config = ConfigV4::Static(embassy_net::StaticConfigV4 {
70 address: Ipv4Cidr::new(Ipv4Address::from_bytes(&addr.0), 0), 66 address: Ipv4Cidr::new(addr, 0),
71 gateway: None, 67 gateway: None,
72 dns_servers, 68 dns_servers,
73 }); 69 });
@@ -93,22 +89,21 @@ async fn main_task(spawner: Spawner) {
93 89
94 // Generate random seed 90 // Generate random seed
95 let mut seed = [0; 8]; 91 let mut seed = [0; 8];
96 OsRng.fill_bytes(&mut seed); 92 OsRng.try_fill_bytes(&mut seed).unwrap();
97 let seed = u64::from_le_bytes(seed); 93 let seed = u64::from_le_bytes(seed);
98 94
99 // Init network stack 95 // Init network stack
100 static STACK: StaticCell<Stack<embassy_net_ppp::Device<'static>>> = StaticCell::new();
101 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); 96 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
102 let stack = &*STACK.init(Stack::new( 97 let (stack, net_runner) = embassy_net::new(
103 device, 98 device,
104 Config::default(), // don't configure IP yet 99 Config::default(), // don't configure IP yet
105 RESOURCES.init(StackResources::<3>::new()), 100 RESOURCES.init(StackResources::new()),
106 seed, 101 seed,
107 )); 102 );
108 103
109 // Launch network task 104 // Launch network task
110 spawner.spawn(net_task(stack)).unwrap(); 105 spawner.spawn(net_task(net_runner).unwrap());
111 spawner.spawn(ppp_task(stack, runner, port)).unwrap(); 106 spawner.spawn(ppp_task(stack, runner, port).unwrap());
112 107
113 // Then we can use it! 108 // Then we can use it!
114 let mut rx_buffer = [0; 4096]; 109 let mut rx_buffer = [0; 4096];
@@ -165,56 +160,6 @@ fn main() {
165 160
166 let executor = EXECUTOR.init(Executor::new()); 161 let executor = EXECUTOR.init(Executor::new());
167 executor.run(|spawner| { 162 executor.run(|spawner| {
168 spawner.spawn(main_task(spawner)).unwrap(); 163 spawner.spawn(main_task(spawner).unwrap());
169 }); 164 });
170} 165}
171
172mod adapter {
173 use core::future::poll_fn;
174 use core::pin::Pin;
175
176 use futures::AsyncBufReadExt;
177
178 /// Adapter from `futures::io` traits.
179 #[derive(Clone)]
180 pub struct FromFutures<T: ?Sized> {
181 inner: T,
182 }
183
184 impl<T> FromFutures<T> {
185 /// Create a new adapter.
186 pub fn new(inner: T) -> Self {
187 Self { inner }
188 }
189 }
190
191 impl<T: ?Sized> embedded_io_async::ErrorType for FromFutures<T> {
192 type Error = std::io::Error;
193 }
194
195 impl<T: futures::io::AsyncRead + Unpin + ?Sized> embedded_io_async::Read for FromFutures<T> {
196 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
197 poll_fn(|cx| Pin::new(&mut self.inner).poll_read(cx, buf)).await
198 }
199 }
200
201 impl<T: futures::io::AsyncBufRead + Unpin + ?Sized> embedded_io_async::BufRead for FromFutures<T> {
202 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
203 self.inner.fill_buf().await
204 }
205
206 fn consume(&mut self, amt: usize) {
207 Pin::new(&mut self.inner).consume(amt)
208 }
209 }
210
211 impl<T: futures::io::AsyncWrite + Unpin + ?Sized> embedded_io_async::Write for FromFutures<T> {
212 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
213 poll_fn(|cx| Pin::new(&mut self.inner).poll_write(cx, buf)).await
214 }
215
216 async fn flush(&mut self) -> Result<(), Self::Error> {
217 poll_fn(|cx| Pin::new(&mut self.inner).poll_flush(cx)).await
218 }
219 }
220}
diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs
index bee91990d..c5c4da65f 100644
--- a/examples/std/src/bin/net_udp.rs
+++ b/examples/std/src/bin/net_udp.rs
@@ -1,11 +1,11 @@
1use clap::Parser; 1use clap::Parser;
2use embassy_executor::{Executor, Spawner}; 2use embassy_executor::{Executor, Spawner};
3use embassy_net::udp::{PacketMetadata, UdpSocket}; 3use embassy_net::udp::{PacketMetadata, UdpSocket};
4use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 4use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
5use embassy_net_tuntap::TunTapDevice; 5use embassy_net_tuntap::TunTapDevice;
6use heapless::Vec; 6use heapless::Vec;
7use log::*; 7use log::*;
8use rand_core::{OsRng, RngCore}; 8use rand_core::{OsRng, TryRngCore};
9use static_cell::StaticCell; 9use static_cell::StaticCell;
10 10
11#[derive(Parser)] 11#[derive(Parser)]
@@ -20,8 +20,8 @@ struct Opts {
20} 20}
21 21
22#[embassy_executor::task] 22#[embassy_executor::task]
23async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! { 23async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
24 stack.run().await 24 runner.run().await
25} 25}
26 26
27#[embassy_executor::task] 27#[embassy_executor::task]
@@ -44,21 +44,15 @@ async fn main_task(spawner: Spawner) {
44 44
45 // Generate random seed 45 // Generate random seed
46 let mut seed = [0; 8]; 46 let mut seed = [0; 8];
47 OsRng.fill_bytes(&mut seed); 47 OsRng.try_fill_bytes(&mut seed).unwrap();
48 let seed = u64::from_le_bytes(seed); 48 let seed = u64::from_le_bytes(seed);
49 49
50 // Init network stack 50 // Init network stack
51 static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
52 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); 51 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
53 let stack = &*STACK.init(Stack::new( 52 let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
54 device,
55 config,
56 RESOURCES.init(StackResources::<3>::new()),
57 seed,
58 ));
59 53
60 // Launch network task 54 // Launch network task
61 spawner.spawn(net_task(stack)).unwrap(); 55 spawner.spawn(net_task(runner).unwrap());
62 56
63 // Then we can use it! 57 // Then we can use it!
64 let mut rx_meta = [PacketMetadata::EMPTY; 16]; 58 let mut rx_meta = [PacketMetadata::EMPTY; 16];
@@ -92,6 +86,6 @@ fn main() {
92 86
93 let executor = EXECUTOR.init(Executor::new()); 87 let executor = EXECUTOR.init(Executor::new());
94 executor.run(|spawner| { 88 executor.run(|spawner| {
95 spawner.spawn(main_task(spawner)).unwrap(); 89 spawner.spawn(main_task(spawner).unwrap());
96 }); 90 });
97} 91}
diff --git a/examples/std/src/bin/serial.rs b/examples/std/src/bin/serial.rs
index 10c85511d..1ed9997c4 100644
--- a/examples/std/src/bin/serial.rs
+++ b/examples/std/src/bin/serial.rs
@@ -50,6 +50,6 @@ fn main() {
50 50
51 let executor = EXECUTOR.init(Executor::new()); 51 let executor = EXECUTOR.init(Executor::new());
52 executor.run(|spawner| { 52 executor.run(|spawner| {
53 spawner.spawn(run()).unwrap(); 53 spawner.spawn(run().unwrap());
54 }); 54 });
55} 55}
diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs
index e8b6eaa6c..77886f471 100644
--- a/examples/std/src/bin/tcp_accept.rs
+++ b/examples/std/src/bin/tcp_accept.rs
@@ -1,15 +1,13 @@
1use core::fmt::Write as _;
2
3use clap::Parser; 1use clap::Parser;
4use embassy_executor::{Executor, Spawner}; 2use embassy_executor::{Executor, Spawner};
5use embassy_net::tcp::TcpSocket; 3use embassy_net::tcp::TcpSocket;
6use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 4use embassy_net::{Config, Ipv4Address, Ipv4Cidr, StackResources};
7use embassy_net_tuntap::TunTapDevice; 5use embassy_net_tuntap::TunTapDevice;
8use embassy_time::{Duration, Timer}; 6use embassy_time::{Duration, Timer};
9use embedded_io_async::Write as _; 7use embedded_io_async::Write as _;
10use heapless::Vec; 8use heapless::Vec;
11use log::*; 9use log::*;
12use rand_core::{OsRng, RngCore}; 10use rand_core::{OsRng, TryRngCore};
13use static_cell::StaticCell; 11use static_cell::StaticCell;
14 12
15#[derive(Parser)] 13#[derive(Parser)]
@@ -24,18 +22,8 @@ struct Opts {
24} 22}
25 23
26#[embassy_executor::task] 24#[embassy_executor::task]
27async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! { 25async fn net_task(mut runner: embassy_net::Runner<'static, TunTapDevice>) -> ! {
28 stack.run().await 26 runner.run().await
29}
30
31#[derive(Default)]
32struct StrWrite(pub heapless::Vec<u8, 30>);
33
34impl core::fmt::Write for StrWrite {
35 fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> {
36 self.0.extend_from_slice(s.as_bytes()).unwrap();
37 Ok(())
38 }
39} 27}
40 28
41#[embassy_executor::task] 29#[embassy_executor::task]
@@ -58,21 +46,15 @@ async fn main_task(spawner: Spawner) {
58 46
59 // Generate random seed 47 // Generate random seed
60 let mut seed = [0; 8]; 48 let mut seed = [0; 8];
61 OsRng.fill_bytes(&mut seed); 49 OsRng.try_fill_bytes(&mut seed).unwrap();
62 let seed = u64::from_le_bytes(seed); 50 let seed = u64::from_le_bytes(seed);
63 51
64 // Init network stack 52 // Init network stack
65 static STACK: StaticCell<Stack<TunTapDevice>> = StaticCell::new();
66 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); 53 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
67 let stack = &*STACK.init(Stack::new( 54 let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed);
68 device,
69 config,
70 RESOURCES.init(StackResources::<3>::new()),
71 seed,
72 ));
73 55
74 // Launch network task 56 // Launch network task
75 spawner.spawn(net_task(stack)).unwrap(); 57 spawner.spawn(net_task(runner).unwrap());
76 58
77 // Then we can use it! 59 // Then we can use it!
78 let mut rx_buffer = [0; 4096]; 60 let mut rx_buffer = [0; 4096];
@@ -91,9 +73,8 @@ async fn main_task(spawner: Spawner) {
91 73
92 // Write some quick output 74 // Write some quick output
93 for i in 1..=5 { 75 for i in 1..=5 {
94 let mut w = StrWrite::default(); 76 let s = format!("{}! ", i);
95 write!(w, "{}! ", i).unwrap(); 77 let r = socket.write_all(s.as_bytes()).await;
96 let r = socket.write_all(&w.0).await;
97 if let Err(e) = r { 78 if let Err(e) = r {
98 warn!("write error: {:?}", e); 79 warn!("write error: {:?}", e);
99 return; 80 return;
@@ -120,6 +101,6 @@ fn main() {
120 101
121 let executor = EXECUTOR.init(Executor::new()); 102 let executor = EXECUTOR.init(Executor::new());
122 executor.run(|spawner| { 103 executor.run(|spawner| {
123 spawner.spawn(main_task(spawner)).unwrap(); 104 spawner.spawn(main_task(spawner).unwrap());
124 }); 105 });
125} 106}
diff --git a/examples/std/src/bin/tick.rs b/examples/std/src/bin/tick.rs
index f23cf3549..16b82c82b 100644
--- a/examples/std/src/bin/tick.rs
+++ b/examples/std/src/bin/tick.rs
@@ -17,5 +17,5 @@ async fn main(spawner: Spawner) {
17 .format_timestamp_nanos() 17 .format_timestamp_nanos()
18 .init(); 18 .init();
19 19
20 spawner.spawn(run()).unwrap(); 20 spawner.spawn(run().unwrap());
21} 21}
diff --git a/examples/std/tap.sh b/examples/std/tap.sh
new file mode 100644
index 000000000..fb89d2381
--- /dev/null
+++ b/examples/std/tap.sh
@@ -0,0 +1,7 @@
1ip tuntap add name tap99 mode tap user $SUDO_USER
2ip link set tap99 up
3ip addr add 192.168.69.100/24 dev tap99
4ip -6 addr add fe80::100/64 dev tap99
5ip -6 addr add fdaa::100/64 dev tap99
6ip -6 route add fe80::/64 dev tap99
7ip -6 route add fdaa::/64 dev tap99