device/
device.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Device-side example.

use std::time::{Duration, Instant};
use tokio::time::sleep;
use usb_gadget::{default_udc, Config, Gadget, Id, OsDescriptor, Strings};
use uuid::uuid;

use upc::{
    device::{InterfaceId, UpcFunction},
    Class,
};

mod common;
use common::*;

const DEVICE_CLASS: Class = Class::vendor_specific(0xff, 0);

#[tokio::main(flavor = "current_thread")]
async fn main() {
    init_log();

    usb_gadget::remove_all().expect("cannot remove all USB gadgets");
    sleep(Duration::from_secs(1)).await;

    println!("Creating UPC function...");
    let (mut upc, hnd) = UpcFunction::new(
        InterfaceId::new(CLASS)
            .with_name("USB PACKET TEST")
            .with_guid(uuid!("3bf77270-42d2-42c6-a475-490227a9cc89")),
    );
    upc.set_info(INFO.to_vec()).await;

    println!("Registering gadget...");
    let udc = default_udc().expect("cannot get UDC");
    let mut gadget = Gadget::new(DEVICE_CLASS.into(), Id::new(VID, PID), Strings::new("usb-packet", "test", "0"))
        .with_config(Config::new("config").with_function(hnd))
        .with_os_descriptor(OsDescriptor::microsoft());
    gadget.device_release = 0x0110;
    let reg = gadget.bind(&udc).expect("cannot bind to UDC");
    assert!(reg.is_attached());

    println!("Waiting for connection...");
    let (tx, mut rx) = upc.accept().await.expect("accept failed");
    assert_eq!(rx.topic(), TOPIC, "wrong topic");

    let rx_task = tokio::spawn(async move {
        let mut rx_testdata = TestData::new(HOST_SEED, TEST_PACKET_MAX_SIZE);
        let mut rx_delay = TestDelayer::new(HOST_SEED);

        let start = Instant::now();
        let mut total = 0;

        println!("Receiving...");
        for n in 0..TEST_PACKETS {
            let data = rx.recv().await.expect("receive failed");
            eprintln!("Recv {n}: {} bytes", data.len());
            total += data.len();
            rx_testdata.validate(&data);
            rx_delay.delay().await;
        }

        let elapsed = start.elapsed().as_secs_f32();
        println!("Received {total} bytes in {elapsed:.2} seconds: {} MB/s", total as f32 / elapsed / 1_048_576.);

        println!("Waiting for receiver close");
        rx.recv().await.expect_err("receiver not closed");
        println!("Receiver closed");
    });

    let mut tx_testdata = TestData::new(DEVICE_SEED, TEST_PACKET_MAX_SIZE);
    let mut tx_delay = TestDelayer::new(DEVICE_SEED);

    let start = Instant::now();
    let mut total = 0;

    println!("Sending");
    for n in 0..TEST_PACKETS {
        let data = tx_testdata.generate();
        let len = data.len();
        tx.send(data.into()).await.expect("send failed");
        total += len;
        tx_delay.delay().await;

        eprintln!("Send {n}: {len} bytes");
    }

    let elapsed = start.elapsed().as_secs_f32();
    println!("Sent {total} bytes in {elapsed:.2} seconds: {} MB/s", total as f32 / elapsed / 1_048_576.);

    sleep(Duration::from_secs(1)).await;

    println!("Waiting for receiver...");
    rx_task.await.unwrap();
    drop(tx);
    println!("Disconnected");

    sleep(Duration::from_secs(1)).await;
}