Skip to main content

Interface

Struct Interface 

Source
#[non_exhaustive]
pub struct Interface { pub interface_class: Class, pub name: HashMap<Language, String>, pub endpoints: Vec<Endpoint>, pub association: Option<Association>, pub os_ext_compat: Vec<OsExtCompat>, pub os_ext_props: Vec<OsExtProp>, pub custom_descs: Vec<CustomDesc>, }
Expand description

An USB interface.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§interface_class: Class

Interface class.

§name: HashMap<Language, String>

Interface name.

§endpoints: Vec<Endpoint>

USB endpoints.

§association: Option<Association>

Interface association.

§os_ext_compat: Vec<OsExtCompat>

Microsoft extended compatibility descriptors.

§os_ext_props: Vec<OsExtProp>

Microsoft extended properties.

§custom_descs: Vec<CustomDesc>

Custom descriptors.

These are inserted directly after the interface descriptor.

Implementations§

Source§

impl Interface

Source

pub fn new(interface_class: Class, name: impl AsRef<str>) -> Self

Creates a new interface.

Examples found in repository?
examples/custom_interface_device_split.rs (line 44)
25fn main() {
26    env_logger::init();
27
28    let existing = std::env::var("EXISTING_FFS").ok();
29    let register_only = std::env::var("REGISTER_ONLY").ok().is_some();
30
31    let (ep1_rx, ep1_dir) = EndpointDirection::host_to_device();
32    let (ep2_tx, ep2_dir) = EndpointDirection::device_to_host();
33
34    let mut builder = Custom::builder();
35
36    if register_only {
37        // We are only registering and binding the gadget, and leaving the FunctionFS interactions
38        // to another process.
39        builder.ffs_no_init = true;
40        builder.ffs_uid = Some(std::env::var("SUDO_UID").unwrap().parse().unwrap());
41        builder.ffs_gid = Some(std::env::var("SUDO_GID").unwrap().parse().unwrap());
42    } else {
43        builder = builder.with_interface(
44            Interface::new(Class::vendor_specific(1, 2), "custom interface")
45                .with_endpoint(Endpoint::bulk(ep1_dir))
46                .with_endpoint(Endpoint::bulk(ep2_dir)),
47        );
48    }
49
50    let (reg, custom) = if let Some(ref path) = existing {
51        (None, builder.existing(path).unwrap())
52    } else {
53        let (mut custom, handle) = builder.build();
54
55        usb_gadget::remove_all().expect("cannot remove all gadgets");
56
57        let udc = default_udc().expect("cannot get UDC");
58        let gadget = Gadget::new(
59            Class::vendor_specific(255, 3),
60            Id::new(6, 0x11),
61            Strings::new("manufacturer", "custom USB interface", "serial_number"),
62        )
63        .with_config(Config::new("config").with_function(handle))
64        .with_os_descriptor(OsDescriptor::microsoft())
65        .with_web_usb(WebUsb::new(0xf1, "http://webusb.org"));
66
67        let reg = gadget.register().expect("cannot register gadget");
68
69        if register_only {
70            let ffs_dir = custom.ffs_dir().unwrap();
71            println!("FunctionFS dir mounted at {}", ffs_dir.display());
72            println!("You can now run this program again as unprivileged user:");
73            println!("EXISTING_FFS={} {}", ffs_dir.display(), std::env::args().next().unwrap());
74
75            let mut ep1_path = ffs_dir.clone();
76            ep1_path.push("ep1");
77            while std::fs::metadata(&ep1_path).is_err() {
78                thread::sleep(Duration::from_secs(1));
79            }
80
81            println!("Detected ep1 in FunctionFS dir, this means descriptors have been written to ep0.");
82            println!("Now binding gadget to UDC (making it active)...");
83        }
84
85        reg.bind(Some(&udc)).expect("cannot bind to UDC");
86
87        println!("Custom function at {}", custom.status().unwrap().path().unwrap().display());
88        println!();
89
90        (Some(reg), custom)
91    };
92
93    if register_only {
94        println!("Waiting for the gadget to become unbound. If you stop the other process, this will happen automatically.");
95        while reg.as_ref().unwrap().udc().unwrap().is_some() {
96            thread::sleep(Duration::from_secs(1));
97        }
98    } else {
99        if existing.is_some() {
100            println!("The FunctionFS setup is done, you can type 'yes' in the other process and hit <ENTER>");
101        }
102        run(ep1_rx, ep2_tx, custom);
103    }
104
105    if let Some(reg) = reg {
106        println!("Unregistering");
107        reg.remove().unwrap();
108    }
109}
More examples
Hide additional examples
examples/custom_interface_device_async.rs (line 29)
19async fn main() {
20    env_logger::init();
21
22    usb_gadget::remove_all().expect("cannot remove all gadgets");
23
24    let (mut ep1_rx, ep1_dir) = EndpointDirection::host_to_device();
25    let (mut ep2_tx, ep2_dir) = EndpointDirection::device_to_host();
26
27    let (mut custom, handle) = Custom::builder()
28        .with_interface(
29            Interface::new(Class::vendor_specific(1, 2), "custom interface")
30                .with_endpoint(Endpoint::bulk(ep1_dir))
31                .with_endpoint(Endpoint::bulk(ep2_dir)),
32        )
33        .build();
34
35    let udc = default_udc().expect("cannot get UDC");
36    let reg = Gadget::new(
37        Class::vendor_specific(255, 3),
38        Id::new(6, 0x11),
39        Strings::new("manufacturer", "custom USB interface", "serial_number"),
40    )
41    .with_config(Config::new("config").with_function(handle))
42    .with_os_descriptor(OsDescriptor::microsoft())
43    .with_web_usb(WebUsb::new(0xf1, "http://webusb.org"))
44    .bind(&udc)
45    .expect("cannot bind to UDC");
46
47    println!("Custom function at {}", custom.status().unwrap().path().unwrap().display());
48    println!();
49
50    let ep1_control = ep1_rx.control().unwrap();
51    println!("ep1 unclaimed: {:?}", ep1_control.unclaimed_fifo());
52    println!("ep1 real address: {}", ep1_control.real_address().unwrap());
53    println!("ep1 descriptor: {:?}", ep1_control.descriptor().unwrap());
54    println!();
55
56    let ep2_control = ep2_tx.control().unwrap();
57    println!("ep2 unclaimed: {:?}", ep2_control.unclaimed_fifo());
58    println!("ep2 real address: {}", ep2_control.real_address().unwrap());
59    println!("ep2 descriptor: {:?}", ep2_control.descriptor().unwrap());
60    println!();
61
62    let stop = Arc::new(AtomicBool::new(false));
63
64    let stop1 = stop.clone();
65    tokio::spawn(async move {
66        let size = ep1_rx.max_packet_size().unwrap();
67        let mut b = 0;
68        while !stop1.load(Ordering::Relaxed) {
69            let data = ep1_rx.recv_async(BytesMut::with_capacity(size)).await.expect("recv_async failed");
70            match data {
71                Some(data) => {
72                    println!("received {} bytes: {data:x?}", data.len());
73                    if !data.iter().all(|x| *x == b) {
74                        panic!("wrong data received");
75                    }
76                    b = b.wrapping_add(1);
77                }
78                None => {
79                    println!("receive empty");
80                }
81            }
82        }
83    });
84
85    let stop2 = stop.clone();
86    tokio::spawn(async move {
87        let size = ep2_tx.max_packet_size().unwrap();
88        let mut b = 0u8;
89        while !stop2.load(Ordering::Relaxed) {
90            let data = vec![b; size];
91            match ep2_tx.send_async(data.into()).await {
92                Ok(()) => {
93                    println!("sent data {b} of size {size} bytes");
94                    b = b.wrapping_add(1);
95                }
96                Err(err) => panic!("send failed: {err}"),
97            }
98        }
99    });
100
101    let mut ctrl_data = Vec::new();
102    while !stop.load(Ordering::Relaxed) {
103        custom.wait_event().await.expect("wait for event failed");
104        println!("event ready");
105        let event = custom.event().expect("event failed");
106
107        println!("Event: {event:?}");
108        match event {
109            Event::SetupHostToDevice(req) => {
110                if req.ctrl_req().request == 255 {
111                    println!("Stopping");
112                    stop.store(true, Ordering::Relaxed);
113                }
114                ctrl_data = req.recv_all().unwrap();
115                println!("Control data: {ctrl_data:x?}");
116            }
117            Event::SetupDeviceToHost(req) => {
118                println!("Replying with data");
119                req.send(&ctrl_data).unwrap();
120            }
121            _ => (),
122        }
123    }
124
125    tokio::time::sleep(Duration::from_secs(1)).await;
126
127    println!("Unregistering");
128    reg.remove().unwrap();
129}
examples/custom_interface_device.rs (line 30)
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}
Source

