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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//! Cross USB is a USB library which works seamlessly across native and WASM targets.
//!
//! The idea is the user only has to write one way to access USB devices, which can be compiled
//! to both WASM and native targets without any additional conditional compilation or configuration.
//!
//! For native device support, this library uses [nusb](https://docs.rs/nusb/latest/nusb/), a cross platform USB library written in Rust
//! and comparable to the very popular `libusb` C library. Web Assembly support is provided by [web-sys](https://docs.rs/web-sys/latest/web_sys/)
//! with the [Web USB API](https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API).
//!
//!
//! ## CURRENT LIMITATIONS:
//! * Isochronous and interrupt transfers are currently not supported. This
//! will probably change in a future release.
//!
//! * Hotplug support is not implemented. Waiting on
//! [hotplug support in nusb](https://github.com/kevinmehall/nusb/pull/20).
//!
//! * When compiling this crate on a WASM target, you **must** use either
//! `RUSTFLAGS=--cfg=web_sys_unstable_apis` or by passing the argument in a
//! `.cargo/config.toml` file. Read more here:
//! <https://rustwasm.github.io/wasm-bindgen/web-sys/unstable-apis.html>
//!
//! ## Example:
//! ```no_run
//! # tokio_test::block_on(async {
//! use cross_usb::prelude::*;
//! use cross_usb::usb::{Recipient, ControlType, ControlIn};
//! use cross_usb::device_filter;
//!
//! // Obtain a device descriptor using a DeviceFilter,
//! // in this case with its VendorID and ProductID
//! let filters = vec![
//! device_filter!{vendor_id: 0x054c, product_id: 0x00c9}
//! ];
//! let dev_descriptor = cross_usb::get_device(filters).await.expect("Failed to find device");
//!
//! // Open the device that the descriptor is describing
//! let dev = dev_descriptor.open().await.expect("Failed to open device");
//!
//! // Obtain an interface of the device
//! let interface = dev.open_interface(0).await.expect("Failed to open interface");
//!
//! // Send a Control transfer to the device, obtaining
//! // the result and storing it in `result`
//! let result = interface.control_in(ControlIn {
//! control_type: ControlType::Vendor,
//! recipient: Recipient::Interface,
//! request: 0x01,
//! value: 0,
//! index: 0,
//! length: 4,
//! })
//! .await
//! .expect("Sending control transfer failed");
//! # })
//! ```
/// This prelude imports all the necessary traits needed to actually use USB
/// devices and interfaces.
///
/// ```
/// use cross_usb::prelude::*;
/// ```
/// The context contains the platform specific implementation of the USB transfers
/// Information about a USB device, containing information about a device
/// without claiming it
///
/// **Note:** On WASM targets, a device *must* be claimed in order to get
/// information about it in normal circumstances, so this is not as useful
/// on WASM.
pub use crateDeviceInfo;
/// A USB device, you must open an [`Interface`] to perform transfers.
pub use crateDevice;
/// A USB interface to perform transfers with.
pub use crateInterface;
/// Information about a USB device for use in [`get_device`] or
/// [`get_device_list`].
///
/// It's easiest to construct this using the [`device_filter`]
/// macro.
pub use crateDeviceFilter;
/// Gets a single (the first found) device as a [`DeviceInfo`] from a list of VendorID
/// and ProductIDs
///
/// ## Example
/// ```no_run
/// # tokio_test::block_on(async {
/// use cross_usb::{get_device, DeviceFilter, device_filter};
///
/// let filter = vec![
/// device_filter!{vendor_id: 0x054c, product_id: 0x00c9},
/// device_filter!{vendor_id: 0x054c},
/// ];
///
/// let device = get_device(filter).await.expect("Could not find device matching filters");
/// # })
/// ```
pub use crateget_device;
/// Gets a list of [`DeviceInfo`]s from a list of VendorID and ProductIDs
///
/// ## Example
/// ```no_run
/// # tokio_test::block_on(async {
/// use cross_usb::{get_device_list, DeviceFilter, device_filter};
///
/// let filter = vec![
/// device_filter!{vendor_id: 0x054c, product_id: 0x00c9},
/// device_filter!{vendor_id: 0x054c},
/// ];
///
/// let device_list = get_device_list(filter).await.expect("Could not find device matching filters");
///
/// /* Do something with the list of devices... */
/// # })
/// ```
pub use crateget_device_list;
/// Macro to create a device filter more easily.
///
/// The only valid keys are fields of the [`DeviceFilter`] struct.
/// You may use as many or as few of them as you need, the rest
/// of the values will be filled with [`None`].
///
/// ## Usage
/// ```
/// use cross_usb::device_filter;
///
/// // Example with all fields filled
/// device_filter!{
/// vendor_id: 0x054c, // u16
/// product_id: 0x0186, // u16
/// class: 0xFF, // u8
/// subclass: 0x02, // u8
/// protocol: 0x15, // u8
/// };
/// ```
compile_error!