device/
device.rs

1//! Device-side example.
2
3use 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    println!("Waiting for connection...");
43    let (tx, mut rx) = upc.accept().await.expect("accept failed");
44    assert_eq!(rx.topic(), TOPIC, "wrong topic");
45
46    let rx_task = tokio::spawn(async move {
47        let mut rx_testdata = TestData::new(HOST_SEED, TEST_PACKET_MAX_SIZE);
48        let mut rx_delay = TestDelayer::new(HOST_SEED);
49
50        let start = Instant::now();
51        let mut total = 0;
52
53        println!("Receiving...");
54        for n in 0..TEST_PACKETS {
55            let data = rx.recv().await.expect("receive failed");
56            eprintln!("Recv {n}: {} bytes", data.len());
57            total += data.len();
58            rx_testdata.validate(&data);
59            rx_delay.delay().await;
60        }
61
62        let elapsed = start.elapsed().as_secs_f32();
63        println!("Received {total} bytes in {elapsed:.2} seconds: {} MB/s", total as f32 / elapsed / 1_048_576.);
64
65        println!("Waiting for receiver close");
66        rx.recv().await.expect_err("receiver not closed");
67        println!("Receiver closed");
68    });
69
70    let mut tx_testdata = TestData::new(DEVICE_SEED, TEST_PACKET_MAX_SIZE);
71    let mut tx_delay = TestDelayer::new(DEVICE_SEED);
72
73    let start = Instant::now();
74    let mut total = 0;
75
76    println!("Sending");
77    for n in 0..TEST_PACKETS {
78        let data = tx_testdata.generate();
79        let len = data.len();
80        tx.send(data.into()).await.expect("send failed");
81        total += len;
82        tx_delay.delay().await;
83
84        eprintln!("Send {n}: {len} bytes");
85    }
86
87    let elapsed = start.elapsed().as_secs_f32();
88    println!("Sent {total} bytes in {elapsed:.2} seconds: {} MB/s", total as f32 / elapsed / 1_048_576.);
89
90    sleep(Duration::from_secs(3)).await;
91
92    println!("Waiting for receiver...");
93    rx_task.await.unwrap();
94    drop(tx);
95    println!("Disconnected");
96
97    sleep(Duration::from_secs(1)).await;
98}