1use std::time::{Duration, Instant};
4use tokio::time::sleep;
5use usb_gadget::{default_udc, Config, Gadget, Id, OsDescriptor, Strings};
6use uuid::uuid;
7
8use upc::{
9 device::{InterfaceId, UpcFunction},
10 Class,
11};
12
13mod common;
14use common::*;
15
16const DEVICE_CLASS: Class = Class::vendor_specific(0xff, 0);
17
18#[tokio::main(flavor = "current_thread")]
19async fn main() {
20 init_log();
21
22 usb_gadget::remove_all().expect("cannot remove all USB gadgets");
23 sleep(Duration::from_secs(1)).await;
24
25 println!("Creating UPC function...");
26 let (mut upc, hnd) = UpcFunction::new(
27 InterfaceId::new(CLASS)
28 .with_name("USB PACKET TEST")
29 .with_guid(uuid!("3bf77270-42d2-42c6-a475-490227a9cc89")),
30 );
31 upc.set_info(INFO.to_vec()).await;
32
33 println!("Registering gadget...");
34 let udc = default_udc().expect("cannot get UDC");
35 let mut gadget = Gadget::new(DEVICE_CLASS.into(), Id::new(VID, PID), Strings::new("usb-packet", "test", "0"))
36 .with_config(Config::new("config").with_function(hnd))
37 .with_os_descriptor(OsDescriptor::microsoft());
38 gadget.device_release = 0x0110;
39 let reg = gadget.bind(&udc).expect("cannot bind to UDC");
40 assert!(reg.is_attached());
41
42 loop {
43 println!("Waiting for connection...");
44 let (tx, mut rx) = tokio::select! {
45 res = upc.accept() => res.expect("accept failed"),
46 _ = tokio::signal::ctrl_c() => break,
47 };
48
49 assert_eq!(rx.topic(), TOPIC, "wrong topic");
50
51 let overall_start = Instant::now();
52
53 let rx_task = tokio::spawn(async move {
54 let mut rx_testdata = TestData::new(HOST_SEED, TEST_PACKET_MAX_SIZE);
55 let mut rx_delay = TestDelayer::new(HOST_SEED);
56
57 let start = Instant::now();
58 let mut total = 0usize;
59
60 println!("Receiving...");
61 for n in 0..TEST_PACKETS {
62 let data = rx.recv().await.expect("receive failed").expect("unexpected EOF");
63 eprintln!("Recv {n}: {} bytes", data.len());
64 total += data.len();
65 rx_testdata.validate(&data);
66 rx_delay.delay().await;
67 }
68
69 let elapsed = start.elapsed().as_secs_f32();
70 println!(
71 "Received {total} bytes in {elapsed:.2} seconds: {} MB/s",
72 total as f32 / elapsed / 1_048_576.
73 );
74
75 println!("Waiting for receiver close");
76 assert_eq!(rx.recv().await.unwrap(), None, "receiver not closed");
77 println!("Receiver closed");
78
79 total
80 });
81
82 let mut tx_testdata = TestData::new(DEVICE_SEED, TEST_PACKET_MAX_SIZE);
83 let mut tx_delay = TestDelayer::new(DEVICE_SEED);
84
85 let start = Instant::now();
86 let mut tx_total = 0;
87
88 println!("Sending");
89 for n in 0..TEST_PACKETS {
90 let data = tx_testdata.generate();
91 let len = data.len();
92 tx.send(data.into()).await.expect("send failed");
93 tx_total += len;
94 tx_delay.delay().await;
95
96 eprintln!("Send {n}: {len} bytes");
97 }
98
99 let elapsed = start.elapsed().as_secs_f32();
100 println!(
101 "Sent {tx_total} bytes in {elapsed:.2} seconds: {} MB/s",
102 tx_total as f32 / elapsed / 1_048_576.
103 );
104
105 sleep(Duration::from_secs(3)).await;
106
107 println!("Waiting for receiver...");
108 let rx_total = rx_task.await.unwrap();
109 drop(tx);
110
111 let overall_elapsed = overall_start.elapsed().as_secs_f32();
112 let total_bytes = tx_total + rx_total;
113 println!(
114 "Total throughput: {} bytes in {overall_elapsed:.2} seconds: {:.2} MB/s",
115 total_bytes,
116 total_bytes as f32 / overall_elapsed / 1_048_576.
117 );
118 println!("Disconnected\n");
119 }
120
121 drop(reg);
122 sleep(Duration::from_secs(1)).await;
123}