aboutsummaryrefslogtreecommitdiff
path: root/examples/std/src/bin/tcp_accept.rs
diff options
context:
space:
mode:
authorQuentin Smith <[email protected]>2023-07-17 21:31:43 -0400
committerQuentin Smith <[email protected]>2023-07-17 21:31:43 -0400
commit6f02403184eb7fb7990fb88fc9df9c4328a690a3 (patch)
tree748f510e190bb2724750507a6e69ed1a8e08cb20 /examples/std/src/bin/tcp_accept.rs
parentd896f80405aa8963877049ed999e4aba25d6e2bb (diff)
parent6b5df4523aa1c4902f02e803450ae4b418e0e3ca (diff)
Merge remote-tracking branch 'origin/main' into nrf-pdm
Diffstat (limited to 'examples/std/src/bin/tcp_accept.rs')
-rw-r--r--examples/std/src/bin/tcp_accept.rs129
1 files changed, 129 insertions, 0 deletions
diff --git a/examples/std/src/bin/tcp_accept.rs b/examples/std/src/bin/tcp_accept.rs
new file mode 100644
index 000000000..df09986ac
--- /dev/null
+++ b/examples/std/src/bin/tcp_accept.rs
@@ -0,0 +1,129 @@
1#![feature(type_alias_impl_trait)]
2
3use core::fmt::Write as _;
4use std::default::Default;
5
6use clap::Parser;
7use embassy_executor::{Executor, Spawner};
8use embassy_net::tcp::TcpSocket;
9use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources};
10use embassy_time::{Duration, Timer};
11use embedded_io::asynch::Write as _;
12use heapless::Vec;
13use log::*;
14use rand_core::{OsRng, RngCore};
15use static_cell::{make_static, StaticCell};
16
17#[path = "../tuntap.rs"]
18mod tuntap;
19
20use crate::tuntap::TunTapDevice;
21#[derive(Parser)]
22#[clap(version = "1.0")]
23struct Opts {
24 /// TAP device name
25 #[clap(long, default_value = "tap0")]
26 tap: String,
27 /// use a static IP instead of DHCP
28 #[clap(long)]
29 static_ip: bool,
30}
31
32#[embassy_executor::task]
33async fn net_task(stack: &'static Stack<TunTapDevice>) -> ! {
34 stack.run().await
35}
36
37#[derive(Default)]
38struct StrWrite(pub heapless::Vec<u8, 30>);
39
40impl core::fmt::Write for StrWrite {
41 fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> {
42 self.0.extend_from_slice(s.as_bytes()).unwrap();
43 Ok(())
44 }
45}
46
47#[embassy_executor::task]
48async fn main_task(spawner: Spawner) {
49 let opts: Opts = Opts::parse();
50
51 // Init network device
52 let device = TunTapDevice::new(&opts.tap).unwrap();
53
54 // Choose between dhcp or static ip
55 let config = if opts.static_ip {
56 Config::ipv4_static(embassy_net::StaticConfigV4 {
57 address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24),
58 dns_servers: Vec::new(),
59 gateway: Some(Ipv4Address::new(192, 168, 69, 1)),
60 })
61 } else {
62 Config::dhcpv4(Default::default())
63 };
64
65 // Generate random seed
66 let mut seed = [0; 8];
67 OsRng.fill_bytes(&mut seed);
68 let seed = u64::from_le_bytes(seed);
69
70 // Init network stack
71 let stack = &*make_static!(Stack::new(
72 device,
73 config,
74 make_static!(StackResources::<3>::new()),
75 seed
76 ));
77
78 // Launch network task
79 spawner.spawn(net_task(stack)).unwrap();
80
81 // Then we can use it!
82 let mut rx_buffer = [0; 4096];
83 let mut tx_buffer = [0; 4096];
84
85 loop {
86 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
87 socket.set_timeout(Some(Duration::from_secs(10)));
88 info!("Listening on TCP:9999...");
89 if let Err(_) = socket.accept(9999).await {
90 warn!("accept error");
91 continue;
92 }
93
94 info!("Accepted a connection");
95
96 // Write some quick output
97 for i in 1..=5 {
98 let mut w = StrWrite::default();
99 write!(w, "{}! ", i).unwrap();
100 let r = socket.write_all(&w.0).await;
101 if let Err(e) = r {
102 warn!("write error: {:?}", e);
103 return;
104 }
105
106 Timer::after(Duration::from_millis(500)).await;
107 }
108 info!("Closing the connection");
109 socket.abort();
110 info!("Flushing the RST out...");
111 _ = socket.flush().await;
112 info!("Finished with the socket");
113 }
114}
115
116static EXECUTOR: StaticCell<Executor> = StaticCell::new();
117
118fn main() {
119 env_logger::builder()
120 .filter_level(log::LevelFilter::Debug)
121 .filter_module("async_io", log::LevelFilter::Info)
122 .format_timestamp_nanos()
123 .init();
124
125 let executor = EXECUTOR.init(Executor::new());
126 executor.run(|spawner| {
127 spawner.spawn(main_task(spawner)).unwrap();
128 });
129}