1use libc::c_int;
2use libusb::*;
3
4#[derive(Debug,PartialEq,Eq,Clone,Copy,Hash)]
6pub enum Speed {
7 Unknown,
9
10 Low,
12
13 Full,
15
16 High,
18
19 Super,
21}
22
23#[doc(hidden)]
24pub fn speed_from_libusb(n: c_int) -> Speed {
25 match n {
26 LIBUSB_SPEED_SUPER => Speed::Super,
27 LIBUSB_SPEED_HIGH => Speed::High,
28 LIBUSB_SPEED_FULL => Speed::Full,
29 LIBUSB_SPEED_LOW => Speed::Low,
30
31 _ => Speed::Unknown,
32 }
33}
34
35#[derive(Debug,PartialEq,Eq,Clone,Copy,Hash)]
37pub enum Direction {
38 In,
40
41 Out,
43}
44
45#[derive(Debug,PartialEq,Eq,Clone,Copy,Hash)]
47pub enum TransferType {
48 Control,
50
51 Isochronous,
53
54 Bulk,
56
57 Interrupt,
59}
60
61
62#[derive(Debug,PartialEq,Eq,Clone,Copy,Hash)]
64pub enum SyncType {
65 NoSync,
67
68 Asynchronous,
70
71 Adaptive,
73
74 Synchronous,
76}
77
78
79#[derive(Debug,PartialEq,Eq,Clone,Copy,Hash)]
81pub enum UsageType {
82 Data,
84
85 Feedback,
87
88 FeedbackData,
90
91 Reserved,
93}
94
95
96#[derive(Debug,PartialEq,Eq,Clone,Copy,Hash)]
98pub enum RequestType {
99 Standard,
101
102 Class,
104
105 Vendor,
107
108 Reserved,
110}
111
112#[derive(Debug,PartialEq,Eq,Clone,Copy,Hash)]
114pub enum Recipient {
115 Device,
117
118 Interface,
120
121 Endpoint,
123
124 Other,
126}
127
128#[derive(Debug,PartialEq,Eq,Clone,Copy,Hash)]
143pub struct Version(pub u8, pub u8, pub u8);
144
145impl Version {
146 pub fn from_bcd(mut raw: u16) -> Self {
151 let sub_minor: u8 = (raw & 0x000F) as u8;
152 raw >>= 4;
153
154 let minor: u8 = (raw & 0x000F) as u8;
155 raw >>= 4;
156
157 let mut major: u8 = (raw & 0x000F) as u8;
158 raw >>= 4;
159
160 major += (10 * raw) as u8;
161
162 Version(major, minor, sub_minor)
163 }
164
165 pub fn major(self) -> u8 {
167 let Version(major, _, _) = self;
168 major
169 }
170
171 pub fn minor(self) -> u8 {
173 let Version(_, minor, _) = self;
174 minor
175 }
176
177 pub fn sub_minor(self) -> u8 {
179 let Version(_, _, sub_minor) = self;
180 sub_minor
181 }
182}
183
184pub fn request_type(direction: Direction, request_type: RequestType, recipient: Recipient) -> u8 {
200 let mut value: u8 = match direction {
201 Direction::Out => LIBUSB_ENDPOINT_OUT,
202 Direction::In => LIBUSB_ENDPOINT_IN,
203 };
204
205 value |= match request_type {
206 RequestType::Standard => LIBUSB_REQUEST_TYPE_STANDARD,
207 RequestType::Class => LIBUSB_REQUEST_TYPE_CLASS,
208 RequestType::Vendor => LIBUSB_REQUEST_TYPE_VENDOR,
209 RequestType::Reserved => LIBUSB_REQUEST_TYPE_RESERVED,
210 };
211
212 value |= match recipient {
213 Recipient::Device => LIBUSB_RECIPIENT_DEVICE,
214 Recipient::Interface => LIBUSB_RECIPIENT_INTERFACE,
215 Recipient::Endpoint => LIBUSB_RECIPIENT_ENDPOINT,
216 Recipient::Other => LIBUSB_RECIPIENT_OTHER,
217 };
218
219 value
220}
221
222
223#[cfg(test)]
224mod test {
225 use super::*;
226
227 #[test]
230 fn version_returns_major_version() {
231 assert_eq!(1, Version(1, 0, 0).major());
232 assert_eq!(2, Version(2, 0, 0).major());
233 }
234
235 #[test]
236 fn version_returns_minor_version() {
237 assert_eq!(1, Version(0, 1, 0).minor());
238 assert_eq!(2, Version(0, 2, 0).minor());
239 }
240
241 #[test]
242 fn version_returns_sub_minor_version() {
243 assert_eq!(1, Version(0, 0, 1).sub_minor());
244 assert_eq!(2, Version(0, 0, 2).sub_minor());
245 }
246
247 #[test]
248 fn version_parses_major_version() {
249 assert_eq!(3, Version::from_bcd(0x0300).major());
250 }
251
252 #[test]
253 fn version_parses_long_major_version() {
254 assert_eq!(12, Version::from_bcd(0x1200).major());
255 }
256
257 #[test]
258 fn version_parses_minor_version() {
259 assert_eq!(1, Version::from_bcd(0x0010).minor());
260 assert_eq!(2, Version::from_bcd(0x0020).minor());
261 }
262
263 #[test]
264 fn version_parses_sub_minor_version() {
265 assert_eq!(1, Version::from_bcd(0x0001).sub_minor());
266 assert_eq!(2, Version::from_bcd(0x0002).sub_minor());
267 }
268
269 #[test]
270 fn version_parses_full_version() {
271 assert_eq!(Version(12, 3, 4), Version::from_bcd(0x1234));
272 }
273
274 #[test]
277 fn request_type_builds_value_for_out_direction() {
278 assert_eq!(request_type(Direction::Out, RequestType::Standard, Recipient::Device) & 0x80, 0x00);
279 }
280
281 #[test]
282 fn request_type_builds_value_for_in_direction() {
283 assert_eq!(request_type(Direction::In, RequestType::Standard, Recipient::Device) & 0x80, 0x80);
284 }
285
286 #[test]
289 fn request_type_builds_value_for_standard_request() {
290 assert_eq!(request_type(Direction::Out, RequestType::Standard, Recipient::Device) & 0x60, 0x00);
291 }
292
293 #[test]
294 fn request_type_builds_value_for_class_request() {
295 assert_eq!(request_type(Direction::Out, RequestType::Class, Recipient::Device) & 0x60, 0x20);
296 }
297
298 #[test]
299 fn request_type_builds_value_for_vendor_request() {
300 assert_eq!(request_type(Direction::Out, RequestType::Vendor, Recipient::Device) & 0x60, 0x40);
301 }
302
303 #[test]
304 fn request_type_builds_value_for_reserved_request() {
305 assert_eq!(request_type(Direction::Out, RequestType::Reserved, Recipient::Device) & 0x60, 0x60);
306 }
307
308 #[test]
311 fn request_type_builds_value_for_device_recipient() {
312 assert_eq!(request_type(Direction::Out, RequestType::Standard, Recipient::Device) & 0x0F, 0x00);
313 }
314
315 #[test]
316 fn request_type_builds_value_for_interface_recipient() {
317 assert_eq!(request_type(Direction::Out, RequestType::Standard, Recipient::Interface) & 0x0F, 0x01);
318 }
319
320 #[test]
321 fn request_type_builds_value_for_endpoint_recipient() {
322 assert_eq!(request_type(Direction::Out, RequestType::Standard, Recipient::Endpoint) & 0x0F, 0x02);
323 }
324
325 #[test]
326 fn request_type_builds_value_for_other_recipient() {
327 assert_eq!(request_type(Direction::Out, RequestType::Standard, Recipient::Other) & 0x0F, 0x03);
328 }
329}