usb 2.17.0 → 3.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/LICENSE +18 -4
  2. package/README.md +25 -516
  3. package/dist/index.d.ts +67 -13
  4. package/dist/index.js +333 -64
  5. package/index.d.ts +89 -0
  6. package/index.js +583 -0
  7. package/package.json +53 -33
  8. package/CHANGELOG.md +0 -294
  9. package/binding.gyp +0 -128
  10. package/dist/index.js.map +0 -1
  11. package/dist/usb/bindings.d.ts +0 -266
  12. package/dist/usb/bindings.js +0 -10
  13. package/dist/usb/bindings.js.map +0 -1
  14. package/dist/usb/capability.d.ts +0 -13
  15. package/dist/usb/capability.js +0 -17
  16. package/dist/usb/capability.js.map +0 -1
  17. package/dist/usb/descriptors.d.ts +0 -128
  18. package/dist/usb/descriptors.js +0 -3
  19. package/dist/usb/descriptors.js.map +0 -1
  20. package/dist/usb/device.d.ts +0 -100
  21. package/dist/usb/device.js +0 -297
  22. package/dist/usb/device.js.map +0 -1
  23. package/dist/usb/endpoint.d.ts +0 -94
  24. package/dist/usb/endpoint.js +0 -219
  25. package/dist/usb/endpoint.js.map +0 -1
  26. package/dist/usb/index.d.ts +0 -31
  27. package/dist/usb/index.js +0 -116
  28. package/dist/usb/index.js.map +0 -1
  29. package/dist/usb/interface.d.ts +0 -80
  30. package/dist/usb/interface.js +0 -133
  31. package/dist/usb/interface.js.map +0 -1
  32. package/dist/webusb/index.d.ts +0 -64
  33. package/dist/webusb/index.js +0 -295
  34. package/dist/webusb/index.js.map +0 -1
  35. package/dist/webusb/webusb-device.d.ts +0 -54
  36. package/dist/webusb/webusb-device.js +0 -434
  37. package/dist/webusb/webusb-device.js.map +0 -1
  38. package/libusb/.clang-tidy +0 -34
  39. package/libusb/.codespellrc +0 -3
  40. package/libusb/.private/README.txt +0 -5
  41. package/libusb/.private/appveyor_build.sh +0 -26
  42. package/libusb/.private/bm.sh +0 -54
  43. package/libusb/.private/ci-build.sh +0 -92
  44. package/libusb/.private/ci-container-build.sh +0 -67
  45. package/libusb/.private/post-rewrite.sh +0 -32
  46. package/libusb/.private/pre-commit.sh +0 -52
  47. package/libusb/.private/wbs.txt +0 -43
  48. package/libusb/.travis.yml +0 -58
  49. package/libusb/AUTHORS +0 -231
  50. package/libusb/COPYING +0 -504
  51. package/libusb/ChangeLog +0 -365
  52. package/libusb/HACKING +0 -25
  53. package/libusb/INSTALL_WIN.txt +0 -52
  54. package/libusb/KEYS +0 -123
  55. package/libusb/Makefile.am +0 -50
  56. package/libusb/NEWS +0 -2
  57. package/libusb/PORTING +0 -94
  58. package/libusb/README +0 -29
  59. package/libusb/README.git +0 -41
  60. package/libusb/TODO +0 -2
  61. package/libusb/Xcode/common.xcconfig +0 -92
  62. package/libusb/Xcode/config.h +0 -31
  63. package/libusb/Xcode/debug.xcconfig +0 -32
  64. package/libusb/Xcode/libusb.xcconfig +0 -21
  65. package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +0 -1391
  66. package/libusb/Xcode/libusb_debug.xcconfig +0 -21
  67. package/libusb/Xcode/libusb_release.xcconfig +0 -21
  68. package/libusb/Xcode/release.xcconfig +0 -30
  69. package/libusb/android/README +0 -152
  70. package/libusb/android/config.h +0 -55
  71. package/libusb/android/examples/unrooted_android.c +0 -301
  72. package/libusb/android/examples/unrooted_android.h +0 -36
  73. package/libusb/android/jni/Android.mk +0 -23
  74. package/libusb/android/jni/Application.mk +0 -40
  75. package/libusb/android/jni/examples.mk +0 -168
  76. package/libusb/android/jni/libusb.mk +0 -60
  77. package/libusb/android/jni/tests.mk +0 -45
  78. package/libusb/appveyor.yml +0 -108
  79. package/libusb/autogen.sh +0 -10
  80. package/libusb/bootstrap.sh +0 -10
  81. package/libusb/configure.ac +0 -450
  82. package/libusb/doc/Makefile.in +0 -22
  83. package/libusb/doc/doxygen.cfg.in +0 -2571
  84. package/libusb/doc/libusb.png +0 -0
  85. package/libusb/examples/Makefile.am +0 -12
  86. package/libusb/examples/dpfp.c +0 -711
  87. package/libusb/examples/ezusb.c +0 -846
  88. package/libusb/examples/ezusb.h +0 -109
  89. package/libusb/examples/fxload.c +0 -310
  90. package/libusb/examples/hotplugtest.c +0 -147
  91. package/libusb/examples/listdevs.c +0 -73
  92. package/libusb/examples/sam3u_benchmark.c +0 -228
  93. package/libusb/examples/testlibusb.c +0 -312
  94. package/libusb/examples/xusb.c +0 -1254
  95. package/libusb/libusb/Makefile.am +0 -98
  96. package/libusb/libusb/Makefile.am.extra +0 -26
  97. package/libusb/libusb/core.c +0 -2925
  98. package/libusb/libusb/descriptor.c +0 -1558
  99. package/libusb/libusb/hotplug.c +0 -489
  100. package/libusb/libusb/io.c +0 -2865
  101. package/libusb/libusb/libusb-1.0.def +0 -199
  102. package/libusb/libusb/libusb-1.0.rc +0 -53
  103. package/libusb/libusb/libusb.h +0 -2421
  104. package/libusb/libusb/libusbi.h +0 -1535
  105. package/libusb/libusb/os/darwin_usb.c +0 -2977
  106. package/libusb/libusb/os/darwin_usb.h +0 -156
  107. package/libusb/libusb/os/emscripten_webusb.cpp +0 -875
  108. package/libusb/libusb/os/events_posix.c +0 -340
  109. package/libusb/libusb/os/events_posix.h +0 -62
  110. package/libusb/libusb/os/events_windows.c +0 -214
  111. package/libusb/libusb/os/events_windows.h +0 -46
  112. package/libusb/libusb/os/haiku_pollfs.cpp +0 -372
  113. package/libusb/libusb/os/haiku_usb.h +0 -113
  114. package/libusb/libusb/os/haiku_usb_backend.cpp +0 -532
  115. package/libusb/libusb/os/haiku_usb_raw.cpp +0 -231
  116. package/libusb/libusb/os/haiku_usb_raw.h +0 -188
  117. package/libusb/libusb/os/linux_netlink.c +0 -401
  118. package/libusb/libusb/os/linux_udev.c +0 -321
  119. package/libusb/libusb/os/linux_usbfs.c +0 -2829
  120. package/libusb/libusb/os/linux_usbfs.h +0 -221
  121. package/libusb/libusb/os/netbsd_usb.c +0 -617
  122. package/libusb/libusb/os/null_usb.c +0 -111
  123. package/libusb/libusb/os/openbsd_usb.c +0 -700
  124. package/libusb/libusb/os/sunos_usb.c +0 -1619
  125. package/libusb/libusb/os/sunos_usb.h +0 -79
  126. package/libusb/libusb/os/threads_posix.c +0 -126
  127. package/libusb/libusb/os/threads_posix.h +0 -98
  128. package/libusb/libusb/os/threads_windows.c +0 -40
  129. package/libusb/libusb/os/threads_windows.h +0 -113
  130. package/libusb/libusb/os/windows_common.c +0 -923
  131. package/libusb/libusb/os/windows_common.h +0 -424
  132. package/libusb/libusb/os/windows_usbdk.c +0 -724
  133. package/libusb/libusb/os/windows_usbdk.h +0 -106
  134. package/libusb/libusb/os/windows_winusb.c +0 -4766
  135. package/libusb/libusb/os/windows_winusb.h +0 -787
  136. package/libusb/libusb/strerror.c +0 -223
  137. package/libusb/libusb/sync.c +0 -342
  138. package/libusb/libusb/version.h +0 -18
  139. package/libusb/libusb/version_nano.h +0 -1
  140. package/libusb/libusb-1.0.pc.in +0 -11
  141. package/libusb/msvc/Base.props +0 -60
  142. package/libusb/msvc/Configuration.Application.props +0 -7
  143. package/libusb/msvc/Configuration.Base.props +0 -47
  144. package/libusb/msvc/Configuration.DynamicLibrary.props +0 -21
  145. package/libusb/msvc/Configuration.StaticLibrary.props +0 -7
  146. package/libusb/msvc/ProjectConfigurations.Base.props +0 -69
  147. package/libusb/msvc/build_all.ps1 +0 -17
  148. package/libusb/msvc/config.h +0 -58
  149. package/libusb/msvc/dpfp.vcxproj +0 -33
  150. package/libusb/msvc/dpfp_threaded.vcxproj +0 -38
  151. package/libusb/msvc/fxload.vcxproj +0 -46
  152. package/libusb/msvc/getopt/getopt.c +0 -1060
  153. package/libusb/msvc/getopt/getopt.h +0 -180
  154. package/libusb/msvc/getopt/getopt1.c +0 -188
  155. package/libusb/msvc/getopt.vcxproj +0 -33
  156. package/libusb/msvc/hotplugtest.vcxproj +0 -32
  157. package/libusb/msvc/init_context.vcxproj +0 -35
  158. package/libusb/msvc/libusb.sln +0 -542
  159. package/libusb/msvc/libusb_dll.vcxproj +0 -61
  160. package/libusb/msvc/libusb_static.vcxproj +0 -49
  161. package/libusb/msvc/listdevs.vcxproj +0 -32
  162. package/libusb/msvc/sam3u_benchmark.vcxproj +0 -33
  163. package/libusb/msvc/set_option.vcxproj +0 -35
  164. package/libusb/msvc/stress.vcxproj +0 -35
  165. package/libusb/msvc/stress_mt.vcxproj +0 -33
  166. package/libusb/msvc/testlibusb.vcxproj +0 -32
  167. package/libusb/msvc/xusb.vcxproj +0 -38
  168. package/libusb/tests/Makefile.am +0 -40
  169. package/libusb/tests/init_context.c +0 -153
  170. package/libusb/tests/libusb_testlib.h +0 -76
  171. package/libusb/tests/macos.c +0 -130
  172. package/libusb/tests/set_option.c +0 -253
  173. package/libusb/tests/stress.c +0 -172
  174. package/libusb/tests/stress_mt.c +0 -267
  175. package/libusb/tests/testlib.c +0 -184
  176. package/libusb/tests/umockdev.c +0 -1175
  177. package/libusb/tests/webusb-test-shim/index.js +0 -12
  178. package/libusb/tests/webusb-test-shim/package-lock.json +0 -50
  179. package/libusb/tests/webusb-test-shim/package.json +0 -10
  180. package/libusb.gypi +0 -154
  181. package/libusb_config/config.h +0 -1
  182. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  183. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  184. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  185. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  186. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  187. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  188. package/prebuilds/linux-ia32/node.napi.node +0 -0
  189. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  190. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  191. package/prebuilds/win32-arm64/node.napi.node +0 -0
  192. package/prebuilds/win32-ia32/node.napi.node +0 -0
  193. package/prebuilds/win32-x64/node.napi.node +0 -0
  194. package/src/device.cc +0 -439
  195. package/src/helpers.h +0 -64
  196. package/src/hotplug/hotplug.h +0 -22
  197. package/src/hotplug/libusb.cc +0 -90
  198. package/src/hotplug/windows.cc +0 -168
  199. package/src/node_usb.cc +0 -314
  200. package/src/node_usb.h +0 -131
  201. package/src/thread_name.cc +0 -79
  202. package/src/thread_name.h +0 -11
  203. package/src/transfer.cc +0 -143
  204. package/src/uv_async_queue.h +0 -41
  205. package/test/usb.coffee +0 -250
  206. package/test/webusb.coffee +0 -227
  207. package/test/worker.cjs +0 -13
