1 use libusb1_sys as ffi;
2
3 #[test]
test_version()4 fn test_version() {
5 use std::{ffi::CStr, str};
6 let version = unsafe { &*ffi::libusb_get_version() };
7 let rc = str::from_utf8(unsafe { CStr::from_ptr(version.rc) }.to_bytes()).unwrap_or("");
8 let describe =
9 str::from_utf8(unsafe { CStr::from_ptr(version.describe) }.to_bytes()).unwrap_or("");
10
11 assert_eq!(version.major, 1);
12 assert_eq!(version.minor, 0);
13 println!(
14 "libusb v{}.{}.{}.{}{} {}",
15 version.major, version.minor, version.micro, version.nano, rc, describe
16 );
17 }
18
19 #[test]
test_init_and_exit()20 fn test_init_and_exit() {
21 let mut context: *mut ffi::libusb_context = std::ptr::null_mut();
22 for i in 0..=100 {
23 match unsafe { ffi::libusb_init(&mut context) } {
24 0 => (),
25 err => panic!("Failed to init libusb on iteration {}: {}", i, err),
26 }
27 unsafe {
28 ffi::libusb_exit(context);
29 }
30 #[cfg(target_os = "macos")]
31 std::thread::sleep(std::time::Duration::from_millis(1));
32 context = std::ptr::null_mut();
33 }
34 }
35
36 #[test]
test_get_device_list()37 fn test_get_device_list() {
38 let mut context = std::mem::MaybeUninit::<*mut ffi::libusb_context>::uninit();
39 match unsafe { ffi::libusb_init(context.as_mut_ptr()) } {
40 0 => (),
41 err => panic!("Failed to init libusb {}", err),
42 }
43 let mut list = std::mem::MaybeUninit::<*const *mut ffi::libusb_device>::uninit();
44 let list_size =
45 unsafe { ffi::libusb_get_device_list(context.assume_init(), list.as_mut_ptr()) };
46 if list_size < 0 || unsafe { list.assume_init().is_null() } {
47 panic!("Failed to get device list {} {:p}", -list_size, unsafe {
48 list.assume_init()
49 });
50 }
51 unsafe {
52 ffi::libusb_free_device_list(list.assume_init(), 1);
53 }
54 unsafe {
55 ffi::libusb_exit(context.assume_init());
56 }
57 }
58
59 #[test]
test_fill_control_setup()60 fn test_fill_control_setup() {
61 let mut buf = [0u8; ffi::constants::LIBUSB_CONTROL_SETUP_SIZE + 1];
62 unsafe {
63 ffi::libusb_fill_control_setup(
64 buf.as_mut_ptr(),
65 ffi::constants::LIBUSB_REQUEST_TYPE_VENDOR | ffi::constants::LIBUSB_ENDPOINT_OUT,
66 0x04,
67 0x4e,
68 0,
69 (buf.len() - ffi::constants::LIBUSB_CONTROL_SETUP_SIZE) as u16,
70 );
71 }
72 buf[ffi::constants::LIBUSB_CONTROL_SETUP_SIZE] = 0x01;
73 let setup: *mut ffi::libusb_control_setup = buf.as_mut_ptr() as *mut _;
74
75 assert_eq!(
76 unsafe { (*setup).bmRequestType },
77 ffi::constants::LIBUSB_REQUEST_TYPE_VENDOR | ffi::constants::LIBUSB_ENDPOINT_OUT
78 );
79 assert_eq!(unsafe { (*setup).bRequest }, 0x04);
80 assert_eq!(unsafe { u16::from_le((*setup).wValue) }, 0x4e);
81 assert_eq!(unsafe { u16::from_le((*setup).wIndex) }, 0);
82 assert_eq!(unsafe { u16::from_le((*setup).wLength) }, 1);
83 }
84
85 #[test]
test_fill_control_transfer()86 fn test_fill_control_transfer() {
87 extern "system" fn callback(_transfer: *mut ffi::libusb_transfer) {}
88
89 let mut buf = [0u8; ffi::constants::LIBUSB_CONTROL_SETUP_SIZE + 1];
90 unsafe {
91 ffi::libusb_fill_control_setup(
92 buf.as_mut_ptr(),
93 ffi::constants::LIBUSB_REQUEST_TYPE_VENDOR | ffi::constants::LIBUSB_ENDPOINT_OUT,
94 0x04,
95 0x4e,
96 0,
97 (buf.len() - ffi::constants::LIBUSB_CONTROL_SETUP_SIZE) as u16,
98 );
99 }
100 buf[ffi::constants::LIBUSB_CONTROL_SETUP_SIZE] = 0x05;
101
102 let mut transfer = std::mem::MaybeUninit::<ffi::libusb_transfer>::uninit();
103
104 unsafe {
105 ffi::libusb_fill_control_transfer(
106 transfer.as_mut_ptr(),
107 std::ptr::null_mut(),
108 buf.as_mut_ptr(),
109 callback,
110 std::ptr::null_mut(),
111 1000,
112 );
113 }
114 let transfer = unsafe { &mut transfer.assume_init() };
115 assert_eq!(transfer.endpoint, 0);
116 assert_eq!(
117 transfer.length as usize,
118 ffi::constants::LIBUSB_CONTROL_SETUP_SIZE + 1
119 );
120 assert_eq!(transfer.timeout, 1000);
121 assert_eq!(
122 transfer.transfer_type,
123 ffi::constants::LIBUSB_TRANSFER_TYPE_CONTROL
124 );
125 assert_eq!(transfer.buffer, buf.as_mut_ptr());
126
127 let data = unsafe {
128 std::slice::from_raw_parts(ffi::libusb_control_transfer_get_data(transfer as *mut _), 1)
129 };
130 assert_eq!(data[0], 0x05);
131 }
132
133 #[test]
test_fill_bulk_transfer()134 fn test_fill_bulk_transfer() {
135 extern "system" fn callback(_transfer: *mut ffi::libusb_transfer) {}
136
137 let mut transfer = std::mem::MaybeUninit::<ffi::libusb_transfer>::uninit();
138 let mut buf = [5u8; 64];
139 unsafe {
140 ffi::libusb_fill_bulk_transfer(
141 transfer.as_mut_ptr(),
142 std::ptr::null_mut(),
143 0x80,
144 buf.as_mut_ptr(),
145 buf.len() as libc::c_int,
146 callback,
147 std::ptr::null_mut(),
148 1000,
149 );
150 }
151 let transfer = unsafe { &transfer.assume_init() };
152 assert_eq!(transfer.endpoint, 0x80);
153 assert_eq!(transfer.timeout, 1000);
154 assert_eq!(
155 transfer.transfer_type,
156 ffi::constants::LIBUSB_TRANSFER_TYPE_BULK
157 );
158 assert_eq!(transfer.buffer, buf.as_mut_ptr());
159 assert_eq!(transfer.length, buf.len() as libc::c_int);
160 }
161