pub fn with_endpoint(self, endpoint: Endpoint) -> Self

Add an USB endpoint.

Examples found in repository?
examples/custom_interface_device_split.rs (line 45)
25fn main() {
26    env_logger::init();
27
28    let existing = std::env::var("EXISTING_FFS").ok();
29    let register_only = std::env::var("REGISTER_ONLY").ok().is_some();
30
31    let (ep1_rx, ep1_dir) = EndpointDirection::host_to_device();
32    let (ep2_tx, ep2_dir) = EndpointDirection::device_to_host();
33
34    let mut builder = Custom::builder();
35
36    if register_only {
37        // We are only registering and binding the gadget, and leaving the FunctionFS interactions
38        // to another process.
39        builder.ffs_no_init = true;
40        builder.ffs_uid = Some(std::env::var("SUDO_UID").unwrap().parse().unwrap());
41        builder.ffs_gid = Some(std::env::var("SUDO_GID").unwrap().parse().unwrap());
42    } else {
43        builder = builder.with_interface(
44            Interface::new(Class::vendor_specific(1, 2), "custom interface")
45                .with_endpoint(Endpoint::bulk(ep1_dir))
46                .with_endpoint(Endpoint::bulk(ep2_dir)),
47        );
48    }
49
50    let (reg, custom) = if let Some(ref path) = existing {
51        (None, builder.existing(path).unwrap())
52    } else {
53        let (mut custom, handle) = builder.build();
54
55        usb_gadget::remove_all().expect("cannot remove all gadgets");
56
57        let udc = default_udc().expect("cannot get UDC");
58        let gadget = Gadget::new(
59            Class::vendor_specific(255, 3),
60            Id::new(6, 0x11),
61            Strings::new("manufacturer", "custom USB interface", "serial_number"),
62        )
63        .with_config(Config::new("config").with_function(handle))
64        .with_os_descriptor(OsDescriptor::microsoft())
65        .with_web_usb(WebUsb::new(0xf1, "http://webusb.org"));
66
67        let reg = gadget.register().expect("cannot register gadget");
68
69        if register_only {
70            let ffs_dir = custom.ffs_dir().unwrap();
71            println!("FunctionFS dir mounted at {}", ffs_dir.display());
72            println!("You can now run this program again as unprivileged user:");
73            println!("EXISTING_FFS={} {}", ffs_dir.display(), std::env::args().next().unwrap());
74
75            let mut ep1_path = ffs_dir.clone();
76            ep1_path.push("ep1");
77            while std::fs::metadata(&ep1_path).is_err() {
78                thread::sleep(Duration::from_secs(1));
79            }
80
81            println!("Detected ep1 in FunctionFS dir, this means descriptors have been written to ep0.");
82            println!("Now binding gadget to UDC (making it active)...");
83        }
84
85        reg.bind(Some(&udc)).expect("cannot bind to UDC");
86
87        println!("Custom function at {}", custom.status().unwrap().path().unwrap().display());
88        println!();
89
90        (Some(reg), custom)
91    };
92
93    if register_only {
94        println!("Waiting for the gadget to become unbound. If you stop the other process, this will happen automatically.");
95        while reg.as_ref().unwrap().udc().unwrap().is_some() {
96            thread::sleep(Duration::from_secs(1));
97        }
98    } else {
99        if existing.is_some() {
100            println!("The FunctionFS setup is done, you can type 'yes' in the other process and hit <ENTER>");
101        }
102        run(ep1_rx, ep2_tx, custom);
103    }
104
105    if let Some(reg) = reg {
106        println!("Unregistering");
107        reg.remove().unwrap();
108    }
109}
More examples
Hide additional examples
examples/custom_interface_device_async.rs (line 30)
19async fn main() {
20    env_logger::init();
21
22    usb_gadget::remove_all().expect("cannot remove all gadgets");
23
24    let (mut ep1_rx, ep1_dir) = EndpointDirection::host_to_device();
25    let (mut ep2_tx, ep2_dir) = EndpointDirection::device_to_host();
26
27    let (mut custom, handle) = Custom::builder()
28        .with_interface(
29            Interface::new(Class::vendor_specific(1, 2), "custom interface")
30                .with_endpoint(Endpoint::bulk(ep1_dir))
31                .with_endpoint(Endpoint::bulk(ep2_dir)),
32        )
33        .build();
34
35    let udc = default_udc().expect("cannot get UDC");
36    let reg = Gadget::new(
37        Class::vendor_specific(255, 3),
38        Id::new(6, 0x11),
39        Strings::new("manufacturer", "custom USB interface", "serial_number"),
40    )
41    .with_config(Config::new("config").with_function(handle))
42    .with_os_descriptor(OsDescriptor::microsoft())
43    .with_web_usb(WebUsb::new(0xf1, "http://webusb.org"))
44    .bind(&udc)
45    .expect("cannot bind to UDC");
46
47    println!("Custom function at {}", custom.status().unwrap().path().unwrap().display());
48    println!();
49
50    let ep1_control = ep1_rx.control().unwrap();
51    println!("ep1 unclaimed: {:?}", ep1_control.unclaimed_fifo());
52    println!("ep1 real address: {}", ep1_control.real_address().unwrap());
53    println!("ep1 descriptor: {:?}", ep1_control.descriptor().unwrap());
54    println!();
55
56    let ep2_control = ep2_tx.control().unwrap();
57    println!("ep2 unclaimed: {:?}", ep2_control.unclaimed_fifo());
58    println!("ep2 real address: {}", ep2_control.real_address().unwrap());
59    println!("ep2 descriptor: {:?}", ep2_control.descriptor().unwrap());
60    println!();
61
62    let stop = Arc::new(AtomicBool::new(false));
63
64    let stop1 = stop.clone();
65    tokio::spawn(async move {
66        let size = ep1_rx.max_packet_size().unwrap();
67        let mut b = 0;
68        while !stop1.load(Ordering::Relaxed) {
69            let data = ep1_rx.recv_async(BytesMut::with_capacity(size)).await.expect("recv_async failed");
70            match data {
71                Some(data) => {
72                    println!("received {} bytes: {data:x?}", data.len());
73                    if !data.iter().all(|x| *x == b) {
74                        panic!("wrong data received");
75                    }
76                    b = b.wrapping_add(1);
77                }
78                None => {
79                    println!("receive empty");
80                }
81            }
82        }
83    });
84
85    let stop2 = stop.clone();
86    tokio::spawn(async move {
87        let size = ep2_tx.max_packet_size().unwrap();
88        let mut b = 0u8;
89        while !stop2.load(Ordering::Relaxed) {
90            let data = vec![b; size];
91            match ep2_tx.send_async(data.into()).await {
92                Ok(()) => {
93                    println!("sent data {b} of size {size} bytes");
94                    b = b.wrapping_add(1);
95                }
96                Err(err) => panic!("send failed: {err}"),
97            }
98        }
99    });
100
101    let mut ctrl_data = Vec::new();
102    while !stop.load(Ordering::Relaxed) {
103        custom.wait_event().await.expect("wait for event failed");
104        println!("event ready");
105        let event = custom.event().expect("event failed");
106
107        println!("Event: {event:?}");
108        match event {
109            Event::SetupHostToDevice(req) => {
110                if req.ctrl_req().request == 255 {
111                    println!("Stopping");
112                    stop.store(true, Ordering::Relaxed);
113                }
114                ctrl_data = req.recv_all().unwrap();
115                println!("Control data: {ctrl_data:x?}");
116            }
117            Event::SetupDeviceToHost(req) => {
118                println!("Replying with data");
119                req.send(&ctrl_data).unwrap();
120            }
121            _ => (),
122        }
123    }
124
125    tokio::time::sleep(Duration::from_secs(1)).await;
126
127    println!("Unregistering");
128    reg.remove().unwrap();
129}
examples/custom_interface_device.rs (line 31)
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}
Source

pub fn with_association(self, association: &Association) -> Self

Set the USB interface association.

Source

pub fn with_os_ext_compat(self, os_ext_compat: OsExtCompat) -> Self

Adds a Microsoft extended compatibility descriptor.

Source

pub fn with_os_ext_prop(self, os_ext_prop: OsExtProp) -> Self

Adds a Microsoft extended property.

Source

pub fn with_custom_desc(self, custom_desc: CustomDesc) -> Self

Adds a custom descriptor after the interface descriptor.

Trait Implementations§

Source§

impl Debug for Interface

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.