#![no_std] use defmt::{assert, *}; use embassy_futures::join::join; use embassy_net::driver::Driver; use embassy_net::tcp::TcpSocket; use embassy_net::{Ipv4Address, Stack}; use embassy_time::{with_timeout, Duration, Timer}; pub struct Expected { pub down_kbps: usize, pub up_kbps: usize, pub updown_kbps: usize, } pub async fn run(stack: &Stack, expected: Expected) { info!("Waiting for DHCP up..."); while stack.config_v4().is_none() { Timer::after(Duration::from_millis(100)).await; } info!("IP addressing up!"); let down = test_download(stack).await; let up = test_upload(stack).await; let updown = test_upload_download(stack).await; assert!(down > expected.down_kbps); assert!(up > expected.up_kbps); assert!(updown > expected.updown_kbps); } const TEST_DURATION: usize = 10; const IO_BUFFER_SIZE: usize = 1024; const RX_BUFFER_SIZE: usize = 4096; const TX_BUFFER_SIZE: usize = 4096; const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2); const DOWNLOAD_PORT: u16 = 4321; const UPLOAD_PORT: u16 = 4322; const UPLOAD_DOWNLOAD_PORT: u16 = 4323; async fn test_download(stack: &Stack) -> usize { info!("Testing download..."); let mut rx_buffer = [0; RX_BUFFER_SIZE]; let mut tx_buffer = [0; TX_BUFFER_SIZE]; let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); socket.set_timeout(Some(Duration::from_secs(10))); info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT); if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await { error!("connect error: {:?}", e); return 0; } info!("connected, testing..."); let mut rx_buf = [0; IO_BUFFER_SIZE]; let mut total: usize = 0; with_timeout(Duration::from_secs(TEST_DURATION as _), async { loop { match socket.read(&mut rx_buf).await { Ok(0) => { error!("read EOF"); return 0; } Ok(n) => total += n, Err(e) => { error!("read error: {:?}", e); return 0; } } } }) .await .ok(); let kbps = (total + 512) / 1024 / TEST_DURATION; info!("download: {} kB/s", kbps); kbps } async fn test_upload(stack: &Stack) -> usize { info!("Testing upload..."); let mut rx_buffer = [0; RX_BUFFER_SIZE]; let mut tx_buffer = [0; TX_BUFFER_SIZE]; let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); socket.set_timeout(Some(Duration::from_secs(10))); info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT); if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await { error!("connect error: {:?}", e); return 0; } info!("connected, testing..."); let buf = [0; IO_BUFFER_SIZE]; let mut total: usize = 0; with_timeout(Duration::from_secs(TEST_DURATION as _), async { loop { match socket.write(&buf).await { Ok(0) => { error!("write zero?!??!?!"); return 0; } Ok(n) => total += n, Err(e) => { error!("write error: {:?}", e); return 0; } } } }) .await .ok(); let kbps = (total + 512) / 1024 / TEST_DURATION; info!("upload: {} kB/s", kbps); kbps } async fn test_upload_download(stack: &Stack) -> usize { info!("Testing upload+download..."); let mut rx_buffer = [0; RX_BUFFER_SIZE]; let mut tx_buffer = [0; TX_BUFFER_SIZE]; let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); socket.set_timeout(Some(Duration::from_secs(10))); info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT); if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await { error!("connect error: {:?}", e); return 0; } info!("connected, testing..."); let (mut reader, mut writer) = socket.split(); let tx_buf = [0; IO_BUFFER_SIZE]; let mut rx_buf = [0; IO_BUFFER_SIZE]; let mut total: usize = 0; let tx_fut = async { loop { match writer.write(&tx_buf).await { Ok(0) => { error!("write zero?!??!?!"); return 0; } Ok(_) => {} Err(e) => { error!("write error: {:?}", e); return 0; } } } }; let rx_fut = async { loop { match reader.read(&mut rx_buf).await { Ok(0) => { error!("read EOF"); return 0; } Ok(n) => total += n, Err(e) => { error!("read error: {:?}", e); return 0; } } } }; with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut)) .await .ok(); let kbps = (total + 512) / 1024 / TEST_DURATION; info!("upload+download: {} kB/s", kbps); kbps }