Skip to main content

simple_device/
simple_device.rs

1//! Simple device-side example from the README.
2
3use std::time::Duration;
4use upc::{
5    device::{InterfaceId, UpcFunction},
6    Class,
7};
8use usb_gadget::{default_udc, Config, Gadget, Id, OsDescriptor, Strings};
9use uuid::uuid;
10
11#[tokio::main(flavor = "current_thread")]
12async fn main() -> std::io::Result<()> {
13    let class = Class::vendor_specific(0x01, 0);
14
15    // Create a USB gadget with a UPC function.
16    let (mut upc, hnd) =
17        UpcFunction::new(InterfaceId::new(class).with_guid(uuid!("3bf77270-42d2-42c6-a475-490227a9cc89")));
18    upc.set_info(b"my device".to_vec()).await;
19
20    let udc = default_udc().expect("no UDC available");
21    let gadget = Gadget::new(class.into(), Id::new(0x1209, 0x0001), Strings::new("mfr", "product", "serial"))
22        .with_config(Config::new("config").with_function(hnd))
23        .with_os_descriptor(OsDescriptor::microsoft());
24    let _reg = gadget.bind(&udc).expect("cannot bind to UDC");
25
26    // Accept a connection and exchange packets.
27    let (tx, mut rx) = upc.accept().await?;
28    if let Some(data) = rx.recv().await? {
29        println!("received: {:?}", data);
30        tx.send(b"pong"[..].into()).await?;
31    }
32
33    // Allow USB transport to flush before teardown.
34    tokio::time::sleep(Duration::from_secs(1)).await;
35    Ok(())
36}