aboutsummaryrefslogtreecommitdiff
path: root/embassy-net-examples/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-04-07 19:06:45 +0200
committerDario Nieuwenhuis <[email protected]>2021-04-07 19:06:45 +0200
commit9c5a8b945a743e75d586fdc2ef857d7c2a038e7d (patch)
treec7e4c88840281b3b54fbda466c717a83094f8121 /embassy-net-examples/src
parent9bee576fd241f019c363919b0c29551c6b8ee4b2 (diff)
Update to latest embassy, atomic-pool, smoltcp
Diffstat (limited to 'embassy-net-examples/src')
-rw-r--r--embassy-net-examples/src/main.rs36
-rw-r--r--embassy-net-examples/src/tuntap.rs35
2 files changed, 55 insertions, 16 deletions
diff --git a/embassy-net-examples/src/main.rs b/embassy-net-examples/src/main.rs
index dba1415b7..c157ea34e 100644
--- a/embassy-net-examples/src/main.rs
+++ b/embassy-net-examples/src/main.rs
@@ -1,6 +1,10 @@
1#![feature(type_alias_impl_trait)] 1#![feature(type_alias_impl_trait)]
2#![feature(min_type_alias_impl_trait)]
3#![feature(impl_trait_in_bindings)]
4#![allow(incomplete_features)]
2 5
3use embassy::executor::{task, Spawner}; 6use clap::{AppSettings, Clap};
7use embassy::executor::Spawner;
4use embassy::io::AsyncWriteExt; 8use embassy::io::AsyncWriteExt;
5use embassy::util::Forever; 9use embassy::util::Forever;
6use embassy_net::*; 10use embassy_net::*;
@@ -13,25 +17,39 @@ mod tuntap;
13use crate::tuntap::TunTapDevice; 17use crate::tuntap::TunTapDevice;
14 18
15static DEVICE: Forever<TunTapDevice> = Forever::new(); 19static DEVICE: Forever<TunTapDevice> = Forever::new();
16static CONFIG: Forever<StaticConfigurator> = Forever::new(); 20static CONFIG: Forever<DhcpConfigurator> = Forever::new();
17 21
18#[task] 22#[derive(Clap)]
23#[clap(version = "1.0")]
24#[clap(setting = AppSettings::ColoredHelp)]
25struct Opts {
26 /// TAP device name
27 #[clap(long, default_value = "tap0")]
28 tap: String,
29}
30
31#[embassy::task]
19async fn net_task() { 32async fn net_task() {
20 embassy_net::run().await 33 embassy_net::run().await
21} 34}
22 35
23#[task] 36#[embassy::task]
24async fn main_task(spawner: Spawner) { 37async fn main_task(spawner: Spawner) {
38 let opts: Opts = Opts::parse();
39
25 // Init network device 40 // Init network device
26 let device = TunTapDevice::new("tap0").unwrap(); 41 let device = TunTapDevice::new(&opts.tap).unwrap();
27 42
28 // Static IP configuration 43 // Static IP configuration
29 let config = StaticConfigurator::new(UpConfig { 44 let config = StaticConfigurator::new(Config {
30 address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 1), 24), 45 address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24),
31 dns_servers: Vec::new(), 46 dns_servers: Vec::new(),
32 gateway: Ipv4Address::new(192, 168, 69, 100), 47 gateway: Some(Ipv4Address::new(192, 168, 69, 1)),
33 }); 48 });
34 49
50 // DHCP configruation
51 let config = DhcpConfigurator::new();
52
35 // Init network stack 53 // Init network stack
36 embassy_net::init(DEVICE.put(device), CONFIG.put(config)); 54 embassy_net::init(DEVICE.put(device), CONFIG.put(config));
37 55
@@ -45,7 +63,7 @@ async fn main_task(spawner: Spawner) {
45 63
46 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); 64 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
47 65
48 let remote_endpoint = (Ipv4Address::new(192, 168, 69, 100), 8000); 66 let remote_endpoint = (Ipv4Address::new(192, 168, 69, 74), 8000);
49 info!("connecting to {:?}...", remote_endpoint); 67 info!("connecting to {:?}...", remote_endpoint);
50 let r = socket.connect(remote_endpoint).await; 68 let r = socket.connect(remote_endpoint).await;
51 if let Err(e) = r { 69 if let Err(e) = r {
diff --git a/embassy-net-examples/src/tuntap.rs b/embassy-net-examples/src/tuntap.rs
index b2117e81b..dd453deb3 100644
--- a/embassy-net-examples/src/tuntap.rs
+++ b/embassy-net-examples/src/tuntap.rs
@@ -1,5 +1,4 @@
1use async_io::Async; 1use async_io::Async;
2use embassy::util::WakerRegistration;
3use libc; 2use libc;
4use log::*; 3use log::*;
5use smoltcp::wire::EthernetFrame; 4use smoltcp::wire::EthernetFrame;
@@ -130,20 +129,21 @@ impl io::Write for TunTap {
130 129
131pub struct TunTapDevice { 130pub struct TunTapDevice {
132 device: Async<TunTap>, 131 device: Async<TunTap>,
133 waker: WakerRegistration, 132 waker: Option<Waker>,
134} 133}
135 134
136impl TunTapDevice { 135impl TunTapDevice {
137 pub fn new(name: &str) -> io::Result<TunTapDevice> { 136 pub fn new(name: &str) -> io::Result<TunTapDevice> {
138 Ok(Self { 137 Ok(Self {
139 device: Async::new(TunTap::new(name)?)?, 138 device: Async::new(TunTap::new(name)?)?,
140 waker: WakerRegistration::new(), 139 waker: None,
141 }) 140 })
142 } 141 }
143} 142}
144 143
145use core::task::Waker; 144use core::task::Waker;
146use embassy_net::{DeviceCapabilities, LinkState, Packet, PacketBox, PacketBuf}; 145use embassy_net::{DeviceCapabilities, LinkState, Packet, PacketBox, PacketBoxExt, PacketBuf};
146use std::task::Context;
147 147
148impl crate::Device for TunTapDevice { 148impl crate::Device for TunTapDevice {
149 fn is_transmit_ready(&mut self) -> bool { 149 fn is_transmit_ready(&mut self) -> bool {
@@ -169,7 +169,8 @@ impl crate::Device for TunTapDevice {
169 return Some(pkt.slice(0..n)); 169 return Some(pkt.slice(0..n));
170 } 170 }
171 Err(e) if e.kind() == io::ErrorKind::WouldBlock => { 171 Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
172 let ready = if let Some(mut cx) = self.waker.context() { 172 let ready = if let Some(w) = self.waker.as_ref() {
173 let mut cx = Context::from_waker(w);
173 let ready = self.device.poll_readable(&mut cx).is_ready(); 174 let ready = self.device.poll_readable(&mut cx).is_ready();
174 ready 175 ready
175 } else { 176 } else {
@@ -184,8 +185,28 @@ impl crate::Device for TunTapDevice {
184 } 185 }
185 } 186 }
186 187
187 fn register_waker(&mut self, waker: &Waker) { 188 fn register_waker(&mut self, w: &Waker) {
188 self.waker.register(waker) 189 match self.waker {
190 // Optimization: If both the old and new Wakers wake the same task, we can simply
191 // keep the old waker, skipping the clone. (In most executor implementations,
192 // cloning a waker is somewhat expensive, comparable to cloning an Arc).
193 Some(ref w2) if (w2.will_wake(w)) => {}
194 _ => {
195 // clone the new waker and store it
196 if let Some(old_waker) = core::mem::replace(&mut self.waker, Some(w.clone())) {
197 // We had a waker registered for another task. Wake it, so the other task can
198 // reregister itself if it's still interested.
199 //
200 // If two tasks are waiting on the same thing concurrently, this will cause them
201 // to wake each other in a loop fighting over this WakerRegistration. This wastes
202 // CPU but things will still work.
203 //
204 // If the user wants to have two tasks waiting on the same thing they should use
205 // a more appropriate primitive that can store multiple wakers.
206 old_waker.wake()
207 }
208 }
209 }
189 } 210 }
190 211
191 fn capabilities(&mut self) -> DeviceCapabilities { 212 fn capabilities(&mut self) -> DeviceCapabilities {