@@ -1,1254 +0,0 @@
1
- /*
2
- * xusb: Generic USB test program
3
- * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4
- * Contributions to Mass Storage by Alan Stern.
5
- *
6
- * This library is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU Lesser General Public
8
- * License as published by the Free Software Foundation; either
9
- * version 2.1 of the License, or (at your option) any later version.
10
- *
11
- * This library is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- * Lesser General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU Lesser General Public
17
- * License along with this library; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
- */
20
-
21
- #include <stdarg.h>
22
- #include <stdbool.h>
23
- #include <stdio.h>
24
- #include <stdint.h>
25
- #include <stdlib.h>
26
- #include <string.h>
27
- #include <time.h>
28
-
29
- #include "libusb.h"
30
-
31
- #if defined(_MSC_VER)
32
- #define snprintf _snprintf
33
- #define putenv _putenv
34
- #endif
35
-
36
- // Future versions of libusb will use usb_interface instead of interface
37
- // in libusb_config_descriptor => catter for that
38
- #define usb_interface interface
39
-
40
- #ifndef ARRAYSIZE
41
- #define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
42
- #endif
43
-
44
- // Global variables
45
- static bool binary_dump = false;
46
- static bool extra_info = false;
47
- static bool force_device_request = false; // For WCID descriptor queries
48
- static const char* binary_name = NULL;
49
-
50
- static inline void msleep(int msecs)
51
- {
52
- #if defined(_WIN32)
53
- Sleep(msecs);
54
- #else
55
- const struct timespec ts = { msecs / 1000, (msecs % 1000) * 1000000L };
56
- nanosleep(&ts, NULL);
57
- #endif
58
- }
59
-
60
- static void perr(char const *format, ...)
61
- {
62
- va_list args;
63
-
64
- va_start (args, format);
65
- vfprintf(stderr, format, args);
66
- va_end(args);
67
- }
68
-
69
- #define ERR_EXIT(errcode) do { perr(" %s\n", libusb_strerror((enum libusb_error)(errcode))); return -1; } while (0)
70
- #define CALL_CHECK(fcall) do { int _r=fcall; if (_r < 0) ERR_EXIT(_r); } while (0)
71
- #define CALL_CHECK_CLOSE(fcall, hdl) do { int _r=fcall; if (_r < 0) { libusb_close(hdl); ERR_EXIT(_r); } } while (0)
72
- #define B(x) (((x)!=0)?1:0)
73
- #define be_to_int32(buf) (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|(buf)[3])
74
-
75
- #define RETRY_MAX 5
76
- #define REQUEST_SENSE_LENGTH 0x12
77
- #define INQUIRY_LENGTH 0x24
78
- #define READ_CAPACITY_LENGTH 0x08
79
-
80
- // HID Class-Specific Requests values. See section 7.2 of the HID specifications
81
- #define HID_GET_REPORT 0x01
82
- #define HID_GET_IDLE 0x02
83
- #define HID_GET_PROTOCOL 0x03
84
- #define HID_SET_REPORT 0x09
85
- #define HID_SET_IDLE 0x0A
86
- #define HID_SET_PROTOCOL 0x0B
87
- #define HID_REPORT_TYPE_INPUT 0x01
88
- #define HID_REPORT_TYPE_OUTPUT 0x02
89
- #define HID_REPORT_TYPE_FEATURE 0x03
90
-
91
- // Mass Storage Requests values. See section 3 of the Bulk-Only Mass Storage Class specifications
92
- #define BOMS_RESET 0xFF
93
- #define BOMS_GET_MAX_LUN 0xFE
94
-
95
- // Microsoft OS Descriptor
96
- #define MS_OS_DESC_STRING_INDEX 0xEE
97
- #define MS_OS_DESC_STRING_LENGTH 0x12
98
- #define MS_OS_DESC_VENDOR_CODE_OFFSET 0x10
99
- static const uint8_t ms_os_desc_string[] = {
100
- MS_OS_DESC_STRING_LENGTH,
101
- LIBUSB_DT_STRING,
102
- 'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0,
103
- };
104
-
105
- // Section 5.1: Command Block Wrapper (CBW)
106
- struct command_block_wrapper {
107
- uint8_t dCBWSignature[4];
108
- uint32_t dCBWTag;
109
- uint32_t dCBWDataTransferLength;
110
- uint8_t bmCBWFlags;
111
- uint8_t bCBWLUN;
112
- uint8_t bCBWCBLength;
113
- uint8_t CBWCB[16];
114
- };
115
-
116
- // Section 5.2: Command Status Wrapper (CSW)
117
- struct command_status_wrapper {
118
- uint8_t dCSWSignature[4];
119
- uint32_t dCSWTag;
120
- uint32_t dCSWDataResidue;
121
- uint8_t bCSWStatus;
122
- };
123
-
124
- static const uint8_t cdb_length[256] = {
125
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
126
- 06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06, // 0
127
- 06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06, // 1
128
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 2
129
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 3
130
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 4
131
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 5
132
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // 6
133
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // 7
134
- 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, // 8
135
- 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, // 9
136
- 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // A
137
- 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // B
138
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // C
139
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // D
140
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // E
141
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // F
142
- };
143
-
144
- static enum test_type {
145
- USE_GENERIC,
146
- USE_PS3,
147
- USE_XBOX,
148
- USE_SCSI,
149
- USE_HID,
150
- } test_mode;
151
- static uint16_t VID, PID;
152
-
153
- static void display_buffer_hex(unsigned char *buffer, unsigned size)
154
- {
155
- unsigned i, j, k;
156
-
157
- for (i=0; i<size; i+=16) {
158
- printf("\n %08x ", i);
159
- for(j=0,k=0; k<16; j++,k++) {
160
- if (i+j < size) {
161
- printf("%02x", buffer[i+j]);
162
- } else {
163
- printf(" ");
164
- }
165
- printf(" ");
166
- }
167
- printf(" ");
168
- for(j=0,k=0; k<16; j++,k++) {
169
- if (i+j < size) {
170
- if ((buffer[i+j] < 32) || (buffer[i+j] > 126)) {
171
- printf(".");
172
- } else {
173
- printf("%c", buffer[i+j]);
174
- }
175
- }
176
- }
177
- }
178
- printf("\n" );
179
- }
180
-
181
- static char* uuid_to_string(const uint8_t* uuid)
182
- {
183
- static char uuid_string[40];
184
- if (uuid == NULL) return NULL;
185
- snprintf(uuid_string, sizeof(uuid_string),
186
- "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
187
- uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
188
- uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
189
- return uuid_string;
190
- }
191
-
192
- // The PS3 Controller is really a HID device that got its HID Report Descriptors
193
- // removed by Sony
194
- static int display_ps3_status(libusb_device_handle *handle)
195
- {
196
- uint8_t input_report[49];
197
- uint8_t master_bt_address[8];
198
- uint8_t device_bt_address[18];
199
-
200
- // Get the controller's bluetooth address of its master device
201
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
202
- HID_GET_REPORT, 0x03f5, 0, master_bt_address, sizeof(master_bt_address), 100));
203
- printf("\nMaster's bluetooth address: %02X:%02X:%02X:%02X:%02X:%02X\n", master_bt_address[2], master_bt_address[3],
204
- master_bt_address[4], master_bt_address[5], master_bt_address[6], master_bt_address[7]);
205
-
206
- // Get the controller's bluetooth address
207
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
208
- HID_GET_REPORT, 0x03f2, 0, device_bt_address, sizeof(device_bt_address), 100));
209
- printf("\nMaster's bluetooth address: %02X:%02X:%02X:%02X:%02X:%02X\n", device_bt_address[4], device_bt_address[5],
210
- device_bt_address[6], device_bt_address[7], device_bt_address[8], device_bt_address[9]);
211
-
212
- // Get the status of the controller's buttons via its HID report
213
- printf("\nReading PS3 Input Report...\n");
214
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
215
- HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x01, 0, input_report, sizeof(input_report), 1000));
216
- switch(input_report[2]){ /** Direction pad plus start, select, and joystick buttons */
217
- case 0x01:
218
- printf("\tSELECT pressed\n");
219
- break;
220
- case 0x02:
221
- printf("\tLEFT 3 pressed\n");
222
- break;
223
- case 0x04:
224
- printf("\tRIGHT 3 pressed\n");
225
- break;
226
- case 0x08:
227
- printf("\tSTART pressed\n");
228
- break;
229
- case 0x10:
230
- printf("\tUP pressed\n");
231
- break;
232
- case 0x20:
233
- printf("\tRIGHT pressed\n");
234
- break;
235
- case 0x40:
236
- printf("\tDOWN pressed\n");
237
- break;
238
- case 0x80:
239
- printf("\tLEFT pressed\n");
240
- break;
241
- }
242
- switch(input_report[3]){ /** Shapes plus top right and left buttons */
243
- case 0x01:
244
- printf("\tLEFT 2 pressed\n");
245
- break;
246
- case 0x02:
247
- printf("\tRIGHT 2 pressed\n");
248
- break;
249
- case 0x04:
250
- printf("\tLEFT 1 pressed\n");
251
- break;
252
- case 0x08:
253
- printf("\tRIGHT 1 pressed\n");
254
- break;
255
- case 0x10:
256
- printf("\tTRIANGLE pressed\n");
257
- break;
258
- case 0x20:
259
- printf("\tCIRCLE pressed\n");
260
- break;
261
- case 0x40:
262
- printf("\tCROSS pressed\n");
263
- break;
264
- case 0x80:
265
- printf("\tSQUARE pressed\n");
266
- break;
267
- }
268
- printf("\tPS button: %d\n", input_report[4]);
269
- printf("\tLeft Analog (X,Y): (%d,%d)\n", input_report[6], input_report[7]);
270
- printf("\tRight Analog (X,Y): (%d,%d)\n", input_report[8], input_report[9]);
271
- printf("\tL2 Value: %d\tR2 Value: %d\n", input_report[18], input_report[19]);
272
- printf("\tL1 Value: %d\tR1 Value: %d\n", input_report[20], input_report[21]);
273
- printf("\tRoll (x axis): %d Yaw (y axis): %d Pitch (z axis) %d\n",
274
- //(((input_report[42] + 128) % 256) - 128),
275
- (int8_t)(input_report[42]),
276
- (int8_t)(input_report[44]),
277
- (int8_t)(input_report[46]));
278
- printf("\tAcceleration: %d\n\n", (int8_t)(input_report[48]));
279
- return 0;
280
- }
281
- // The XBOX Controller is really a HID device that got its HID Report Descriptors
282
- // removed by Microsoft.
283
- // Input/Output reports described at http://euc.jp/periphs/xbox-controller.ja.html
284
- static int display_xbox_status(libusb_device_handle *handle)
285
- {
286
- uint8_t input_report[20];
287
- printf("\nReading XBox Input Report...\n");
288
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
289
- HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, input_report, 20, 1000));
290
- printf(" D-pad: %02X\n", input_report[2]&0x0F);
291
- printf(" Start:%d, Back:%d, Left Stick Press:%d, Right Stick Press:%d\n", B(input_report[2]&0x10), B(input_report[2]&0x20),
292
- B(input_report[2]&0x40), B(input_report[2]&0x80));
293
- // A, B, X, Y, Black, White are pressure sensitive
294
- printf(" A:%d, B:%d, X:%d, Y:%d, White:%d, Black:%d\n", input_report[4], input_report[5],
295
- input_report[6], input_report[7], input_report[9], input_report[8]);
296
- printf(" Left Trigger: %d, Right Trigger: %d\n", input_report[10], input_report[11]);
297
- printf(" Left Analog (X,Y): (%d,%d)\n", (int16_t)((input_report[13]<<8)|input_report[12]),
298
- (int16_t)((input_report[15]<<8)|input_report[14]));
299
- printf(" Right Analog (X,Y): (%d,%d)\n", (int16_t)((input_report[17]<<8)|input_report[16]),
300
- (int16_t)((input_report[19]<<8)|input_report[18]));
301
- return 0;
302
- }
303
-
304
- static int set_xbox_actuators(libusb_device_handle *handle, uint8_t left, uint8_t right)
305
- {
306
- uint8_t output_report[6];
307
-
308
- printf("\nWriting XBox Controller Output Report...\n");
309
-
310
- memset(output_report, 0, sizeof(output_report));
311
- output_report[1] = sizeof(output_report);
312
- output_report[3] = left;
313
- output_report[5] = right;
314
-
315
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
316
- HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT<<8)|0x00, 0, output_report, 06, 1000));
317
- return 0;
318
- }
319
-
320
- static int send_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint, uint8_t lun,
321
- uint8_t *cdb, uint8_t direction, int data_length, uint32_t *ret_tag)
322
- {
323
- static uint32_t tag = 1;
324
- uint8_t cdb_len;
325
- int i, r, size;
326
- struct command_block_wrapper cbw;
327
-
328
- if (cdb == NULL) {
329
- return -1;
330
- }
331
-
332
- if (endpoint & LIBUSB_ENDPOINT_IN) {
333
- perr("send_mass_storage_command: cannot send command on IN endpoint\n");
334
- return -1;
335
- }
336
-
337
- cdb_len = cdb_length[cdb[0]];
338
- if ((cdb_len == 0) || (cdb_len > sizeof(cbw.CBWCB))) {
339
- perr("send_mass_storage_command: don't know how to handle this command (%02X, length %d)\n",
340
- cdb[0], cdb_len);
341
- return -1;
342
- }
343
-
344
- memset(&cbw, 0, sizeof(cbw));
345
- cbw.dCBWSignature[0] = 'U';
346
- cbw.dCBWSignature[1] = 'S';
347
- cbw.dCBWSignature[2] = 'B';
348
- cbw.dCBWSignature[3] = 'C';
349
- *ret_tag = tag;
350
- cbw.dCBWTag = tag++;
351
- cbw.dCBWDataTransferLength = data_length;
352
- cbw.bmCBWFlags = direction;
353
- cbw.bCBWLUN = lun;
354
- // Subclass is 1 or 6 => cdb_len
355
- cbw.bCBWCBLength = cdb_len;
356
- memcpy(cbw.CBWCB, cdb, cdb_len);
357
-
358
- i = 0;
359
- do {
360
- // The transfer length must always be exactly 31 bytes.
361
- r = libusb_bulk_transfer(handle, endpoint, (unsigned char*)&cbw, 31, &size, 1000);
362
- if (r == LIBUSB_ERROR_PIPE) {
363
- libusb_clear_halt(handle, endpoint);
364
- }
365
- i++;
366
- } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
367
- if (r != LIBUSB_SUCCESS) {
368
- perr(" send_mass_storage_command: %s\n", libusb_strerror((enum libusb_error)r));
369
- return -1;
370
- }
371
-
372
- printf(" sent %d CDB bytes\n", cdb_len);
373
- return 0;
374
- }
375
-
376
- static int get_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t expected_tag)
377
- {
378
- int i, r, size;
379
- struct command_status_wrapper csw;
380
-
381
- // The device is allowed to STALL this transfer. If it does, you have to
382
- // clear the stall and try again.
383
- i = 0;
384
- do {
385
- r = libusb_bulk_transfer(handle, endpoint, (unsigned char*)&csw, 13, &size, 1000);
386
- if (r == LIBUSB_ERROR_PIPE) {
387
- libusb_clear_halt(handle, endpoint);
388
- }
389
- i++;
390
- } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
391
- if (r != LIBUSB_SUCCESS) {
392
- perr(" get_mass_storage_status: %s\n", libusb_strerror((enum libusb_error)r));
393
- return -1;
394
- }
395
- if (size != 13) {
396
- perr(" get_mass_storage_status: received %d bytes (expected 13)\n", size);
397
- return -1;
398
- }
399
- if (csw.dCSWTag != expected_tag) {
400
- perr(" get_mass_storage_status: mismatched tags (expected %08X, received %08X)\n",
401
- expected_tag, csw.dCSWTag);
402
- return -1;
403
- }
404
- // For this test, we ignore the dCSWSignature check for validity...
405
- printf(" Mass Storage Status: %02X (%s)\n", csw.bCSWStatus, csw.bCSWStatus?"FAILED":"Success");
406
- if (csw.dCSWTag != expected_tag)
407
- return -1;
408
- if (csw.bCSWStatus) {
409
- // REQUEST SENSE is appropriate only if bCSWStatus is 1, meaning that the
410
- // command failed somehow. Larger values (2 in particular) mean that
411
- // the command couldn't be understood.
412
- if (csw.bCSWStatus == 1)
413
- return -2; // request Get Sense
414
- else
415
- return -1;
416
- }
417
-
418
- // In theory we also should check dCSWDataResidue. But lots of devices
419
- // set it wrongly.
420
- return 0;
421
- }
422
-
423
- static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out)
424
- {
425
- uint8_t cdb[16]; // SCSI Command Descriptor Block
426
- uint8_t sense[18];
427
- uint32_t expected_tag;
428
- int size;
429
- int rc;
430
-
431
- // Request Sense
432
- printf("Request Sense:\n");
433
- memset(sense, 0, sizeof(sense));
434
- memset(cdb, 0, sizeof(cdb));
435
- cdb[0] = 0x03; // Request Sense
436
- cdb[4] = REQUEST_SENSE_LENGTH;
437
-
438
- send_mass_storage_command(handle, endpoint_out, 0, cdb, LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH, &expected_tag);
439
- rc = libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&sense, REQUEST_SENSE_LENGTH, &size, 1000);
440
- if (rc < 0)
441
- {
442
- printf("libusb_bulk_transfer failed: %s\n", libusb_error_name(rc));
443
- return;
444
- }
445
- printf(" received %d bytes\n", size);
446
-
447
- if ((sense[0] != 0x70) && (sense[0] != 0x71)) {
448
- perr(" ERROR No sense data\n");
449
- } else {
450
- perr(" ERROR Sense: %02X %02X %02X\n", sense[2]&0x0F, sense[12], sense[13]);
451
- }
452
- // Strictly speaking, the get_mass_storage_status() call should come
453
- // before these perr() lines. If the status is nonzero then we must
454
- // assume there's no data in the buffer. For xusb it doesn't matter.
455
- get_mass_storage_status(handle, endpoint_in, expected_tag);
456
- }
457
-
458
- // Mass Storage device to test bulk transfers (non destructive test)
459
- static int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out)
460
- {
461
- int r, size;
462
- uint8_t lun;
463
- uint32_t expected_tag;
464
- uint32_t i, max_lba, block_size;
465
- double device_size;
466
- uint8_t cdb[16]; // SCSI Command Descriptor Block
467
- uint8_t buffer[64];
468
- unsigned char vid[9], pid[9], rev[5];
469
- unsigned char *data;
470
- FILE *fd;
471
-
472
- printf("\nReading Max LUN:\n");
473
- r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
474
- BOMS_GET_MAX_LUN, 0, 0, &lun, 1, 1000);
475
- // Some devices send a STALL instead of the actual value.
476
- // In such cases we should set lun to 0.
477
- if (r == LIBUSB_ERROR_PIPE) {
478
- lun = 0;
479
- printf(" Stalled, setting Max LUN to 0\n");
480
- } else if (r < 0) {
481
- perr(" Failed.\n");
482
- return r;
483
- } else {
484
- printf(" Max LUN = %d\n", lun);
485
- }
486
-
487
- // Send Inquiry
488
- printf("\nSending Inquiry:\n");
489
- memset(buffer, 0, sizeof(buffer));
490
- memset(cdb, 0, sizeof(cdb));
491
- cdb[0] = 0x12; // Inquiry
492
- cdb[4] = INQUIRY_LENGTH;
493
-
494
- send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, INQUIRY_LENGTH, &expected_tag);
495
- CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, INQUIRY_LENGTH, &size, 1000));
496
- printf(" received %d bytes\n", size);
497
- // The following strings are not zero terminated
498
- for (i=0; i<8; i++) {
499
- vid[i] = buffer[8+i];
500
- pid[i] = buffer[16+i];
501
- rev[i/2] = buffer[32+i/2]; // instead of another loop
502
- }
503
- vid[8] = 0;
504
- pid[8] = 0;
505
- rev[4] = 0;
506
- printf(" VID:PID:REV \"%8s\":\"%8s\":\"%4s\"\n", vid, pid, rev);
507
- if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
508
- get_sense(handle, endpoint_in, endpoint_out);
509
- }
510
-
511
- // Read capacity
512
- printf("\nReading Capacity:\n");
513
- memset(buffer, 0, sizeof(buffer));
514
- memset(cdb, 0, sizeof(cdb));
515
- cdb[0] = 0x25; // Read Capacity
516
-
517
- send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, READ_CAPACITY_LENGTH, &expected_tag);
518
- CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, READ_CAPACITY_LENGTH, &size, 1000));
519
- printf(" received %d bytes\n", size);
520
- max_lba = be_to_int32(&buffer[0]);
521
- block_size = be_to_int32(&buffer[4]);
522
- device_size = ((double)(max_lba+1))*block_size/(1024*1024*1024);
523
- printf(" Max LBA: %08X, Block Size: %08X (%.2f GB)\n", max_lba, block_size, device_size);
524
- if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
525
- get_sense(handle, endpoint_in, endpoint_out);
526
- }
527
-
528
- // coverity[tainted_data]
529
- data = (unsigned char*) calloc(1, block_size);
530
- if (data == NULL) {
531
- perr(" unable to allocate data buffer\n");
532
- return -1;
533
- }
534
-
535
- // Send Read
536
- printf("\nAttempting to read %u bytes:\n", block_size);
537
- memset(cdb, 0, sizeof(cdb));
538
-
539
- cdb[0] = 0x28; // Read(10)
540
- cdb[8] = 0x01; // 1 block
541
-
542
- send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, block_size, &expected_tag);
543
- libusb_bulk_transfer(handle, endpoint_in, data, block_size, &size, 5000);
544
- printf(" READ: received %d bytes\n", size);
545
- if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
546
- get_sense(handle, endpoint_in, endpoint_out);
547
- } else {
548
- display_buffer_hex(data, size);
549
- if (binary_dump) {
550
- fd = fopen(binary_name, "w");
551
- if (fd != NULL) {
552
- if (fwrite(data, 1, (size_t)size, fd) != (unsigned int)size) {
553
- perr(" unable to write binary data\n");
554
- }
555
- fclose(fd);
556
- }
557
- }
558
- }
559
- free(data);
560
-
561
- return 0;
562
- }
563
-
564
- // HID
565
- static int get_hid_record_size(const uint8_t *hid_report_descriptor, int size, int type)
566
- {
567
- uint8_t j = 0;
568
- uint8_t offset;
569
- int record_size[3] = {0, 0, 0};
570
- unsigned int nb_bits = 0, nb_items = 0;
571
- bool found_record_marker;
572
-
573
- found_record_marker = false;
574
- for (int i = hid_report_descriptor[0]+1; i < size; i += offset) {
575
- offset = (hid_report_descriptor[i]&0x03) + 1;
576
- if (offset == 4)
577
- offset = 5;
578
- switch (hid_report_descriptor[i] & 0xFC) {
579
- case 0x74: // bitsize
580
- nb_bits = hid_report_descriptor[i+1];
581
- break;
582
- case 0x94: // count
583
- nb_items = 0;
584
- for (j=1; j<offset; j++) {
585
- nb_items = ((unsigned int)hid_report_descriptor[i+j]) << (8U*(j-1U));
586
- }
587
- break;
588
- case 0x80: // input
589
- found_record_marker = true;
590
- j = 0;
591
- break;
592
- case 0x90: // output
593
- found_record_marker = true;
594
- j = 1;
595
- break;
596
- case 0xb0: // feature
597
- found_record_marker = true;
598
- j = 2;
599
- break;
600
- case 0xC0: // end of collection
601
- nb_items = 0;
602
- nb_bits = 0;
603
- break;
604
- default:
605
- continue;
606
- }
607
- if (found_record_marker) {
608
- found_record_marker = false;
609
- record_size[j] += nb_items*nb_bits;
610
- }
611
- }
612
- if ((type < HID_REPORT_TYPE_INPUT) || (type > HID_REPORT_TYPE_FEATURE)) {
613
- return 0;
614
- } else {
615
- return (record_size[type - HID_REPORT_TYPE_INPUT]+7)/8;
616
- }
617
- }
618
-
619
- static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
620
- {
621
- int r, size, descriptor_size;
622
- uint8_t hid_report_descriptor[256];
623
- uint8_t *report_buffer;
624
- FILE *fd;
625
-
626
- printf("\nReading HID Report Descriptors:\n");
627
- descriptor_size = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_STANDARD|LIBUSB_RECIPIENT_INTERFACE,
628
- LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_REPORT<<8, 0, hid_report_descriptor, sizeof(hid_report_descriptor), 1000);
629
- if (descriptor_size < 0) {
630
- printf(" Failed\n");
631
- return -1;
632
- }
633
- display_buffer_hex(hid_report_descriptor, (unsigned int)descriptor_size);
634
- if (binary_dump) {
635
- fd = fopen(binary_name, "w");
636
- if (fd != NULL) {
637
- if (fwrite(hid_report_descriptor, 1, (size_t)descriptor_size, fd) != (size_t)descriptor_size) {
638
- printf(" Error writing descriptor to file\n");
639
- }
640
- fclose(fd);
641
- }
642
- }
643
-
644
- size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_FEATURE);
645
- if (size <= 0) {
646
- printf("\nSkipping Feature Report readout (None detected)\n");
647
- } else if (size > UINT16_MAX) {
648
- printf("\nSkipping Feature Report readout (bigger than UINT16_MAX)\n");
649
- } else {
650
- report_buffer = (uint8_t*) calloc(1, (size_t)size);
651
- if (report_buffer == NULL) {
652
- return -1;
653
- }
654
-
655
- printf("\nReading Feature Report (length %d)...\n", size);
656
- r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
657
- HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, report_buffer, (uint16_t)size, 5000);
658
- if (r >= 0) {
659
- display_buffer_hex(report_buffer, (unsigned int)size);
660
- } else {
661
- switch(r) {
662
- case LIBUSB_ERROR_NOT_FOUND:
663
- printf(" No Feature Report available for this device\n");
664
- break;
665
- case LIBUSB_ERROR_PIPE:
666
- printf(" Detected stall - resetting pipe...\n");
667
- libusb_clear_halt(handle, 0);
668
- break;
669
- default:
670
- printf(" Error: %s\n", libusb_strerror((enum libusb_error)r));
671
- break;
672
- }
673
- }
674
- free(report_buffer);
675
- }
676
-
677
- size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_INPUT);
678
- if (size <= 0) {
679
- printf("\nSkipping Input Report readout (None detected)\n");
680
- } else if (size > UINT16_MAX) {
681
- printf("\nSkipping Input Report readout (bigger than UINT16_MAX)\n");
682
- } else {
683
- report_buffer = (uint8_t*) calloc(1, (size_t)size);
684
- if (report_buffer == NULL) {
685
- return -1;
686
- }
687
-
688
- printf("\nReading Input Report (length %d)...\n", size);
689
- r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
690
- HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, report_buffer, (uint16_t)size, 5000);
691
- if (r >= 0) {
692
- display_buffer_hex(report_buffer, (unsigned int)size);
693
- } else {
694
- switch(r) {
695
- case LIBUSB_ERROR_TIMEOUT:
696
- printf(" Timeout! Please make sure you act on the device within the 5 seconds allocated...\n");
697
- break;
698
- case LIBUSB_ERROR_PIPE:
699
- printf(" Detected stall - resetting pipe...\n");
700
- libusb_clear_halt(handle, 0);
701
- break;
702
- default:
703
- printf(" Error: %s\n", libusb_strerror((enum libusb_error)r));
704
- break;
705
- }
706
- }
707
-
708
- // Attempt a bulk read from endpoint 0 (this should just return a raw input report)
709
- printf("\nTesting interrupt read using endpoint %02X...\n", endpoint_in);
710
- r = libusb_interrupt_transfer(handle, endpoint_in, report_buffer, size, &size, 5000);
711
- if (r >= 0) {
712
- display_buffer_hex(report_buffer, (unsigned int)size);
713
- } else {
714
- printf(" %s\n", libusb_strerror((enum libusb_error)r));
715
- }
716
-
717
- free(report_buffer);
718
- }
719
- return 0;
720
- }
721
-
722
- // Read the MS WinUSB Feature Descriptors, that are used on Windows 8 for automated driver installation
723
- static void read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uint8_t bRequest, int iface_number)
724
- {
725
- #define MAX_OS_FD_LENGTH 256
726
- int i, r;
727
- uint8_t os_desc[MAX_OS_FD_LENGTH];
728
- uint32_t length;
729
- void* le_type_punning_IS_fine;
730
- struct {
731
- const char* desc;
732
- uint8_t recipient;
733
- uint16_t index;
734
- uint16_t header_size;
735
- } os_fd[2] = {
736
- {"Extended Compat ID", LIBUSB_RECIPIENT_DEVICE, 0x0004, 0x10},
737
- {"Extended Properties", LIBUSB_RECIPIENT_INTERFACE, 0x0005, 0x0A}
738
- };
739
-
740
- if (iface_number < 0) return;
741
- // WinUSB has a limitation that forces wIndex to the interface number when issuing
742
- // an Interface Request. To work around that, we can force a Device Request for
743
- // the Extended Properties, assuming the device answers both equally.
744
- if (force_device_request)
745
- os_fd[1].recipient = LIBUSB_RECIPIENT_DEVICE;
746
-
747
- for (i=0; i<2; i++) {
748
- printf("\nReading %s OS Feature Descriptor (wIndex = 0x%04d):\n", os_fd[i].desc, os_fd[i].index);
749
-
750
- // Read the header part
751
- r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
752
- bRequest, (uint16_t)(((iface_number)<< 8)|0x00), os_fd[i].index, os_desc, os_fd[i].header_size, 1000);
753
- if (r < os_fd[i].header_size) {
754
- perr(" Failed: %s", (r<0)?libusb_strerror((enum libusb_error)r):"header size is too small");
755
- return;
756
- }
757
- le_type_punning_IS_fine = (void*)os_desc;
758
- length = *((uint32_t*)le_type_punning_IS_fine);
759
- if (length > MAX_OS_FD_LENGTH) {
760
- length = MAX_OS_FD_LENGTH;
761
- }
762
-
763
- // Read the full feature descriptor
764
- r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
765
- bRequest, (uint16_t)(((iface_number)<< 8)|0x00), os_fd[i].index, os_desc, (uint16_t)length, 1000);
766
- if (r < 0) {
767
- perr(" Failed: %s", libusb_strerror((enum libusb_error)r));
768
- return;
769
- } else {
770
- display_buffer_hex(os_desc, (unsigned int)r);
771
- }
772
- }
773
- }
774
-
775
- static void print_sublink_speed_attribute(struct libusb_ssplus_sublink_attribute* ss_attr) {
776
- static const char exponent[] = " KMG";
777
- printf(" id=%u speed=%u%cbs %s %s SuperSpeed%s",
778
- ss_attr->ssid,
779
- ss_attr->mantissa,
780
- (exponent[ss_attr->exponent]),
781
- (ss_attr->type == LIBUSB_SSPLUS_ATTR_TYPE_ASYM)? "Asym" : "Sym",
782
- (ss_attr->direction == LIBUSB_SSPLUS_ATTR_DIR_TX)? "TX" : "RX",
783
- (ss_attr->protocol == LIBUSB_SSPLUS_ATTR_PROT_SSPLUS)? "Plus": "" );
784
- }
785
-
786
- static void print_device_cap(struct libusb_bos_dev_capability_descriptor *dev_cap)
787
- {
788
- switch(dev_cap->bDevCapabilityType) {
789
- case LIBUSB_BT_USB_2_0_EXTENSION: {
790
- struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext = NULL;
791
- libusb_get_usb_2_0_extension_descriptor(NULL, dev_cap, &usb_2_0_ext);
792
- if (usb_2_0_ext) {
793
- printf(" USB 2.0 extension:\n");
794
- printf(" attributes : %02X\n", usb_2_0_ext->bmAttributes);
795
- libusb_free_usb_2_0_extension_descriptor(usb_2_0_ext);
796
- }
797
- break;
798
- }
799
- case LIBUSB_BT_SS_USB_DEVICE_CAPABILITY: {
800
- struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap = NULL;
801
- libusb_get_ss_usb_device_capability_descriptor(NULL, dev_cap, &ss_usb_device_cap);
802
- if (ss_usb_device_cap) {
803
- printf(" USB 3.0 capabilities:\n");
804
- printf(" attributes : %02X\n", ss_usb_device_cap->bmAttributes);
805
- printf(" supported speeds : %04X\n", ss_usb_device_cap->wSpeedSupported);
806
- printf(" supported functionality: %02X\n", ss_usb_device_cap->bFunctionalitySupport);
807
- libusb_free_ss_usb_device_capability_descriptor(ss_usb_device_cap);
808
- }
809
- break;
810
- }
811
- case LIBUSB_BT_CONTAINER_ID: {
812
- struct libusb_container_id_descriptor *container_id = NULL;
813
- libusb_get_container_id_descriptor(NULL, dev_cap, &container_id);
814
- if (container_id) {
815
- printf(" Container ID:\n %s\n", uuid_to_string(container_id->ContainerID));
816
- libusb_free_container_id_descriptor(container_id);
817
- }
818
- break;
819
- }
820
- case LIBUSB_BT_PLATFORM_DESCRIPTOR: {
821
- struct libusb_platform_descriptor *platform_descriptor = NULL;
822
- libusb_get_platform_descriptor(NULL, dev_cap, &platform_descriptor);
823
- if (platform_descriptor) {
824
- printf(" Platform descriptor:\n");
825
- printf(" bLength : %d\n", platform_descriptor->bLength);
826
- printf(" PlatformCapabilityUUID : %s\n", uuid_to_string(platform_descriptor->PlatformCapabilityUUID));
827
- display_buffer_hex(&platform_descriptor->CapabilityData[0], platform_descriptor->bLength - 20);
828
- printf("\n");
829
- libusb_free_platform_descriptor(platform_descriptor);
830
- }
831
- break;
832
-
833
- }
834
- case LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY: {
835
- struct libusb_ssplus_usb_device_capability_descriptor *ssplus_usb_device_cap = NULL;
836
- libusb_get_ssplus_usb_device_capability_descriptor(NULL, dev_cap, &ssplus_usb_device_cap);
837
- if (ssplus_usb_device_cap) {
838
- printf(" USB 3.1 capabilities:\n");
839
- printf(" num speed IDs: %d\n", ssplus_usb_device_cap->numSublinkSpeedIDs);
840
- printf(" minLaneSpeed: %d\n", ssplus_usb_device_cap->ssid);
841
- printf(" minRXLanes: %d\n", ssplus_usb_device_cap->minRxLaneCount);
842
- printf(" minTXLanes: %d\n", ssplus_usb_device_cap->minTxLaneCount);
843
-
844
- printf(" num speed attribute IDs: %d\n", ssplus_usb_device_cap->numSublinkSpeedAttributes);
845
- for(uint8_t i=0 ; i < ssplus_usb_device_cap->numSublinkSpeedAttributes ; i++) {
846
- print_sublink_speed_attribute(&ssplus_usb_device_cap->sublinkSpeedAttributes[i]);
847
- printf("\n");
848
- }
849
- libusb_free_ssplus_usb_device_capability_descriptor(ssplus_usb_device_cap);
850
- }
851
- break;
852
- }
853
- default:
854
- printf(" Unknown BOS device capability %02x:\n", dev_cap->bDevCapabilityType);
855
- }
856
- }
857
-
858
- static int test_device(uint16_t vid, uint16_t pid)
859
- {
860
- libusb_device_handle *handle;
861
- libusb_device *dev;
862
- uint8_t bus, port_path[8];
863
- struct libusb_config_descriptor *conf_desc;
864
- const struct libusb_endpoint_descriptor *endpoint;
865
- int i, j, k, r;
866
- int iface, nb_ifaces, first_iface = -1;
867
- struct libusb_device_descriptor dev_desc;
868
- const char* const speed_name[] = { "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)",
869
- "480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)", "10000 Mbit/s (USB SuperSpeedPlus)",
870
- "20000 Mbit/s (USB SuperSpeedPlus x2)" };
871
- unsigned char string[128];
872
- uint8_t string_index[3]; // indexes of the string descriptors
873
- uint8_t endpoint_in = 0, endpoint_out = 0; // default IN and OUT endpoints
874
-
875
- printf("Opening device %04X:%04X...\n", vid, pid);
876
- handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
877
-
878
- if (handle == NULL) {
879
- perr(" Failed.\n");
880
- return -1;
881
- }
882
-
883
- dev = libusb_get_device(handle);
884
- bus = libusb_get_bus_number(dev);
885
- if (extra_info) {
886
- r = libusb_get_port_numbers(dev, port_path, sizeof(port_path));
887
- if (r > 0) {
888
- printf("\nDevice properties:\n");
889
- printf(" bus number: %d\n", bus);
890
- printf(" port path: %d", port_path[0]);
891
- for (i=1; i<r; i++) {
892
- printf("->%d", port_path[i]);
893
- }
894
- printf(" (from root hub)\n");
895
- }
896
- r = libusb_get_device_speed(dev);
897
- if ((r < 0) || ((size_t)r >= ARRAYSIZE(speed_name)))
898
- r = 0;
899
- printf(" speed: %s\n", speed_name[r]);
900
- }
901
-
902
- printf("\nReading device descriptor:\n");
903
- CALL_CHECK_CLOSE(libusb_get_device_descriptor(dev, &dev_desc), handle);
904
- printf(" length: %d\n", dev_desc.bLength);
905
- printf(" device class: %d\n", dev_desc.bDeviceClass);
906
- printf(" S/N: %d\n", dev_desc.iSerialNumber);
907
- printf(" VID:PID: %04X:%04X\n", dev_desc.idVendor, dev_desc.idProduct);
908
- printf(" bcdDevice: %04X\n", dev_desc.bcdDevice);
909
- printf(" iMan:iProd:iSer: %d:%d:%d\n", dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber);
910
- printf(" nb confs: %d\n", dev_desc.bNumConfigurations);
911
- // Copy the string descriptors for easier parsing
912
- string_index[0] = dev_desc.iManufacturer;
913
- string_index[1] = dev_desc.iProduct;
914
- string_index[2] = dev_desc.iSerialNumber;
915
-
916
- if (dev_desc.bcdUSB >= 0x0201) {
917
- struct libusb_bos_descriptor *bos_desc;
918
-
919
- printf("\nReading BOS descriptor: ");
920
- if (libusb_get_bos_descriptor(handle, &bos_desc) == LIBUSB_SUCCESS) {
921
- printf("%d caps\n", bos_desc->bNumDeviceCaps);
922
- for (i = 0; i < bos_desc->bNumDeviceCaps; i++)
923
- print_device_cap(bos_desc->dev_capability[i]);
924
- libusb_free_bos_descriptor(bos_desc);
925
- } else {
926
- printf("no descriptor\n");
927
- }
928
- }
929
-
930
- printf("\nReading first configuration descriptor:\n");
931
- CALL_CHECK_CLOSE(libusb_get_config_descriptor(dev, 0, &conf_desc), handle);
932
- printf(" total length: %d\n", conf_desc->wTotalLength);
933
- printf(" descriptor length: %d\n", conf_desc->bLength);
934
- nb_ifaces = conf_desc->bNumInterfaces;
935
- printf(" nb interfaces: %d\n", nb_ifaces);
936
- if (nb_ifaces > 0)
937
- first_iface = conf_desc->usb_interface[0].altsetting[0].bInterfaceNumber;
938
- for (i=0; i<nb_ifaces; i++) {
939
- printf(" interface[%d]: id = %d\n", i,
940
- conf_desc->usb_interface[i].altsetting[0].bInterfaceNumber);
941
- for (j=0; j<conf_desc->usb_interface[i].num_altsetting; j++) {
942
- printf("interface[%d].altsetting[%d]: num endpoints = %d\n",
943
- i, j, conf_desc->usb_interface[i].altsetting[j].bNumEndpoints);
944
- printf(" Class.SubClass.Protocol: %02X.%02X.%02X\n",
945
- conf_desc->usb_interface[i].altsetting[j].bInterfaceClass,
946
- conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass,
947
- conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol);
948
- if ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE)
949
- && ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x01)
950
- || (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x06) )
951
- && (conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol == 0x50) ) {
952
- // Mass storage devices that can use basic SCSI commands
953
- test_mode = USE_SCSI;
954
- }
955
- for (k=0; k<conf_desc->usb_interface[i].altsetting[j].bNumEndpoints; k++) {
956
- struct libusb_ss_endpoint_companion_descriptor *ep_comp = NULL;
957
- endpoint = &conf_desc->usb_interface[i].altsetting[j].endpoint[k];
958
- printf(" endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress);
959
- // Use the first interrupt or bulk IN/OUT endpoints as default for testing
960
- if ((endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) & (LIBUSB_TRANSFER_TYPE_BULK | LIBUSB_TRANSFER_TYPE_INTERRUPT)) {
961
- if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
962
- if (!endpoint_in)
963
- endpoint_in = endpoint->bEndpointAddress;
964
- } else {
965
- if (!endpoint_out)
966
- endpoint_out = endpoint->bEndpointAddress;
967
- }
968
- }
969
- printf(" max packet size: %04X\n", endpoint->wMaxPacketSize);
970
- printf(" polling interval: %02X\n", endpoint->bInterval);
971
- libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);
972
- if (ep_comp) {
973
- printf(" max burst: %02X (USB 3.0)\n", ep_comp->bMaxBurst);
974
- printf(" bytes per interval: %04X (USB 3.0)\n", ep_comp->wBytesPerInterval);
975
- libusb_free_ss_endpoint_companion_descriptor(ep_comp);
976
- }
977
- }
978
- }
979
- }
980
- libusb_free_config_descriptor(conf_desc);
981
-
982
- libusb_set_auto_detach_kernel_driver(handle, 1);
983
- for (iface = 0; iface < nb_ifaces; iface++)
984
- {
985
- printf("\nKernel driver attached for interface %d: ", iface);
986
- r = libusb_kernel_driver_active(handle, iface);
987
- if (r == 0)
988
- printf("none\n");
989
- else if (r == 1)
990
- printf("yes\n");
991
- else if (r == LIBUSB_ERROR_NOT_SUPPORTED)
992
- printf("(not supported)\n");
993
- else
994
- perr("\n Failed (error %d) %s\n", r,
995
- libusb_strerror((enum libusb_error) r));
996
-
997
- printf("\nClaiming interface %d...\n", iface);
998
- r = libusb_claim_interface(handle, iface);
999
- if (r != LIBUSB_SUCCESS) {
1000
- perr(" Failed (error %d) %s\n", r,
1001
- libusb_strerror((enum libusb_error) r));
1002
- }
1003
- }
1004
-
1005
- printf("\nReading string descriptors:\n");
1006
- for (i=0; i<3; i++) {
1007
- if (string_index[i] == 0) {
1008
- continue;
1009
- }
1010
- if (libusb_get_string_descriptor_ascii(handle, string_index[i], string, sizeof(string)) > 0) {
1011
- printf(" String (0x%02X): \"%s\"\n", string_index[i], string);
1012
- }
1013
- }
1014
-
1015
- printf("\nReading OS string descriptor:");
1016
- r = libusb_get_string_descriptor(handle, MS_OS_DESC_STRING_INDEX, 0, string, MS_OS_DESC_STRING_LENGTH);
1017
- if (r == MS_OS_DESC_STRING_LENGTH && memcmp(ms_os_desc_string, string, sizeof(ms_os_desc_string)) == 0) {
1018
- // If this is a Microsoft OS String Descriptor,
1019
- // attempt to read the WinUSB extended Feature Descriptors
1020
- printf("\n");
1021
- read_ms_winsub_feature_descriptors(handle, string[MS_OS_DESC_VENDOR_CODE_OFFSET], first_iface);
1022
- } else {
1023
- printf(" no descriptor\n");
1024
- }
1025
-
1026
- // Read IADs
1027
- printf("\nReading interface association descriptors (IADs) for first configuration:\n");
1028
- struct libusb_interface_association_descriptor_array *iad_array;
1029
- r = libusb_get_interface_association_descriptors(dev, 0, &iad_array);
1030
- if (r == LIBUSB_SUCCESS) {
1031
- printf(" nb IADs: %d\n", iad_array->length);
1032
- for (i=0; i<iad_array->length;i++) {
1033
- const struct libusb_interface_association_descriptor *iad = &iad_array->iad[i];
1034
- printf(" IAD %d:\n", i);
1035
- printf(" bFirstInterface: %u\n", iad->bFirstInterface);
1036
- printf(" bInterfaceCount: %u\n", iad->bInterfaceCount);
1037
- printf(" bFunctionClass: %02X\n", iad->bFunctionClass);
1038
- printf(" bFunctionSubClass: %02X\n", iad->bFunctionSubClass);
1039
- printf(" bFunctionProtocol: %02X\n", iad->bFunctionProtocol);
1040
- if (iad->iFunction) {
1041
- if (libusb_get_string_descriptor_ascii(handle, iad->iFunction, string, sizeof(string)) > 0)
1042
- printf(" iFunction: %u (%s)\n", iad->iFunction, string);
1043
- else
1044
- printf(" iFunction: %u (libusb_get_string_descriptor_ascii failed!)\n", iad->iFunction);
1045
- }
1046
- else
1047
- printf(" iFunction: 0\n");
1048
- }
1049
- libusb_free_interface_association_descriptors(iad_array);
1050
- }
1051
-
1052
- switch(test_mode) {
1053
- case USE_PS3:
1054
- CALL_CHECK_CLOSE(display_ps3_status(handle), handle);
1055
- break;
1056
- case USE_XBOX:
1057
- CALL_CHECK_CLOSE(display_xbox_status(handle), handle);
1058
- CALL_CHECK_CLOSE(set_xbox_actuators(handle, 128, 222), handle);
1059
- msleep(2000);
1060
- CALL_CHECK_CLOSE(set_xbox_actuators(handle, 0, 0), handle);
1061
- break;
1062
- case USE_HID:
1063
- test_hid(handle, endpoint_in);
1064
- break;
1065
- case USE_SCSI:
1066
- CALL_CHECK_CLOSE(test_mass_storage(handle, endpoint_in, endpoint_out), handle);
1067
- break;
1068
- case USE_GENERIC:
1069
- break;
1070
- }
1071
-
1072
- printf("\n");
1073
- for (iface = 0; iface<nb_ifaces; iface++) {
1074
- printf("Releasing interface %d...\n", iface);
1075
- libusb_release_interface(handle, iface);
1076
- }
1077
-
1078
- printf("Closing device...\n");
1079
- libusb_close(handle);
1080
-
1081
- return 0;
1082
- }
1083
-
1084
- static void display_help(const char *progname)
1085
- {
1086
- printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] [-x] [-s] [-p] [-w] [vid:pid]\n", progname);
1087
- printf(" -h : display usage\n");
1088
- printf(" -d : enable debug output\n");
1089
- printf(" -i : print topology and speed info\n");
1090
- printf(" -j : test composite FTDI based JTAG device\n");
1091
- printf(" -k : test Mass Storage device\n");
1092
- printf(" -b file : dump Mass Storage data to file 'file'\n");
1093
- printf(" -p : test Sony PS3 SixAxis controller\n");
1094
- printf(" -s : test Microsoft Sidewinder Precision Pro (HID)\n");
1095
- printf(" -x : test Microsoft XBox Controller Type S\n");
1096
- printf(" -l lang : language to report errors in (ISO 639-1)\n");
1097
- printf(" -w : force the use of device requests when querying WCID descriptors\n");
1098
- printf("If only the vid:pid is provided, xusb attempts to run the most appropriate test\n");
1099
- }
1100
-
1101
- int main(int argc, char** argv)
1102
- {
1103
- bool debug_mode = false;
1104
- const struct libusb_version* version;
1105
- int j, r;
1106
- size_t i, arglen;
1107
- unsigned tmp_vid, tmp_pid;
1108
- uint16_t endian_test = 0xBE00;
1109
- char *error_lang = NULL, *old_dbg_str = NULL, str[256];
1110
-
1111
- // Default to generic, expecting VID:PID
1112
- VID = 0;
1113
- PID = 0;
1114
- test_mode = USE_GENERIC;
1115
-
1116
- if (((uint8_t*)&endian_test)[0] == 0xBE) {
1117
- printf("Despite their natural superiority for end users, big endian\n"
1118
- "CPUs are not supported with this program, sorry.\n");
1119
- return EXIT_FAILURE;
1120
- }
1121
-
1122
- if ((argc == 1) || (argc > 7)) {
1123
- display_help(argv[0]);
1124
- return EXIT_FAILURE;
1125
- }
1126
-
1127
- if (argc >= 2) {
1128
- for (j = 1; j<argc; j++) {
1129
- arglen = strlen(argv[j]);
1130
- if ( ((argv[j][0] == '-') || (argv[j][0] == '/'))
1131
- && (arglen >= 2) ) {
1132
- switch(argv[j][1]) {
1133
- case 'd':
1134
- debug_mode = true;
1135
- break;
1136
- case 'i':
1137
- extra_info = true;
1138
- break;
1139
- case 'w':
1140
- force_device_request = true;
1141
- break;
1142
- case 'b':
1143
- if ((j+1 >= argc) || (argv[j+1][0] == '-') || (argv[j+1][0] == '/')) {
1144
- printf(" Option -b requires a file name\n");
1145
- return EXIT_FAILURE;
1146
- }
1147
- binary_name = argv[++j];
1148
- binary_dump = true;
1149
- break;
1150
- case 'l':
1151
- if ((j+1 >= argc) || (argv[j+1][0] == '-') || (argv[j+1][0] == '/')) {
1152
- printf(" Option -l requires an ISO 639-1 language parameter\n");
1153
- return EXIT_FAILURE;
1154
- }
1155
- error_lang = argv[++j];
1156
- break;
1157
- case 'j':
1158
- // OLIMEX ARM-USB-TINY JTAG, 2 channel composite device - 2 interfaces
1159
- if (!VID && !PID) {
1160
- VID = 0x15BA;
1161
- PID = 0x0004;
1162
- }
1163
- break;
1164
- case 'k':
1165
- // Generic 2 GB USB Key (SCSI Transparent/Bulk Only) - 1 interface
1166
- if (!VID && !PID) {
1167
- VID = 0x0204;
1168
- PID = 0x6025;
1169
- }
1170
- break;
1171
- // The following tests will force VID:PID if already provided
1172
- case 'p':
1173
- // Sony PS3 Controller - 1 interface
1174
- VID = 0x054C;
1175
- PID = 0x0268;
1176
- test_mode = USE_PS3;
1177
- break;
1178
- case 's':
1179
- // Microsoft Sidewinder Precision Pro Joystick - 1 HID interface
1180
- VID = 0x045E;
1181
- PID = 0x0008;
1182
- test_mode = USE_HID;
1183
- break;
1184
- case 'x':
1185
- // Microsoft XBox Controller Type S - 1 interface
1186
- VID = 0x045E;
1187
- PID = 0x0289;
1188
- test_mode = USE_XBOX;
1189
- break;
1190
- case 'h':
1191
- display_help(argv[0]);
1192
- return EXIT_SUCCESS;
1193
- default:
1194
- display_help(argv[0]);
1195
- return EXIT_FAILURE;
1196
- }
1197
- } else {
1198
- for (i=0; i<arglen; i++) {
1199
- if (argv[j][i] == ':')
1200
- break;
1201
- }
1202
- if (i != arglen) {
1203
- if (sscanf(argv[j], "%x:%x" , &tmp_vid, &tmp_pid) != 2) {
1204
- printf(" Please specify VID & PID as \"vid:pid\" in hexadecimal format\n");
1205
- return EXIT_FAILURE;
1206
- }
1207
- VID = (uint16_t)tmp_vid;
1208
- PID = (uint16_t)tmp_pid;
1209
- } else {
1210
- display_help(argv[0]);
1211
- return EXIT_FAILURE;
1212
- }
1213
- }
1214
- }
1215
- }
1216
-
1217
- version = libusb_get_version();
1218
- printf("Using libusb v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);
1219
-
1220
- // xusb is commonly used as a debug tool, so it's convenient to have debug output during libusb_init_context().
1221
- if (debug_mode) {
1222
- const struct libusb_init_option options = {.option = LIBUSB_OPTION_LOG_LEVEL, .value = {.ival = LIBUSB_LOG_LEVEL_DEBUG}};
1223
- r = libusb_init_context(/*ctx=*/NULL, /*options=*/&options, /*num_options=*/1);
1224
- } else {
1225
- r = libusb_init_context(/*ctx=*/NULL, /*options=*/NULL, /*num_options=*/0);
1226
- }
1227
-
1228
- if (r < 0)
1229
- return EXIT_FAILURE;
1230
-
1231
- // If not set externally, and no debug option was given, use info log level
1232
- if ((old_dbg_str == NULL) && (!debug_mode))
1233
- libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
1234
- if (error_lang != NULL) {
1235
- r = libusb_setlocale(error_lang);
1236
- if (r < 0)
1237
- printf("Invalid or unsupported locale '%s': %s\n", error_lang, libusb_strerror((enum libusb_error)r));
1238
- }
1239
-
1240
- r = test_device(VID, PID);
1241
-
1242
- libusb_exit(NULL);
1243
-
1244
- if (r < 0)
1245
- return EXIT_FAILURE;
1246
-
1247
-
1248
- if (debug_mode) {
1249
- snprintf(str, sizeof(str), "LIBUSB_DEBUG=%s", (old_dbg_str == NULL)?"":old_dbg_str);
1250
- str[sizeof(str) - 1] = 0; // Windows may not NUL terminate the string
1251
- }
1252
-
1253
- return EXIT_SUCCESS;
1254
- }