diff options
| author | Artur Kowalski <[email protected]> | 2022-08-10 19:38:34 +0200 |
|---|---|---|
| committer | Artur Kowalski <[email protected]> | 2022-08-10 20:13:10 +0200 |
| commit | 865a91976c5b6b5c45b37e0286e7c328e8404dde (patch) | |
| tree | 7187bdb4f78abc30b32274e44dfcaffe6024ab3f /examples/std/src | |
| parent | d5ab0d3ebb119c7ffd95da4b67325f75cae05b7e (diff) | |
Add UDP example app
Diffstat (limited to 'examples/std/src')
| -rw-r--r-- | examples/std/src/bin/net_udp.rs | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs new file mode 100644 index 000000000..7fe36e233 --- /dev/null +++ b/examples/std/src/bin/net_udp.rs | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | #![feature(type_alias_impl_trait)] | ||
| 2 | |||
| 3 | use clap::Parser; | ||
| 4 | use embassy_executor::executor::{Executor, Spawner}; | ||
| 5 | use embassy_net::udp::UdpSocket; | ||
| 6 | use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources}; | ||
| 7 | use embassy_util::Forever; | ||
| 8 | use heapless::Vec; | ||
| 9 | use log::*; | ||
| 10 | use rand_core::{OsRng, RngCore}; | ||
| 11 | |||
| 12 | #[path = "../tuntap.rs"] | ||
| 13 | mod tuntap; | ||
| 14 | |||
| 15 | use crate::tuntap::TunTapDevice; | ||
| 16 | |||
| 17 | macro_rules! forever { | ||
| 18 | ($val:expr) => {{ | ||
| 19 | type T = impl Sized; | ||
| 20 | static FOREVER: Forever<T> = Forever::new(); | ||
| 21 | FOREVER.put_with(move || $val) | ||
| 22 | }}; | ||
| 23 | } | ||
| 24 | |||
| 25 | #[derive(Parser)] | ||
| 26 | #[clap(version = "1.0")] | ||
| 27 | struct Opts { | ||
| 28 | /// TAP device name | ||
| 29 | #[clap(long, default_value = "tap0")] | ||
| 30 | tap: String, | ||
| 31 | /// use a static IP instead of DHCP | ||
| 32 | #[clap(long)] | ||
| 33 | static_ip: bool, | ||
| 34 | } | ||
| 35 | |||
| 36 | #[embassy_executor::task] | ||
| 37 | async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! { | ||
| 38 | stack.run().await | ||
| 39 | } | ||
| 40 | |||
| 41 | #[embassy_executor::task] | ||
| 42 | async fn main_task(spawner: Spawner) { | ||
| 43 | let opts: Opts = Opts::parse(); | ||
| 44 | |||
| 45 | // Init network device | ||
| 46 | let device = TunTapDevice::new(&opts.tap).unwrap(); | ||
| 47 | |||
| 48 | // Choose between dhcp or static ip | ||
| 49 | let config = if opts.static_ip { | ||
| 50 | ConfigStrategy::Static(embassy_net::Config { | ||
| 51 | address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), | ||
| 52 | dns_servers: Vec::new(), | ||
| 53 | gateway: Some(Ipv4Address::new(192, 168, 69, 1)), | ||
| 54 | }) | ||
| 55 | } else { | ||
| 56 | ConfigStrategy::Dhcp | ||
| 57 | }; | ||
| 58 | |||
| 59 | // Generate random seed | ||
| 60 | let mut seed = [0; 8]; | ||
| 61 | OsRng.fill_bytes(&mut seed); | ||
| 62 | let seed = u64::from_le_bytes(seed); | ||
| 63 | |||
| 64 | // Init network stack | ||
| 65 | let stack = &*forever!(Stack::new( | ||
| 66 | device, | ||
| 67 | config, | ||
| 68 | forever!(StackResources::<1, 2, 8>::new()), | ||
| 69 | seed | ||
| 70 | )); | ||
| 71 | |||
| 72 | // Launch network task | ||
| 73 | spawner.spawn(net_task(stack)).unwrap(); | ||
| 74 | |||
| 75 | // Then we can use it! | ||
| 76 | let mut rx_meta = [PacketMetadata::EMPTY; 16]; | ||
| 77 | let mut rx_buffer = [0; 4096]; | ||
| 78 | let mut tx_meta = [PacketMetadata::EMPTY; 16]; | ||
| 79 | let mut tx_buffer = [0; 4096]; | ||
| 80 | let mut buf = [0; 4096]; | ||
| 81 | |||
| 82 | let mut socket = UdpSocket::new(stack, &mut rx_meta, &mut rx_buffer, &mut tx_meta, &mut tx_buffer); | ||
| 83 | socket.bind(9400).unwrap(); | ||
| 84 | |||
| 85 | loop { | ||
| 86 | let (n, ep) = socket.recv_from(&mut buf).await.unwrap(); | ||
| 87 | if let Ok(s) = core::str::from_utf8(&buf[..n]) { | ||
| 88 | info!("ECHO (to {}): {}", ep, s); | ||
| 89 | } else { | ||
| 90 | info!("ECHO (to {}): bytearray len {}", ep, n); | ||
| 91 | } | ||
| 92 | socket.send_to(&buf[..n], ep).await.unwrap(); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | static EXECUTOR: Forever<Executor> = Forever::new(); | ||
| 97 | |||
| 98 | fn main() { | ||
| 99 | env_logger::builder() | ||
| 100 | .filter_level(log::LevelFilter::Debug) | ||
| 101 | .filter_module("async_io", log::LevelFilter::Info) | ||
| 102 | .format_timestamp_nanos() | ||
| 103 | .init(); | ||
| 104 | |||
| 105 | let executor = EXECUTOR.put(Executor::new()); | ||
| 106 | executor.run(|spawner| { | ||
| 107 | spawner.spawn(main_task(spawner)).unwrap(); | ||
| 108 | }); | ||
| 109 | } | ||
