aboutsummaryrefslogtreecommitdiff
path: root/examples/std/src
diff options
context:
space:
mode:
authorTyler <[email protected]>2023-08-24 17:38:04 -0600
committerGitHub <[email protected]>2023-08-24 17:38:04 -0600
commitf033089625b4883f9b8811f5c291292529f66767 (patch)
tree6ecb235b98bb67c9b064fca2b47e035fbeeb234e /examples/std/src
parent6d8a5c6c20953c998df6ddd26906abe520df946d (diff)
parent2a6b743b9e8dbeef6b02320b2485f3f1efe4a337 (diff)
Merge pull request #3 from embassy-rs/main
Update to embassy head
Diffstat (limited to 'examples/std/src')
-rw-r--r--examples/std/src/bin/net.rs7
-rw-r--r--examples/std/src/bin/net_dns.rs5
-rw-r--r--examples/std/src/bin/net_udp.rs5
-rw-r--r--examples/std/src/bin/serial.rs4
-rw-r--r--examples/std/src/bin/tcp_accept.rs7
-rw-r--r--examples/std/src/tuntap.rs224
6 files changed, 8 insertions, 244 deletions
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs
index 3aadb029d..8d8345057 100644
--- a/examples/std/src/bin/net.rs
+++ b/examples/std/src/bin/net.rs
@@ -6,17 +6,14 @@ use clap::Parser;
6use embassy_executor::{Executor, Spawner}; 6use embassy_executor::{Executor, Spawner};
7use embassy_net::tcp::TcpSocket; 7use embassy_net::tcp::TcpSocket;
8use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 8use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
9use embassy_net_tuntap::TunTapDevice;
9use embassy_time::Duration; 10use embassy_time::Duration;
10use embedded_io::asynch::Write; 11use embedded_io_async::Write;
11use heapless::Vec; 12use heapless::Vec;
12use log::*; 13use log::*;
13use rand_core::{OsRng, RngCore}; 14use rand_core::{OsRng, RngCore};
14use static_cell::{make_static, StaticCell}; 15use static_cell::{make_static, StaticCell};
15 16
16#[path = "../tuntap.rs"]
17mod tuntap;
18
19use crate::tuntap::TunTapDevice;
20#[derive(Parser)] 17#[derive(Parser)]
21#[clap(version = "1.0")] 18#[clap(version = "1.0")]
22struct Opts { 19struct Opts {
diff --git a/examples/std/src/bin/net_dns.rs b/examples/std/src/bin/net_dns.rs
index 65b5a2cd9..6c19874d5 100644
--- a/examples/std/src/bin/net_dns.rs
+++ b/examples/std/src/bin/net_dns.rs
@@ -6,15 +6,12 @@ use clap::Parser;
6use embassy_executor::{Executor, Spawner}; 6use embassy_executor::{Executor, Spawner};
7use embassy_net::dns::DnsQueryType; 7use embassy_net::dns::DnsQueryType;
8use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 8use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
9use embassy_net_tuntap::TunTapDevice;
9use heapless::Vec; 10use heapless::Vec;
10use log::*; 11use log::*;
11use rand_core::{OsRng, RngCore}; 12use rand_core::{OsRng, RngCore};
12use static_cell::{make_static, StaticCell}; 13use static_cell::{make_static, StaticCell};
13 14
14#[path = "../tuntap.rs"]
15mod tuntap;
16
17use crate::tuntap::TunTapDevice;
18#[derive(Parser)] 15#[derive(Parser)]
19#[clap(version = "1.0")] 16#[clap(version = "1.0")]
20struct Opts { 17struct Opts {
diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs
index 3fc46156c..98dcc9925 100644
--- a/examples/std/src/bin/net_udp.rs
+++ b/examples/std/src/bin/net_udp.rs
@@ -4,15 +4,12 @@ use clap::Parser;
4use embassy_executor::{Executor, Spawner}; 4use embassy_executor::{Executor, Spawner};
5use embassy_net::udp::{PacketMetadata, UdpSocket}; 5use embassy_net::udp::{PacketMetadata, UdpSocket};
6use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 6use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
7use embassy_net_tuntap::TunTapDevice;
7use heapless::Vec; 8use heapless::Vec;
8use log::*; 9use log::*;
9use rand_core::{OsRng, RngCore}; 10use rand_core::{OsRng, RngCore};
10use static_cell::{make_static, StaticCell}; 11use static_cell::{make_static, StaticCell};
11 12
12#[path = "../tuntap.rs"]
13mod tuntap;
14
15use crate::tuntap::TunTapDevice;
16#[derive(Parser)] 13#[derive(Parser)]
17#[clap(version = "1.0")] 14#[clap(version = "1.0")]
18struct Opts { 15struct Opts {
diff --git a/examples/std/src/bin/serial.rs b/examples/std/src/bin/serial.rs
index 85ee54f70..0b289c74d 100644
--- a/examples/std/src/bin/serial.rs
+++ b/examples/std/src/bin/serial.rs
@@ -5,7 +5,7 @@ mod serial_port;
5 5
6use async_io::Async; 6use async_io::Async;
7use embassy_executor::Executor; 7use embassy_executor::Executor;
8use embedded_io::asynch::Read; 8use embedded_io_async::Read;
9use log::*; 9use log::*;
10use nix::sys::termios; 10use nix::sys::termios;
11use static_cell::StaticCell; 11use static_cell::StaticCell;
@@ -29,7 +29,7 @@ async fn run() {
29 // 29 //
30 // This is not really needed, you could write the code below using futures::io directly. 30 // This is not really needed, you could write the code below using futures::io directly.
31 // It's useful if you want to have portable code across embedded and std. 31 // It's useful if you want to have portable code across embedded and std.
32 let mut port = embedded_io::adapters::FromFutures::new(port); 32 let mut port = embedded_io_adapters::futures_03::FromFutures::new(port);
33 33
34 info!("Serial opened!"); 34 info!("Serial opened!");
35 35
diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs
index df09986ac..199e4c9ec 100644
--- a/examples/std/src/bin/tcp_accept.rs
+++ b/examples/std/src/bin/tcp_accept.rs
@@ -7,17 +7,14 @@ use clap::Parser;
7use embassy_executor::{Executor, Spawner}; 7use embassy_executor::{Executor, Spawner};
8use embassy_net::tcp::TcpSocket; 8use embassy_net::tcp::TcpSocket;
9use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; 9use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
10use embassy_net_tuntap::TunTapDevice;
10use embassy_time::{Duration, Timer}; 11use embassy_time::{Duration, Timer};
11use embedded_io::asynch::Write as _; 12use embedded_io_async::Write as _;
12use heapless::Vec; 13use heapless::Vec;
13use log::*; 14use log::*;
14use rand_core::{OsRng, RngCore}; 15use rand_core::{OsRng, RngCore};
15use static_cell::{make_static, StaticCell}; 16use static_cell::{make_static, StaticCell};
16 17
17#[path = "../tuntap.rs"]
18mod tuntap;
19
20use crate::tuntap::TunTapDevice;
21#[derive(Parser)] 18#[derive(Parser)]
22#[clap(version = "1.0")] 19#[clap(version = "1.0")]
23struct Opts { 20struct Opts {
diff --git a/examples/std/src/tuntap.rs b/examples/std/src/tuntap.rs
deleted file mode 100644
index d918a2e62..000000000
--- a/examples/std/src/tuntap.rs
+++ /dev/null
@@ -1,224 +0,0 @@
1use std::io;
2use std::io::{Read, Write};
3use std::os::unix::io::{AsRawFd, RawFd};
4use std::task::Context;
5
6use async_io::Async;
7use embassy_net_driver::{self, Capabilities, Driver, LinkState};
8use log::*;
9
10pub const SIOCGIFMTU: libc::c_ulong = 0x8921;
11pub const _SIOCGIFINDEX: libc::c_ulong = 0x8933;
12pub const _ETH_P_ALL: libc::c_short = 0x0003;
13pub const TUNSETIFF: libc::c_ulong = 0x400454CA;
14pub const _IFF_TUN: libc::c_int = 0x0001;
15pub const IFF_TAP: libc::c_int = 0x0002;
16pub const IFF_NO_PI: libc::c_int = 0x1000;
17
18const ETHERNET_HEADER_LEN: usize = 14;
19
20#[repr(C)]
21#[derive(Debug)]
22struct ifreq {
23 ifr_name: [libc::c_char; libc::IF_NAMESIZE],
24 ifr_data: libc::c_int, /* ifr_ifindex or ifr_mtu */
25}
26
27fn ifreq_for(name: &str) -> ifreq {
28 let mut ifreq = ifreq {
29 ifr_name: [0; libc::IF_NAMESIZE],
30 ifr_data: 0,
31 };
32 for (i, byte) in name.as_bytes().iter().enumerate() {
33 ifreq.ifr_name[i] = *byte as libc::c_char
34 }
35 ifreq
36}
37
38fn ifreq_ioctl(lower: libc::c_int, ifreq: &mut ifreq, cmd: libc::c_ulong) -> io::Result<libc::c_int> {
39 unsafe {
40 let res = libc::ioctl(lower, cmd as _, ifreq as *mut ifreq);
41 if res == -1 {
42 return Err(io::Error::last_os_error());
43 }
44 }
45
46 Ok(ifreq.ifr_data)
47}
48
49#[derive(Debug)]
50pub struct TunTap {
51 fd: libc::c_int,
52 mtu: usize,
53}
54
55impl AsRawFd for TunTap {
56 fn as_raw_fd(&self) -> RawFd {
57 self.fd
58 }
59}
60
61impl TunTap {
62 pub fn new(name: &str) -> io::Result<TunTap> {
63 unsafe {
64 let fd = libc::open(
65 "/dev/net/tun\0".as_ptr() as *const libc::c_char,
66 libc::O_RDWR | libc::O_NONBLOCK,
67 );
68 if fd == -1 {
69 return Err(io::Error::last_os_error());
70 }
71
72 let mut ifreq = ifreq_for(name);
73 ifreq.ifr_data = IFF_TAP | IFF_NO_PI;
74 ifreq_ioctl(fd, &mut ifreq, TUNSETIFF)?;
75
76 let socket = libc::socket(libc::AF_INET, libc::SOCK_DGRAM, libc::IPPROTO_IP);
77 if socket == -1 {
78 return Err(io::Error::last_os_error());
79 }
80
81 let ip_mtu = ifreq_ioctl(socket, &mut ifreq, SIOCGIFMTU);
82 libc::close(socket);
83 let ip_mtu = ip_mtu? as usize;
84
85 // SIOCGIFMTU returns the IP MTU (typically 1500 bytes.)
86 // smoltcp counts the entire Ethernet packet in the MTU, so add the Ethernet header size to it.
87 let mtu = ip_mtu + ETHERNET_HEADER_LEN;
88
89 Ok(TunTap { fd, mtu })
90 }
91 }
92}
93
94impl Drop for TunTap {
95 fn drop(&mut self) {
96 unsafe {
97 libc::close(self.fd);
98 }
99 }
100}
101
102impl io::Read for TunTap {
103 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
104 let len = unsafe { libc::read(self.fd, buf.as_mut_ptr() as *mut libc::c_void, buf.len()) };
105 if len == -1 {
106 Err(io::Error::last_os_error())
107 } else {
108 Ok(len as usize)
109 }
110 }
111}
112
113impl io::Write for TunTap {
114 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
115 let len = unsafe { libc::write(self.fd, buf.as_ptr() as *mut libc::c_void, buf.len()) };
116 if len == -1 {
117 Err(io::Error::last_os_error())
118 } else {
119 Ok(len as usize)
120 }
121 }
122
123 fn flush(&mut self) -> io::Result<()> {
124 Ok(())
125 }
126}
127
128pub struct TunTapDevice {
129 device: Async<TunTap>,
130}
131
132impl TunTapDevice {
133 pub fn new(name: &str) -> io::Result<TunTapDevice> {
134 Ok(Self {
135 device: Async::new(TunTap::new(name)?)?,
136 })
137 }
138}
139
140impl Driver for TunTapDevice {
141 type RxToken<'a> = RxToken where Self: 'a;
142 type TxToken<'a> = TxToken<'a> where Self: 'a;
143
144 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
145 let mut buf = vec![0; self.device.get_ref().mtu];
146 loop {
147 match self.device.get_mut().read(&mut buf) {
148 Ok(n) => {
149 buf.truncate(n);
150 return Some((
151 RxToken { buffer: buf },
152 TxToken {
153 device: &mut self.device,
154 },
155 ));
156 }
157 Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
158 if !self.device.poll_readable(cx).is_ready() {
159 return None;
160 }
161 }
162 Err(e) => panic!("read error: {:?}", e),
163 }
164 }
165 }
166
167 fn transmit(&mut self, _cx: &mut Context) -> Option<Self::TxToken<'_>> {
168 Some(TxToken {
169 device: &mut self.device,
170 })
171 }
172
173 fn capabilities(&self) -> Capabilities {
174 let mut caps = Capabilities::default();
175 caps.max_transmission_unit = self.device.get_ref().mtu;
176 caps
177 }
178
179 fn link_state(&mut self, _cx: &mut Context) -> LinkState {
180 LinkState::Up
181 }
182
183 fn ethernet_address(&self) -> [u8; 6] {
184 [0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
185 }
186}
187
188#[doc(hidden)]
189pub struct RxToken {
190 buffer: Vec<u8>,
191}
192
193impl embassy_net_driver::RxToken for RxToken {
194 fn consume<R, F>(mut self, f: F) -> R
195 where
196 F: FnOnce(&mut [u8]) -> R,
197 {
198 f(&mut self.buffer)
199 }
200}
201
202#[doc(hidden)]
203pub struct TxToken<'a> {
204 device: &'a mut Async<TunTap>,
205}
206
207impl<'a> embassy_net_driver::TxToken for TxToken<'a> {
208 fn consume<R, F>(self, len: usize, f: F) -> R
209 where
210 F: FnOnce(&mut [u8]) -> R,
211 {
212 let mut buffer = vec![0; len];
213 let result = f(&mut buffer);
214
215 // todo handle WouldBlock with async
216 match self.device.get_mut().write(&buffer) {
217 Ok(_) => {}
218 Err(e) if e.kind() == io::ErrorKind::WouldBlock => info!("transmit WouldBlock"),
219 Err(e) => panic!("transmit error: {:?}", e),
220 }
221
222 result
223 }
224}