Skip to main content

custom_interface_device/
custom_interface_device.rs

1//! Device-side example for USB gadget with custom interface.
2
3use bytes::BytesMut;
4use std::{
5    io::ErrorKind,
6    sync::{
7        atomic::{AtomicBool, Ordering},
8        Arc,
9    },
10    thread,
11    time::Duration,
12};
13
14use usb_gadget::{
15    default_udc,
16    function::custom::{Custom, Endpoint, EndpointDirection, Event, Interface},
17    Class, Config, Gadget, Id, OsDescriptor, Strings, WebUsb,
18};
19
20fn main() {
21    env_logger::init();
22
23    usb_gadget::remove_all().expect("cannot remove all gadgets");
24
25    let (mut ep1_rx, ep1_dir) = EndpointDirection::host_to_device();
26    let (mut ep2_tx, ep2_dir) = EndpointDirection::device_to_host();
27
28    let (mut custom, handle) = Custom::builder()
29        .with_interface(
30            Interface::new(Class::vendor_specific(1, 2), "custom interface")
31                .with_endpoint(Endpoint::bulk(ep1_dir))
32                .with_endpoint(Endpoint::bulk(ep2_dir)),
33        )
34        .build();
35
36    let udc = default_udc().expect("cannot get UDC");
37    let reg = Gadget::new(
38        Class::vendor_specific(255, 3),
39        Id::new(6, 0x11),
40        Strings::new("manufacturer", "custom USB interface", "serial_number"),
41    )
42    .with_config(Config::new("config").with_function(handle))
43    .with_os_descriptor(OsDescriptor::microsoft())
44    .with_web_usb(WebUsb::new(0xf1, "http://webusb.org"))
45    .bind(&udc)
46    .expect("cannot bind to UDC");
47
48    println!("Custom function at {}", custom.status().unwrap().path().unwrap().display());
49    println!();
50
51    let ep1_control = ep1_rx.control().unwrap();
52    println!("ep1 unclaimed: {:?}", ep1_control.unclaimed_fifo());
53    println!("ep1 real address: {}", ep1_control.real_address().unwrap());
54    println!("ep1 descriptor: {:?}", ep1_control.descriptor().unwrap());
55    println!();
56
57    let ep2_control = ep2_tx.control().unwrap();
58    println!("ep2 unclaimed: {:?}", ep2_control.unclaimed_fifo());
59    println!("ep2 real address: {}", ep2_control.real_address().unwrap());
60    println!("ep2 descriptor: {:?}", ep2_control.descriptor().unwrap());
61    println!();
62
63    let stop = Arc::new(AtomicBool::new(false));
64
65    thread::scope(|s| {
66        s.spawn(|| {
67            let size = ep1_rx.max_packet_size().unwrap();
68            let mut b = 0;
69            while !stop.load(Ordering::Relaxed) {
70                let data = ep1_rx
71                    .recv_timeout(BytesMut::with_capacity(size), Duration::from_secs(1))
72                    .expect("recv failed");
73                match data {
74                    Some(data) => {
75                        println!("received {} bytes: {data:x?}", data.len());
76                        if !data.iter().all(|x| *x == b) {
77                            panic!("wrong data received");
78                        }
79                        b = b.wrapping_add(1);
80                    }
81                    None => {
82                        println!("receive empty");
83                    }
84                }
85            }
86        });
87
88        s.spawn(|| {
89            let size = ep2_tx.max_packet_size().unwrap();
90            let mut b = 0u8;
91            while !stop.load(Ordering::Relaxed) {
92                let data = vec![b; size];
93                match ep2_tx.send_timeout(data.into(), Duration::from_secs(1)) {
94                    Ok(()) => {
95                        println!("sent data {b} of size {size} bytes");
96                        b = b.wrapping_add(1);
97                    }
98                    Err(err) if err.kind() == ErrorKind::TimedOut => println!("send timeout"),
99                    Err(err) => panic!("send failed: {err}"),
100                }
101            }
102        });
103
104        s.spawn(|| {
105            let mut ctrl_data = Vec::new();
106
107            while !stop.load(Ordering::Relaxed) {
108                if let Some(event) = custom.event_timeout(Duration::from_secs(1)).expect("event failed") {
109                    println!("Event: {event:?}");
110                    match event {
111                        Event::SetupHostToDevice(req) => {
112                            if req.ctrl_req().request == 255 {
113                                println!("Stopping");
114                                stop.store(true, Ordering::Relaxed);
115                            }
116                            ctrl_data = req.recv_all().unwrap();
117                            println!("Control data: {ctrl_data:x?}");
118                        }
119                        Event::SetupDeviceToHost(req) => {
120                            println!("Replying with data");
121                            req.send(&ctrl_data).unwrap();
122                        }
123                        _ => (),
124                    }
125                } else {
126                    println!("no event");
127                }
128            }
129        });
130    });
131
132    thread::sleep(Duration::from_secs(1));
133
134    println!("Unregistering");
135    reg.remove().unwrap();
136}