libusb 0.5.1 → 0.6.0

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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -2
  3. data/Gemfile +2 -0
  4. data/History.md +12 -0
  5. data/README.md +25 -14
  6. data/Rakefile +64 -109
  7. data/appveyor.yml +23 -0
  8. data/ext/extconf.rb +10 -12
  9. data/ext/libusb_recipe.rb +29 -0
  10. data/lib/libusb/call.rb +14 -11
  11. data/lib/libusb/compat.rb +9 -9
  12. data/lib/libusb/context.rb +16 -1
  13. data/lib/libusb/dependencies.rb +7 -0
  14. data/lib/libusb/dev_handle.rb +13 -3
  15. data/lib/libusb/eventmachine.rb +4 -4
  16. data/lib/libusb/transfer.rb +71 -10
  17. data/lib/libusb/version_gem.rb +1 -1
  18. data/libusb.gemspec +7 -5
  19. data/ports/archives/libusb-1.0.21.tar.bz2 +0 -0
  20. data/test/test_libusb_bulk_stream_transfer.rb +1 -1
  21. data/test/test_libusb_descriptors.rb +4 -4
  22. data/test/test_libusb_event_machine.rb +7 -7
  23. data/test/test_libusb_hotplug.rb +15 -3
  24. data/test/test_libusb_iso_transfer.rb +1 -1
  25. data/test/test_libusb_mass_storage.rb +19 -19
  26. data/test/test_libusb_mass_storage2.rb +1 -1
  27. data/test/test_libusb_structs.rb +13 -0
  28. data/test/test_libusb_threads.rb +2 -2
  29. data/wireshark-usb-sniffer.png +0 -0
  30. metadata +32 -156
  31. checksums.yaml.gz.sig +0 -0
  32. data.tar.gz.sig +0 -0
  33. data/ext/libusb-1.0.20/AUTHORS +0 -89
  34. data/ext/libusb-1.0.20/COPYING +0 -504
  35. data/ext/libusb-1.0.20/ChangeLog +0 -227
  36. data/ext/libusb-1.0.20/INSTALL +0 -234
  37. data/ext/libusb-1.0.20/Makefile.am +0 -28
  38. data/ext/libusb-1.0.20/Makefile.in +0 -897
  39. data/ext/libusb-1.0.20/NEWS +0 -2
  40. data/ext/libusb-1.0.20/PORTING +0 -94
  41. data/ext/libusb-1.0.20/README +0 -29
  42. data/ext/libusb-1.0.20/TODO +0 -2
  43. data/ext/libusb-1.0.20/Xcode/common.xcconfig +0 -49
  44. data/ext/libusb-1.0.20/Xcode/config.h +0 -28
  45. data/ext/libusb-1.0.20/Xcode/debug.xcconfig +0 -29
  46. data/ext/libusb-1.0.20/Xcode/libusb.xcconfig +0 -21
  47. data/ext/libusb-1.0.20/Xcode/libusb.xcodeproj/project.pbxproj +0 -865
  48. data/ext/libusb-1.0.20/Xcode/libusb_debug.xcconfig +0 -21
  49. data/ext/libusb-1.0.20/Xcode/libusb_release.xcconfig +0 -21
  50. data/ext/libusb-1.0.20/Xcode/release.xcconfig +0 -30
  51. data/ext/libusb-1.0.20/aclocal.m4 +0 -1193
  52. data/ext/libusb-1.0.20/android/README +0 -114
  53. data/ext/libusb-1.0.20/android/config.h +0 -81
  54. data/ext/libusb-1.0.20/android/jni/Android.mk +0 -23
  55. data/ext/libusb-1.0.20/android/jni/Application.mk +0 -24
  56. data/ext/libusb-1.0.20/android/jni/examples.mk +0 -134
  57. data/ext/libusb-1.0.20/android/jni/libusb.mk +0 -54
  58. data/ext/libusb-1.0.20/android/jni/tests.mk +0 -56
  59. data/ext/libusb-1.0.20/compile +0 -347
  60. data/ext/libusb-1.0.20/config.guess +0 -1421
  61. data/ext/libusb-1.0.20/config.h.in +0 -155
  62. data/ext/libusb-1.0.20/config.sub +0 -1807
  63. data/ext/libusb-1.0.20/configure +0 -15466
  64. data/ext/libusb-1.0.20/configure.ac +0 -326
  65. data/ext/libusb-1.0.20/depcomp +0 -791
  66. data/ext/libusb-1.0.20/doc/Makefile.am +0 -9
  67. data/ext/libusb-1.0.20/doc/Makefile.in +0 -456
  68. data/ext/libusb-1.0.20/doc/doxygen.cfg.in +0 -2334
  69. data/ext/libusb-1.0.20/examples/Makefile.am +0 -19
  70. data/ext/libusb-1.0.20/examples/Makefile.in +0 -713
  71. data/ext/libusb-1.0.20/examples/dpfp.c +0 -506
  72. data/ext/libusb-1.0.20/examples/dpfp_threaded.c +0 -549
  73. data/ext/libusb-1.0.20/examples/ezusb.c +0 -831
  74. data/ext/libusb-1.0.20/examples/ezusb.h +0 -120
  75. data/ext/libusb-1.0.20/examples/fxload.c +0 -308
  76. data/ext/libusb-1.0.20/examples/getopt/getopt.c +0 -1060
  77. data/ext/libusb-1.0.20/examples/getopt/getopt.h +0 -180
  78. data/ext/libusb-1.0.20/examples/getopt/getopt1.c +0 -188
  79. data/ext/libusb-1.0.20/examples/hotplugtest.c +0 -122
  80. data/ext/libusb-1.0.20/examples/listdevs.c +0 -71
  81. data/ext/libusb-1.0.20/examples/sam3u_benchmark.c +0 -193
  82. data/ext/libusb-1.0.20/examples/xusb.c +0 -1130
  83. data/ext/libusb-1.0.20/install-sh +0 -501
  84. data/ext/libusb-1.0.20/libusb-1.0.pc.in +0 -11
  85. data/ext/libusb-1.0.20/libusb/Makefile.am +0 -90
  86. data/ext/libusb-1.0.20/libusb/Makefile.in +0 -1053
  87. data/ext/libusb-1.0.20/libusb/core.c +0 -2452
  88. data/ext/libusb-1.0.20/libusb/descriptor.c +0 -1201
  89. data/ext/libusb-1.0.20/libusb/hotplug.c +0 -344
  90. data/ext/libusb-1.0.20/libusb/hotplug.h +0 -90
  91. data/ext/libusb-1.0.20/libusb/io.c +0 -2760
  92. data/ext/libusb-1.0.20/libusb/libusb-1.0.def +0 -168
  93. data/ext/libusb-1.0.20/libusb/libusb-1.0.rc +0 -61
  94. data/ext/libusb-1.0.20/libusb/libusb.h +0 -1999
  95. data/ext/libusb-1.0.20/libusb/libusbi.h +0 -1102
  96. data/ext/libusb-1.0.20/libusb/os/darwin_usb.c +0 -1969
  97. data/ext/libusb-1.0.20/libusb/os/darwin_usb.h +0 -158
  98. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.am +0 -5
  99. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.in +0 -810
  100. data/ext/libusb-1.0.20/libusb/os/haiku/aclocal.m4 +0 -1193
  101. data/ext/libusb-1.0.20/libusb/os/haiku/compile +0 -347
  102. data/ext/libusb-1.0.20/libusb/os/haiku/config.guess +0 -1421
  103. data/ext/libusb-1.0.20/libusb/os/haiku/config.sub +0 -1807
  104. data/ext/libusb-1.0.20/libusb/os/haiku/configure +0 -17579
  105. data/ext/libusb-1.0.20/libusb/os/haiku/configure.ac +0 -8
  106. data/ext/libusb-1.0.20/libusb/os/haiku/depcomp +0 -791
  107. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_pollfs.cpp +0 -378
  108. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb.h +0 -112
  109. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_backend.cpp +0 -550
  110. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.cpp +0 -255
  111. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.h +0 -180
  112. data/ext/libusb-1.0.20/libusb/os/haiku/install-sh +0 -501
  113. data/ext/libusb-1.0.20/libusb/os/haiku/ltmain.sh +0 -9655
  114. data/ext/libusb-1.0.20/libusb/os/haiku/m4/libtool.m4 +0 -7992
  115. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltoptions.m4 +0 -384
  116. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltsugar.m4 +0 -123
  117. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltversion.m4 +0 -23
  118. data/ext/libusb-1.0.20/libusb/os/haiku/m4/lt~obsolete.m4 +0 -98
  119. data/ext/libusb-1.0.20/libusb/os/haiku/missing +0 -215
  120. data/ext/libusb-1.0.20/libusb/os/linux_netlink.c +0 -369
  121. data/ext/libusb-1.0.20/libusb/os/linux_udev.c +0 -306
  122. data/ext/libusb-1.0.20/libusb/os/linux_usbfs.c +0 -2692
  123. data/ext/libusb-1.0.20/libusb/os/linux_usbfs.h +0 -192
  124. data/ext/libusb-1.0.20/libusb/os/netbsd_usb.c +0 -674
  125. data/ext/libusb-1.0.20/libusb/os/openbsd_usb.c +0 -768
  126. data/ext/libusb-1.0.20/libusb/os/poll_posix.c +0 -53
  127. data/ext/libusb-1.0.20/libusb/os/poll_posix.h +0 -11
  128. data/ext/libusb-1.0.20/libusb/os/poll_windows.c +0 -728
  129. data/ext/libusb-1.0.20/libusb/os/poll_windows.h +0 -131
  130. data/ext/libusb-1.0.20/libusb/os/threads_posix.c +0 -82
  131. data/ext/libusb-1.0.20/libusb/os/threads_posix.h +0 -50
  132. data/ext/libusb-1.0.20/libusb/os/threads_windows.c +0 -214
  133. data/ext/libusb-1.0.20/libusb/os/threads_windows.h +0 -87
  134. data/ext/libusb-1.0.20/libusb/os/wince_usb.c +0 -869
  135. data/ext/libusb-1.0.20/libusb/os/wince_usb.h +0 -131
  136. data/ext/libusb-1.0.20/libusb/os/windows_common.h +0 -108
  137. data/ext/libusb-1.0.20/libusb/os/windows_usb.c +0 -4643
  138. data/ext/libusb-1.0.20/libusb/os/windows_usb.h +0 -973
  139. data/ext/libusb-1.0.20/libusb/strerror.c +0 -202
  140. data/ext/libusb-1.0.20/libusb/sync.c +0 -308
  141. data/ext/libusb-1.0.20/libusb/version.h +0 -18
  142. data/ext/libusb-1.0.20/libusb/version_nano.h +0 -1
  143. data/ext/libusb-1.0.20/ltmain.sh +0 -9655
  144. data/ext/libusb-1.0.20/m4/libtool.m4 +0 -7992
  145. data/ext/libusb-1.0.20/m4/ltoptions.m4 +0 -384
  146. data/ext/libusb-1.0.20/m4/ltsugar.m4 +0 -123
  147. data/ext/libusb-1.0.20/m4/ltversion.m4 +0 -23
  148. data/ext/libusb-1.0.20/m4/lt~obsolete.m4 +0 -98
  149. data/ext/libusb-1.0.20/missing +0 -215
  150. data/ext/libusb-1.0.20/tests/Makefile.am +0 -6
  151. data/ext/libusb-1.0.20/tests/Makefile.in +0 -596
  152. data/ext/libusb-1.0.20/tests/libusb_testlib.h +0 -107
  153. data/ext/libusb-1.0.20/tests/stress.c +0 -160
  154. data/ext/libusb-1.0.20/tests/testlib.c +0 -277
  155. metadata.gz.sig +0 -0
@@ -1,71 +0,0 @@
1
- /*
2
- * libusb example program to list devices on the bus
3
- * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
4
- *
5
- * This library is free software; you can redistribute it and/or
6
- * modify it under the terms of the GNU Lesser General Public
7
- * License as published by the Free Software Foundation; either
8
- * version 2.1 of the License, or (at your option) any later version.
9
- *
10
- * This library is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- * Lesser General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU Lesser General Public
16
- * License along with this library; if not, write to the Free Software
17
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- */
19
-
20
- #include <stdio.h>
21
-
22
- #include "libusb.h"
23
-
24
- static void print_devs(libusb_device **devs)
25
- {
26
- libusb_device *dev;
27
- int i = 0, j = 0;
28
- uint8_t path[8];
29
-
30
- while ((dev = devs[i++]) != NULL) {
31
- struct libusb_device_descriptor desc;
32
- int r = libusb_get_device_descriptor(dev, &desc);
33
- if (r < 0) {
34
- fprintf(stderr, "failed to get device descriptor");
35
- return;
36
- }
37
-
38
- printf("%04x:%04x (bus %d, device %d)",
39
- desc.idVendor, desc.idProduct,
40
- libusb_get_bus_number(dev), libusb_get_device_address(dev));
41
-
42
- r = libusb_get_port_numbers(dev, path, sizeof(path));
43
- if (r > 0) {
44
- printf(" path: %d", path[0]);
45
- for (j = 1; j < r; j++)
46
- printf(".%d", path[j]);
47
- }
48
- printf("\n");
49
- }
50
- }
51
-
52
- int main(void)
53
- {
54
- libusb_device **devs;
55
- int r;
56
- ssize_t cnt;
57
-
58
- r = libusb_init(NULL);
59
- if (r < 0)
60
- return r;
61
-
62
- cnt = libusb_get_device_list(NULL, &devs);
63
- if (cnt < 0)
64
- return (int) cnt;
65
-
66
- print_devs(devs);
67
- libusb_free_device_list(devs, 1);
68
-
69
- libusb_exit(NULL);
70
- return 0;
71
- }
@@ -1,193 +0,0 @@
1
- /*
2
- * libusb example program to measure Atmel SAM3U isochronous performance
3
- * Copyright (C) 2012 Harald Welte <laforge@gnumonks.org>
4
- *
5
- * Copied with the author's permission under LGPL-2.1 from
6
- * http://git.gnumonks.org/cgi-bin/gitweb.cgi?p=sam3u-tests.git;a=blob;f=usb-benchmark-project/host/benchmark.c;h=74959f7ee88f1597286cd435f312a8ff52c56b7e
7
- *
8
- * An Atmel SAM3U test firmware is also available in the above repository.
9
- *
10
- * This library is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU Lesser General Public
12
- * License as published by the Free Software Foundation; either
13
- * version 2.1 of the License, or (at your option) any later version.
14
- *
15
- * This library is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
- * Lesser General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU Lesser General Public
21
- * License along with this library; if not, write to the Free Software
22
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
- */
24
-
25
- #include <unistd.h>
26
- #include <stdlib.h>
27
- #include <stdio.h>
28
- #include <errno.h>
29
- #include <signal.h>
30
-
31
- #include <libusb.h>
32
-
33
-
34
- #define EP_DATA_IN 0x82
35
- #define EP_ISO_IN 0x86
36
-
37
- static int do_exit = 0;
38
- static struct libusb_device_handle *devh = NULL;
39
-
40
- static unsigned long num_bytes = 0, num_xfer = 0;
41
- static struct timeval tv_start;
42
-
43
- static void LIBUSB_CALL cb_xfr(struct libusb_transfer *xfr)
44
- {
45
- unsigned int i;
46
-
47
- if (xfr->status != LIBUSB_TRANSFER_COMPLETED) {
48
- fprintf(stderr, "transfer status %d\n", xfr->status);
49
- libusb_free_transfer(xfr);
50
- exit(3);
51
- }
52
-
53
- if (xfr->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
54
- for (i = 0; i < xfr->num_iso_packets; i++) {
55
- struct libusb_iso_packet_descriptor *pack = &xfr->iso_packet_desc[i];
56
-
57
- if (pack->status != LIBUSB_TRANSFER_COMPLETED) {
58
- fprintf(stderr, "Error: pack %u status %d\n", i, pack->status);
59
- exit(5);
60
- }
61
-
62
- printf("pack%u length:%u, actual_length:%u\n", i, pack->length, pack->actual_length);
63
- }
64
- }
65
-
66
- printf("length:%u, actual_length:%u\n", xfr->length, xfr->actual_length);
67
- for (i = 0; i < xfr->actual_length; i++) {
68
- printf("%02x", xfr->buffer[i]);
69
- if (i % 16)
70
- printf("\n");
71
- else if (i % 8)
72
- printf(" ");
73
- else
74
- printf(" ");
75
- }
76
- num_bytes += xfr->actual_length;
77
- num_xfer++;
78
-
79
- if (libusb_submit_transfer(xfr) < 0) {
80
- fprintf(stderr, "error re-submitting URB\n");
81
- exit(1);
82
- }
83
- }
84
-
85
- static int benchmark_in(uint8_t ep)
86
- {
87
- static uint8_t buf[2048];
88
- static struct libusb_transfer *xfr;
89
- int num_iso_pack = 0;
90
-
91
- if (ep == EP_ISO_IN)
92
- num_iso_pack = 16;
93
-
94
- xfr = libusb_alloc_transfer(num_iso_pack);
95
- if (!xfr)
96
- return -ENOMEM;
97
-
98
- if (ep == EP_ISO_IN) {
99
- libusb_fill_iso_transfer(xfr, devh, ep, buf,
100
- sizeof(buf), num_iso_pack, cb_xfr, NULL, 0);
101
- libusb_set_iso_packet_lengths(xfr, sizeof(buf)/num_iso_pack);
102
- } else
103
- libusb_fill_bulk_transfer(xfr, devh, ep, buf,
104
- sizeof(buf), cb_xfr, NULL, 0);
105
-
106
- gettimeofday(&tv_start, NULL);
107
-
108
- /* NOTE: To reach maximum possible performance the program must
109
- * submit *multiple* transfers here, not just one.
110
- *
111
- * When only one transfer is submitted there is a gap in the bus
112
- * schedule from when the transfer completes until a new transfer
113
- * is submitted by the callback. This causes some jitter for
114
- * isochronous transfers and loss of throughput for bulk transfers.
115
- *
116
- * This is avoided by queueing multiple transfers in advance, so
117
- * that the host controller is always kept busy, and will schedule
118
- * more transfers on the bus while the callback is running for
119
- * transfers which have completed on the bus.
120
- */
121
-
122
- return libusb_submit_transfer(xfr);
123
- }
124
-
125
- static void measure(void)
126
- {
127
- struct timeval tv_stop;
128
- unsigned int diff_msec;
129
-
130
- gettimeofday(&tv_stop, NULL);
131
-
132
- diff_msec = (tv_stop.tv_sec - tv_start.tv_sec)*1000;
133
- diff_msec += (tv_stop.tv_usec - tv_start.tv_usec)/1000;
134
-
135
- printf("%lu transfers (total %lu bytes) in %u miliseconds => %lu bytes/sec\n",
136
- num_xfer, num_bytes, diff_msec, (num_bytes*1000)/diff_msec);
137
- }
138
-
139
- static void sig_hdlr(int signum)
140
- {
141
- switch (signum) {
142
- case SIGINT:
143
- measure();
144
- do_exit = 1;
145
- break;
146
- }
147
- }
148
-
149
- int main(int argc, char **argv)
150
- {
151
- int rc;
152
- struct sigaction sigact;
153
-
154
- sigact.sa_handler = sig_hdlr;
155
- sigemptyset(&sigact.sa_mask);
156
- sigact.sa_flags = 0;
157
- sigaction(SIGINT, &sigact, NULL);
158
-
159
- rc = libusb_init(NULL);
160
- if (rc < 0) {
161
- fprintf(stderr, "Error initializing libusb: %s\n", libusb_error_name(rc));
162
- exit(1);
163
- }
164
-
165
- devh = libusb_open_device_with_vid_pid(NULL, 0x16c0, 0x0763);
166
- if (!devh) {
167
- fprintf(stderr, "Error finding USB device\n");
168
- goto out;
169
- }
170
-
171
- rc = libusb_claim_interface(devh, 2);
172
- if (rc < 0) {
173
- fprintf(stderr, "Error claiming interface: %s\n", libusb_error_name(rc));
174
- goto out;
175
- }
176
-
177
- benchmark_in(EP_ISO_IN);
178
-
179
- while (!do_exit) {
180
- rc = libusb_handle_events(NULL);
181
- if (rc != LIBUSB_SUCCESS)
182
- break;
183
- }
184
-
185
- /* Measurement has already been done by the signal handler. */
186
-
187
- libusb_release_interface(devh, 0);
188
- out:
189
- if (devh)
190
- libusb_close(devh);
191
- libusb_exit(NULL);
192
- return rc;
193
- }
@@ -1,1130 +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 <stdio.h>
22
- #include <stdint.h>
23
- #include <stdlib.h>
24
- #include <string.h>
25
- #include <stdarg.h>
26
-
27
- #include "libusb.h"
28
-
29
- #if defined(_WIN32)
30
- #define msleep(msecs) Sleep(msecs)
31
- #else
32
- #include <unistd.h>
33
- #define msleep(msecs) usleep(1000*msecs)
34
- #endif
35
-
36
- #if defined(_MSC_VER)
37
- #define snprintf _snprintf
38
- #define putenv _putenv
39
- #endif
40
-
41
- #if !defined(bool)
42
- #define bool int
43
- #endif
44
- #if !defined(true)
45
- #define true (1 == 1)
46
- #endif
47
- #if !defined(false)
48
- #define false (!true)
49
- #endif
50
-
51
- // Future versions of libusb will use usb_interface instead of interface
52
- // in libusb_config_descriptor => catter for that
53
- #define usb_interface interface
54
-
55
- // Global variables
56
- static bool binary_dump = false;
57
- static bool extra_info = false;
58
- static bool force_device_request = false; // For WCID descriptor queries
59
- static const char* binary_name = NULL;
60
-
61
- static int perr(char const *format, ...)
62
- {
63
- va_list args;
64
- int r;
65
-
66
- va_start (args, format);
67
- r = vfprintf(stderr, format, args);
68
- va_end(args);
69
-
70
- return r;
71
- }
72
-
73
- #define ERR_EXIT(errcode) do { perr(" %s\n", libusb_strerror((enum libusb_error)errcode)); return -1; } while (0)
74
- #define CALL_CHECK(fcall) do { r=fcall; if (r < 0) ERR_EXIT(r); } while (0);
75
- #define B(x) (((x)!=0)?1:0)
76
- #define be_to_int32(buf) (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|(buf)[3])
77
-
78
- #define RETRY_MAX 5
79
- #define REQUEST_SENSE_LENGTH 0x12
80
- #define INQUIRY_LENGTH 0x24
81
- #define READ_CAPACITY_LENGTH 0x08
82
-
83
- // HID Class-Specific Requests values. See section 7.2 of the HID specifications
84
- #define HID_GET_REPORT 0x01
85
- #define HID_GET_IDLE 0x02
86
- #define HID_GET_PROTOCOL 0x03
87
- #define HID_SET_REPORT 0x09
88
- #define HID_SET_IDLE 0x0A
89
- #define HID_SET_PROTOCOL 0x0B
90
- #define HID_REPORT_TYPE_INPUT 0x01
91
- #define HID_REPORT_TYPE_OUTPUT 0x02
92
- #define HID_REPORT_TYPE_FEATURE 0x03
93
-
94
- // Mass Storage Requests values. See section 3 of the Bulk-Only Mass Storage Class specifications
95
- #define BOMS_RESET 0xFF
96
- #define BOMS_GET_MAX_LUN 0xFE
97
-
98
- // Section 5.1: Command Block Wrapper (CBW)
99
- struct command_block_wrapper {
100
- uint8_t dCBWSignature[4];
101
- uint32_t dCBWTag;
102
- uint32_t dCBWDataTransferLength;
103
- uint8_t bmCBWFlags;
104
- uint8_t bCBWLUN;
105
- uint8_t bCBWCBLength;
106
- uint8_t CBWCB[16];
107
- };
108
-
109
- // Section 5.2: Command Status Wrapper (CSW)
110
- struct command_status_wrapper {
111
- uint8_t dCSWSignature[4];
112
- uint32_t dCSWTag;
113
- uint32_t dCSWDataResidue;
114
- uint8_t bCSWStatus;
115
- };
116
-
117
- static uint8_t cdb_length[256] = {
118
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
119
- 06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06, // 0
120
- 06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06, // 1
121
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 2
122
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 3
123
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 4
124
- 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 5
125
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // 6
126
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // 7
127
- 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, // 8
128
- 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, // 9
129
- 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // A
130
- 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // B
131
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // C
132
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // D
133
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // E
134
- 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // F
135
- };
136
-
137
- static enum test_type {
138
- USE_GENERIC,
139
- USE_PS3,
140
- USE_XBOX,
141
- USE_SCSI,
142
- USE_HID,
143
- } test_mode;
144
- static uint16_t VID, PID;
145
-
146
- static void display_buffer_hex(unsigned char *buffer, unsigned size)
147
- {
148
- unsigned i, j, k;
149
-
150
- for (i=0; i<size; i+=16) {
151
- printf("\n %08x ", i);
152
- for(j=0,k=0; k<16; j++,k++) {
153
- if (i+j < size) {
154
- printf("%02x", buffer[i+j]);
155
- } else {
156
- printf(" ");
157
- }
158
- printf(" ");
159
- }
160
- printf(" ");
161
- for(j=0,k=0; k<16; j++,k++) {
162
- if (i+j < size) {
163
- if ((buffer[i+j] < 32) || (buffer[i+j] > 126)) {
164
- printf(".");
165
- } else {
166
- printf("%c", buffer[i+j]);
167
- }
168
- }
169
- }
170
- }
171
- printf("\n" );
172
- }
173
-
174
- static char* uuid_to_string(const uint8_t* uuid)
175
- {
176
- static char uuid_string[40];
177
- if (uuid == NULL) return NULL;
178
- sprintf(uuid_string, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
179
- uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
180
- uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
181
- return uuid_string;
182
- }
183
-
184
- // The PS3 Controller is really a HID device that got its HID Report Descriptors
185
- // removed by Sony
186
- static int display_ps3_status(libusb_device_handle *handle)
187
- {
188
- int r;
189
- uint8_t input_report[49];
190
- uint8_t master_bt_address[8];
191
- uint8_t device_bt_address[18];
192
-
193
- // Get the controller's bluetooth address of its master device
194
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
195
- HID_GET_REPORT, 0x03f5, 0, master_bt_address, sizeof(master_bt_address), 100));
196
- printf("\nMaster's bluetooth address: %02X:%02X:%02X:%02X:%02X:%02X\n", master_bt_address[2], master_bt_address[3],
197
- master_bt_address[4], master_bt_address[5], master_bt_address[6], master_bt_address[7]);
198
-
199
- // Get the controller's bluetooth address
200
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
201
- HID_GET_REPORT, 0x03f2, 0, device_bt_address, sizeof(device_bt_address), 100));
202
- printf("\nMaster's bluetooth address: %02X:%02X:%02X:%02X:%02X:%02X\n", device_bt_address[4], device_bt_address[5],
203
- device_bt_address[6], device_bt_address[7], device_bt_address[8], device_bt_address[9]);
204
-
205
- // Get the status of the controller's buttons via its HID report
206
- printf("\nReading PS3 Input Report...\n");
207
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
208
- HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x01, 0, input_report, sizeof(input_report), 1000));
209
- switch(input_report[2]){ /** Direction pad plus start, select, and joystick buttons */
210
- case 0x01:
211
- printf("\tSELECT pressed\n");
212
- break;
213
- case 0x02:
214
- printf("\tLEFT 3 pressed\n");
215
- break;
216
- case 0x04:
217
- printf("\tRIGHT 3 pressed\n");
218
- break;
219
- case 0x08:
220
- printf("\tSTART presed\n");
221
- break;
222
- case 0x10:
223
- printf("\tUP pressed\n");
224
- break;
225
- case 0x20:
226
- printf("\tRIGHT pressed\n");
227
- break;
228
- case 0x40:
229
- printf("\tDOWN pressed\n");
230
- break;
231
- case 0x80:
232
- printf("\tLEFT pressed\n");
233
- break;
234
- }
235
- switch(input_report[3]){ /** Shapes plus top right and left buttons */
236
- case 0x01:
237
- printf("\tLEFT 2 pressed\n");
238
- break;
239
- case 0x02:
240
- printf("\tRIGHT 2 pressed\n");
241
- break;
242
- case 0x04:
243
- printf("\tLEFT 1 pressed\n");
244
- break;
245
- case 0x08:
246
- printf("\tRIGHT 1 presed\n");
247
- break;
248
- case 0x10:
249
- printf("\tTRIANGLE pressed\n");
250
- break;
251
- case 0x20:
252
- printf("\tCIRCLE pressed\n");
253
- break;
254
- case 0x40:
255
- printf("\tCROSS pressed\n");
256
- break;
257
- case 0x80:
258
- printf("\tSQUARE pressed\n");
259
- break;
260
- }
261
- printf("\tPS button: %d\n", input_report[4]);
262
- printf("\tLeft Analog (X,Y): (%d,%d)\n", input_report[6], input_report[7]);
263
- printf("\tRight Analog (X,Y): (%d,%d)\n", input_report[8], input_report[9]);
264
- printf("\tL2 Value: %d\tR2 Value: %d\n", input_report[18], input_report[19]);
265
- printf("\tL1 Value: %d\tR1 Value: %d\n", input_report[20], input_report[21]);
266
- printf("\tRoll (x axis): %d Yaw (y axis): %d Pitch (z axis) %d\n",
267
- //(((input_report[42] + 128) % 256) - 128),
268
- (int8_t)(input_report[42]),
269
- (int8_t)(input_report[44]),
270
- (int8_t)(input_report[46]));
271
- printf("\tAcceleration: %d\n\n", (int8_t)(input_report[48]));
272
- return 0;
273
- }
274
- // The XBOX Controller is really a HID device that got its HID Report Descriptors
275
- // removed by Microsoft.
276
- // Input/Output reports described at http://euc.jp/periphs/xbox-controller.ja.html
277
- static int display_xbox_status(libusb_device_handle *handle)
278
- {
279
- int r;
280
- uint8_t input_report[20];
281
- printf("\nReading XBox Input Report...\n");
282
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
283
- HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, input_report, 20, 1000));
284
- printf(" D-pad: %02X\n", input_report[2]&0x0F);
285
- printf(" Start:%d, Back:%d, Left Stick Press:%d, Right Stick Press:%d\n", B(input_report[2]&0x10), B(input_report[2]&0x20),
286
- B(input_report[2]&0x40), B(input_report[2]&0x80));
287
- // A, B, X, Y, Black, White are pressure sensitive
288
- printf(" A:%d, B:%d, X:%d, Y:%d, White:%d, Black:%d\n", input_report[4], input_report[5],
289
- input_report[6], input_report[7], input_report[9], input_report[8]);
290
- printf(" Left Trigger: %d, Right Trigger: %d\n", input_report[10], input_report[11]);
291
- printf(" Left Analog (X,Y): (%d,%d)\n", (int16_t)((input_report[13]<<8)|input_report[12]),
292
- (int16_t)((input_report[15]<<8)|input_report[14]));
293
- printf(" Right Analog (X,Y): (%d,%d)\n", (int16_t)((input_report[17]<<8)|input_report[16]),
294
- (int16_t)((input_report[19]<<8)|input_report[18]));
295
- return 0;
296
- }
297
-
298
- static int set_xbox_actuators(libusb_device_handle *handle, uint8_t left, uint8_t right)
299
- {
300
- int r;
301
- uint8_t output_report[6];
302
-
303
- printf("\nWriting XBox Controller Output Report...\n");
304
-
305
- memset(output_report, 0, sizeof(output_report));
306
- output_report[1] = sizeof(output_report);
307
- output_report[3] = left;
308
- output_report[5] = right;
309
-
310
- CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
311
- HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT<<8)|0x00, 0, output_report, 06, 1000));
312
- return 0;
313
- }
314
-
315
- static int send_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint, uint8_t lun,
316
- uint8_t *cdb, uint8_t direction, int data_length, uint32_t *ret_tag)
317
- {
318
- static uint32_t tag = 1;
319
- uint8_t cdb_len;
320
- int i, r, size;
321
- struct command_block_wrapper cbw;
322
-
323
- if (cdb == NULL) {
324
- return -1;
325
- }
326
-
327
- if (endpoint & LIBUSB_ENDPOINT_IN) {
328
- perr("send_mass_storage_command: cannot send command on IN endpoint\n");
329
- return -1;
330
- }
331
-
332
- cdb_len = cdb_length[cdb[0]];
333
- if ((cdb_len == 0) || (cdb_len > sizeof(cbw.CBWCB))) {
334
- perr("send_mass_storage_command: don't know how to handle this command (%02X, length %d)\n",
335
- cdb[0], cdb_len);
336
- return -1;
337
- }
338
-
339
- memset(&cbw, 0, sizeof(cbw));
340
- cbw.dCBWSignature[0] = 'U';
341
- cbw.dCBWSignature[1] = 'S';
342
- cbw.dCBWSignature[2] = 'B';
343
- cbw.dCBWSignature[3] = 'C';
344
- *ret_tag = tag;
345
- cbw.dCBWTag = tag++;
346
- cbw.dCBWDataTransferLength = data_length;
347
- cbw.bmCBWFlags = direction;
348
- cbw.bCBWLUN = lun;
349
- // Subclass is 1 or 6 => cdb_len
350
- cbw.bCBWCBLength = cdb_len;
351
- memcpy(cbw.CBWCB, cdb, cdb_len);
352
-
353
- i = 0;
354
- do {
355
- // The transfer length must always be exactly 31 bytes.
356
- r = libusb_bulk_transfer(handle, endpoint, (unsigned char*)&cbw, 31, &size, 1000);
357
- if (r == LIBUSB_ERROR_PIPE) {
358
- libusb_clear_halt(handle, endpoint);
359
- }
360
- i++;
361
- } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
362
- if (r != LIBUSB_SUCCESS) {
363
- perr(" send_mass_storage_command: %s\n", libusb_strerror((enum libusb_error)r));
364
- return -1;
365
- }
366
-
367
- printf(" sent %d CDB bytes\n", cdb_len);
368
- return 0;
369
- }
370
-
371
- static int get_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t expected_tag)
372
- {
373
- int i, r, size;
374
- struct command_status_wrapper csw;
375
-
376
- // The device is allowed to STALL this transfer. If it does, you have to
377
- // clear the stall and try again.
378
- i = 0;
379
- do {
380
- r = libusb_bulk_transfer(handle, endpoint, (unsigned char*)&csw, 13, &size, 1000);
381
- if (r == LIBUSB_ERROR_PIPE) {
382
- libusb_clear_halt(handle, endpoint);
383
- }
384
- i++;
385
- } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
386
- if (r != LIBUSB_SUCCESS) {
387
- perr(" get_mass_storage_status: %s\n", libusb_strerror((enum libusb_error)r));
388
- return -1;
389
- }
390
- if (size != 13) {
391
- perr(" get_mass_storage_status: received %d bytes (expected 13)\n", size);
392
- return -1;
393
- }
394
- if (csw.dCSWTag != expected_tag) {
395
- perr(" get_mass_storage_status: mismatched tags (expected %08X, received %08X)\n",
396
- expected_tag, csw.dCSWTag);
397
- return -1;
398
- }
399
- // For this test, we ignore the dCSWSignature check for validity...
400
- printf(" Mass Storage Status: %02X (%s)\n", csw.bCSWStatus, csw.bCSWStatus?"FAILED":"Success");
401
- if (csw.dCSWTag != expected_tag)
402
- return -1;
403
- if (csw.bCSWStatus) {
404
- // REQUEST SENSE is appropriate only if bCSWStatus is 1, meaning that the
405
- // command failed somehow. Larger values (2 in particular) mean that
406
- // the command couldn't be understood.
407
- if (csw.bCSWStatus == 1)
408
- return -2; // request Get Sense
409
- else
410
- return -1;
411
- }
412
-
413
- // In theory we also should check dCSWDataResidue. But lots of devices
414
- // set it wrongly.
415
- return 0;
416
- }
417
-
418
- static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out)
419
- {
420
- uint8_t cdb[16]; // SCSI Command Descriptor Block
421
- uint8_t sense[18];
422
- uint32_t expected_tag;
423
- int size;
424
- int rc;
425
-
426
- // Request Sense
427
- printf("Request Sense:\n");
428
- memset(sense, 0, sizeof(sense));
429
- memset(cdb, 0, sizeof(cdb));
430
- cdb[0] = 0x03; // Request Sense
431
- cdb[4] = REQUEST_SENSE_LENGTH;
432
-
433
- send_mass_storage_command(handle, endpoint_out, 0, cdb, LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH, &expected_tag);
434
- rc = libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&sense, REQUEST_SENSE_LENGTH, &size, 1000);
435
- if (rc < 0)
436
- {
437
- printf("libusb_bulk_transfer failed: %s\n", libusb_error_name(rc));
438
- return;
439
- }
440
- printf(" received %d bytes\n", size);
441
-
442
- if ((sense[0] != 0x70) && (sense[0] != 0x71)) {
443
- perr(" ERROR No sense data\n");
444
- } else {
445
- perr(" ERROR Sense: %02X %02X %02X\n", sense[2]&0x0F, sense[12], sense[13]);
446
- }
447
- // Strictly speaking, the get_mass_storage_status() call should come
448
- // before these perr() lines. If the status is nonzero then we must
449
- // assume there's no data in the buffer. For xusb it doesn't matter.
450
- get_mass_storage_status(handle, endpoint_in, expected_tag);
451
- }
452
-
453
- // Mass Storage device to test bulk transfers (non destructive test)
454
- static int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out)
455
- {
456
- int r, size;
457
- uint8_t lun;
458
- uint32_t expected_tag;
459
- uint32_t i, max_lba, block_size;
460
- double device_size;
461
- uint8_t cdb[16]; // SCSI Command Descriptor Block
462
- uint8_t buffer[64];
463
- char vid[9], pid[9], rev[5];
464
- unsigned char *data;
465
- FILE *fd;
466
-
467
- printf("Reading Max LUN:\n");
468
- r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
469
- BOMS_GET_MAX_LUN, 0, 0, &lun, 1, 1000);
470
- // Some devices send a STALL instead of the actual value.
471
- // In such cases we should set lun to 0.
472
- if (r == 0) {
473
- lun = 0;
474
- } else if (r < 0) {
475
- perr(" Failed: %s", libusb_strerror((enum libusb_error)r));
476
- }
477
- printf(" Max LUN = %d\n", lun);
478
-
479
- // Send Inquiry
480
- printf("Sending Inquiry:\n");
481
- memset(buffer, 0, sizeof(buffer));
482
- memset(cdb, 0, sizeof(cdb));
483
- cdb[0] = 0x12; // Inquiry
484
- cdb[4] = INQUIRY_LENGTH;
485
-
486
- send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, INQUIRY_LENGTH, &expected_tag);
487
- CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, INQUIRY_LENGTH, &size, 1000));
488
- printf(" received %d bytes\n", size);
489
- // The following strings are not zero terminated
490
- for (i=0; i<8; i++) {
491
- vid[i] = buffer[8+i];
492
- pid[i] = buffer[16+i];
493
- rev[i/2] = buffer[32+i/2]; // instead of another loop
494
- }
495
- vid[8] = 0;
496
- pid[8] = 0;
497
- rev[4] = 0;
498
- printf(" VID:PID:REV \"%8s\":\"%8s\":\"%4s\"\n", vid, pid, rev);
499
- if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
500
- get_sense(handle, endpoint_in, endpoint_out);
501
- }
502
-
503
- // Read capacity
504
- printf("Reading Capacity:\n");
505
- memset(buffer, 0, sizeof(buffer));
506
- memset(cdb, 0, sizeof(cdb));
507
- cdb[0] = 0x25; // Read Capacity
508
-
509
- send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, READ_CAPACITY_LENGTH, &expected_tag);
510
- CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, READ_CAPACITY_LENGTH, &size, 1000));
511
- printf(" received %d bytes\n", size);
512
- max_lba = be_to_int32(&buffer[0]);
513
- block_size = be_to_int32(&buffer[4]);
514
- device_size = ((double)(max_lba+1))*block_size/(1024*1024*1024);
515
- printf(" Max LBA: %08X, Block Size: %08X (%.2f GB)\n", max_lba, block_size, device_size);
516
- if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
517
- get_sense(handle, endpoint_in, endpoint_out);
518
- }
519
-
520
- // coverity[tainted_data]
521
- data = (unsigned char*) calloc(1, block_size);
522
- if (data == NULL) {
523
- perr(" unable to allocate data buffer\n");
524
- return -1;
525
- }
526
-
527
- // Send Read
528
- printf("Attempting to read %d bytes:\n", block_size);
529
- memset(cdb, 0, sizeof(cdb));
530
-
531
- cdb[0] = 0x28; // Read(10)
532
- cdb[8] = 0x01; // 1 block
533
-
534
- send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, block_size, &expected_tag);
535
- libusb_bulk_transfer(handle, endpoint_in, data, block_size, &size, 5000);
536
- printf(" READ: received %d bytes\n", size);
537
- if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
538
- get_sense(handle, endpoint_in, endpoint_out);
539
- } else {
540
- display_buffer_hex(data, size);
541
- if ((binary_dump) && ((fd = fopen(binary_name, "w")) != NULL)) {
542
- if (fwrite(data, 1, (size_t)size, fd) != (unsigned int)size) {
543
- perr(" unable to write binary data\n");
544
- }
545
- fclose(fd);
546
- }
547
- }
548
- free(data);
549
-
550
- return 0;
551
- }
552
-
553
- // HID
554
- static int get_hid_record_size(uint8_t *hid_report_descriptor, int size, int type)
555
- {
556
- uint8_t i, j = 0;
557
- uint8_t offset;
558
- int record_size[3] = {0, 0, 0};
559
- int nb_bits = 0, nb_items = 0;
560
- bool found_record_marker;
561
-
562
- found_record_marker = false;
563
- for (i = hid_report_descriptor[0]+1; i < size; i += offset) {
564
- offset = (hid_report_descriptor[i]&0x03) + 1;
565
- if (offset == 4)
566
- offset = 5;
567
- switch (hid_report_descriptor[i] & 0xFC) {
568
- case 0x74: // bitsize
569
- nb_bits = hid_report_descriptor[i+1];
570
- break;
571
- case 0x94: // count
572
- nb_items = 0;
573
- for (j=1; j<offset; j++) {
574
- nb_items = ((uint32_t)hid_report_descriptor[i+j]) << (8*(j-1));
575
- }
576
- break;
577
- case 0x80: // input
578
- found_record_marker = true;
579
- j = 0;
580
- break;
581
- case 0x90: // output
582
- found_record_marker = true;
583
- j = 1;
584
- break;
585
- case 0xb0: // feature
586
- found_record_marker = true;
587
- j = 2;
588
- break;
589
- case 0xC0: // end of collection
590
- nb_items = 0;
591
- nb_bits = 0;
592
- break;
593
- default:
594
- continue;
595
- }
596
- if (found_record_marker) {
597
- found_record_marker = false;
598
- record_size[j] += nb_items*nb_bits;
599
- }
600
- }
601
- if ((type < HID_REPORT_TYPE_INPUT) || (type > HID_REPORT_TYPE_FEATURE)) {
602
- return 0;
603
- } else {
604
- return (record_size[type - HID_REPORT_TYPE_INPUT]+7)/8;
605
- }
606
- }
607
-
608
- static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
609
- {
610
- int r, size, descriptor_size;
611
- uint8_t hid_report_descriptor[256];
612
- uint8_t *report_buffer;
613
- FILE *fd;
614
-
615
- printf("\nReading HID Report Descriptors:\n");
616
- descriptor_size = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_STANDARD|LIBUSB_RECIPIENT_INTERFACE,
617
- LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_REPORT<<8, 0, hid_report_descriptor, sizeof(hid_report_descriptor), 1000);
618
- if (descriptor_size < 0) {
619
- printf(" Failed\n");
620
- return -1;
621
- }
622
- display_buffer_hex(hid_report_descriptor, descriptor_size);
623
- if ((binary_dump) && ((fd = fopen(binary_name, "w")) != NULL)) {
624
- if (fwrite(hid_report_descriptor, 1, descriptor_size, fd) != descriptor_size) {
625
- printf(" Error writing descriptor to file\n");
626
- }
627
- fclose(fd);
628
- }
629
-
630
- size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_FEATURE);
631
- if (size <= 0) {
632
- printf("\nSkipping Feature Report readout (None detected)\n");
633
- } else {
634
- report_buffer = (uint8_t*) calloc(size, 1);
635
- if (report_buffer == NULL) {
636
- return -1;
637
- }
638
-
639
- printf("\nReading Feature Report (length %d)...\n", size);
640
- r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
641
- HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, report_buffer, (uint16_t)size, 5000);
642
- if (r >= 0) {
643
- display_buffer_hex(report_buffer, size);
644
- } else {
645
- switch(r) {
646
- case LIBUSB_ERROR_NOT_FOUND:
647
- printf(" No Feature Report available for this device\n");
648
- break;
649
- case LIBUSB_ERROR_PIPE:
650
- printf(" Detected stall - resetting pipe...\n");
651
- libusb_clear_halt(handle, 0);
652
- break;
653
- default:
654
- printf(" Error: %s\n", libusb_strerror((enum libusb_error)r));
655
- break;
656
- }
657
- }
658
- free(report_buffer);
659
- }
660
-
661
- size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_INPUT);
662
- if (size <= 0) {
663
- printf("\nSkipping Input Report readout (None detected)\n");
664
- } else {
665
- report_buffer = (uint8_t*) calloc(size, 1);
666
- if (report_buffer == NULL) {
667
- return -1;
668
- }
669
-
670
- printf("\nReading Input Report (length %d)...\n", size);
671
- r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
672
- HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, report_buffer, (uint16_t)size, 5000);
673
- if (r >= 0) {
674
- display_buffer_hex(report_buffer, size);
675
- } else {
676
- switch(r) {
677
- case LIBUSB_ERROR_TIMEOUT:
678
- printf(" Timeout! Please make sure you act on the device within the 5 seconds allocated...\n");
679
- break;
680
- case LIBUSB_ERROR_PIPE:
681
- printf(" Detected stall - resetting pipe...\n");
682
- libusb_clear_halt(handle, 0);
683
- break;
684
- default:
685
- printf(" Error: %s\n", libusb_strerror((enum libusb_error)r));
686
- break;
687
- }
688
- }
689
-
690
- // Attempt a bulk read from endpoint 0 (this should just return a raw input report)
691
- printf("\nTesting interrupt read using endpoint %02X...\n", endpoint_in);
692
- r = libusb_interrupt_transfer(handle, endpoint_in, report_buffer, size, &size, 5000);
693
- if (r >= 0) {
694
- display_buffer_hex(report_buffer, size);
695
- } else {
696
- printf(" %s\n", libusb_strerror((enum libusb_error)r));
697
- }
698
-
699
- free(report_buffer);
700
- }
701
- return 0;
702
- }
703
-
704
- // Read the MS WinUSB Feature Descriptors, that are used on Windows 8 for automated driver installation
705
- static void read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uint8_t bRequest, int iface_number)
706
- {
707
- #define MAX_OS_FD_LENGTH 256
708
- int i, r;
709
- uint8_t os_desc[MAX_OS_FD_LENGTH];
710
- uint32_t length;
711
- void* le_type_punning_IS_fine;
712
- struct {
713
- const char* desc;
714
- uint8_t recipient;
715
- uint16_t index;
716
- uint16_t header_size;
717
- } os_fd[2] = {
718
- {"Extended Compat ID", LIBUSB_RECIPIENT_DEVICE, 0x0004, 0x10},
719
- {"Extended Properties", LIBUSB_RECIPIENT_INTERFACE, 0x0005, 0x0A}
720
- };
721
-
722
- if (iface_number < 0) return;
723
- // WinUSB has a limitation that forces wIndex to the interface number when issuing
724
- // an Interface Request. To work around that, we can force a Device Request for
725
- // the Extended Properties, assuming the device answers both equally.
726
- if (force_device_request)
727
- os_fd[1].recipient = LIBUSB_RECIPIENT_DEVICE;
728
-
729
- for (i=0; i<2; i++) {
730
- printf("\nReading %s OS Feature Descriptor (wIndex = 0x%04d):\n", os_fd[i].desc, os_fd[i].index);
731
-
732
- // Read the header part
733
- r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
734
- bRequest, (uint16_t)(((iface_number)<< 8)|0x00), os_fd[i].index, os_desc, os_fd[i].header_size, 1000);
735
- if (r < os_fd[i].header_size) {
736
- perr(" Failed: %s", (r<0)?libusb_strerror((enum libusb_error)r):"header size is too small");
737
- return;
738
- }
739
- le_type_punning_IS_fine = (void*)os_desc;
740
- length = *((uint32_t*)le_type_punning_IS_fine);
741
- if (length > MAX_OS_FD_LENGTH) {
742
- length = MAX_OS_FD_LENGTH;
743
- }
744
-
745
- // Read the full feature descriptor
746
- r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
747
- bRequest, (uint16_t)(((iface_number)<< 8)|0x00), os_fd[i].index, os_desc, (uint16_t)length, 1000);
748
- if (r < 0) {
749
- perr(" Failed: %s", libusb_strerror((enum libusb_error)r));
750
- return;
751
- } else {
752
- display_buffer_hex(os_desc, r);
753
- }
754
- }
755
- }
756
-
757
- static void print_device_cap(struct libusb_bos_dev_capability_descriptor *dev_cap)
758
- {
759
- switch(dev_cap->bDevCapabilityType) {
760
- case LIBUSB_BT_USB_2_0_EXTENSION: {
761
- struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext = NULL;
762
- libusb_get_usb_2_0_extension_descriptor(NULL, dev_cap, &usb_2_0_ext);
763
- if (usb_2_0_ext) {
764
- printf(" USB 2.0 extension:\n");
765
- printf(" attributes : %02X\n", usb_2_0_ext->bmAttributes);
766
- libusb_free_usb_2_0_extension_descriptor(usb_2_0_ext);
767
- }
768
- break;
769
- }
770
- case LIBUSB_BT_SS_USB_DEVICE_CAPABILITY: {
771
- struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap = NULL;
772
- libusb_get_ss_usb_device_capability_descriptor(NULL, dev_cap, &ss_usb_device_cap);
773
- if (ss_usb_device_cap) {
774
- printf(" USB 3.0 capabilities:\n");
775
- printf(" attributes : %02X\n", ss_usb_device_cap->bmAttributes);
776
- printf(" supported speeds : %04X\n", ss_usb_device_cap->wSpeedSupported);
777
- printf(" supported functionality: %02X\n", ss_usb_device_cap->bFunctionalitySupport);
778
- libusb_free_ss_usb_device_capability_descriptor(ss_usb_device_cap);
779
- }
780
- break;
781
- }
782
- case LIBUSB_BT_CONTAINER_ID: {
783
- struct libusb_container_id_descriptor *container_id = NULL;
784
- libusb_get_container_id_descriptor(NULL, dev_cap, &container_id);
785
- if (container_id) {
786
- printf(" Container ID:\n %s\n", uuid_to_string(container_id->ContainerID));
787
- libusb_free_container_id_descriptor(container_id);
788
- }
789
- break;
790
- }
791
- default:
792
- printf(" Unknown BOS device capability %02x:\n", dev_cap->bDevCapabilityType);
793
- }
794
- }
795
-
796
- static int test_device(uint16_t vid, uint16_t pid)
797
- {
798
- libusb_device_handle *handle;
799
- libusb_device *dev;
800
- uint8_t bus, port_path[8];
801
- struct libusb_bos_descriptor *bos_desc;
802
- struct libusb_config_descriptor *conf_desc;
803
- const struct libusb_endpoint_descriptor *endpoint;
804
- int i, j, k, r;
805
- int iface, nb_ifaces, first_iface = -1;
806
- struct libusb_device_descriptor dev_desc;
807
- const char* speed_name[5] = { "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)",
808
- "480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)"};
809
- char string[128];
810
- uint8_t string_index[3]; // indexes of the string descriptors
811
- uint8_t endpoint_in = 0, endpoint_out = 0; // default IN and OUT endpoints
812
-
813
- printf("Opening device %04X:%04X...\n", vid, pid);
814
- handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
815
-
816
- if (handle == NULL) {
817
- perr(" Failed.\n");
818
- return -1;
819
- }
820
-
821
- dev = libusb_get_device(handle);
822
- bus = libusb_get_bus_number(dev);
823
- if (extra_info) {
824
- r = libusb_get_port_numbers(dev, port_path, sizeof(port_path));
825
- if (r > 0) {
826
- printf("\nDevice properties:\n");
827
- printf(" bus number: %d\n", bus);
828
- printf(" port path: %d", port_path[0]);
829
- for (i=1; i<r; i++) {
830
- printf("->%d", port_path[i]);
831
- }
832
- printf(" (from root hub)\n");
833
- }
834
- r = libusb_get_device_speed(dev);
835
- if ((r<0) || (r>4)) r=0;
836
- printf(" speed: %s\n", speed_name[r]);
837
- }
838
-
839
- printf("\nReading device descriptor:\n");
840
- CALL_CHECK(libusb_get_device_descriptor(dev, &dev_desc));
841
- printf(" length: %d\n", dev_desc.bLength);
842
- printf(" device class: %d\n", dev_desc.bDeviceClass);
843
- printf(" S/N: %d\n", dev_desc.iSerialNumber);
844
- printf(" VID:PID: %04X:%04X\n", dev_desc.idVendor, dev_desc.idProduct);
845
- printf(" bcdDevice: %04X\n", dev_desc.bcdDevice);
846
- printf(" iMan:iProd:iSer: %d:%d:%d\n", dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber);
847
- printf(" nb confs: %d\n", dev_desc.bNumConfigurations);
848
- // Copy the string descriptors for easier parsing
849
- string_index[0] = dev_desc.iManufacturer;
850
- string_index[1] = dev_desc.iProduct;
851
- string_index[2] = dev_desc.iSerialNumber;
852
-
853
- printf("\nReading BOS descriptor: ");
854
- if (libusb_get_bos_descriptor(handle, &bos_desc) == LIBUSB_SUCCESS) {
855
- printf("%d caps\n", bos_desc->bNumDeviceCaps);
856
- for (i = 0; i < bos_desc->bNumDeviceCaps; i++)
857
- print_device_cap(bos_desc->dev_capability[i]);
858
- libusb_free_bos_descriptor(bos_desc);
859
- } else {
860
- printf("no descriptor\n");
861
- }
862
-
863
- printf("\nReading first configuration descriptor:\n");
864
- CALL_CHECK(libusb_get_config_descriptor(dev, 0, &conf_desc));
865
- nb_ifaces = conf_desc->bNumInterfaces;
866
- printf(" nb interfaces: %d\n", nb_ifaces);
867
- if (nb_ifaces > 0)
868
- first_iface = conf_desc->usb_interface[0].altsetting[0].bInterfaceNumber;
869
- for (i=0; i<nb_ifaces; i++) {
870
- printf(" interface[%d]: id = %d\n", i,
871
- conf_desc->usb_interface[i].altsetting[0].bInterfaceNumber);
872
- for (j=0; j<conf_desc->usb_interface[i].num_altsetting; j++) {
873
- printf("interface[%d].altsetting[%d]: num endpoints = %d\n",
874
- i, j, conf_desc->usb_interface[i].altsetting[j].bNumEndpoints);
875
- printf(" Class.SubClass.Protocol: %02X.%02X.%02X\n",
876
- conf_desc->usb_interface[i].altsetting[j].bInterfaceClass,
877
- conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass,
878
- conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol);
879
- if ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE)
880
- && ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x01)
881
- || (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x06) )
882
- && (conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol == 0x50) ) {
883
- // Mass storage devices that can use basic SCSI commands
884
- test_mode = USE_SCSI;
885
- }
886
- for (k=0; k<conf_desc->usb_interface[i].altsetting[j].bNumEndpoints; k++) {
887
- struct libusb_ss_endpoint_companion_descriptor *ep_comp = NULL;
888
- endpoint = &conf_desc->usb_interface[i].altsetting[j].endpoint[k];
889
- printf(" endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress);
890
- // Use the first interrupt or bulk IN/OUT endpoints as default for testing
891
- if ((endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) & (LIBUSB_TRANSFER_TYPE_BULK | LIBUSB_TRANSFER_TYPE_INTERRUPT)) {
892
- if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
893
- if (!endpoint_in)
894
- endpoint_in = endpoint->bEndpointAddress;
895
- } else {
896
- if (!endpoint_out)
897
- endpoint_out = endpoint->bEndpointAddress;
898
- }
899
- }
900
- printf(" max packet size: %04X\n", endpoint->wMaxPacketSize);
901
- printf(" polling interval: %02X\n", endpoint->bInterval);
902
- libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);
903
- if (ep_comp) {
904
- printf(" max burst: %02X (USB 3.0)\n", ep_comp->bMaxBurst);
905
- printf(" bytes per interval: %04X (USB 3.0)\n", ep_comp->wBytesPerInterval);
906
- libusb_free_ss_endpoint_companion_descriptor(ep_comp);
907
- }
908
- }
909
- }
910
- }
911
- libusb_free_config_descriptor(conf_desc);
912
-
913
- libusb_set_auto_detach_kernel_driver(handle, 1);
914
- for (iface = 0; iface < nb_ifaces; iface++)
915
- {
916
- printf("\nClaiming interface %d...\n", iface);
917
- r = libusb_claim_interface(handle, iface);
918
- if (r != LIBUSB_SUCCESS) {
919
- perr(" Failed.\n");
920
- }
921
- }
922
-
923
- printf("\nReading string descriptors:\n");
924
- for (i=0; i<3; i++) {
925
- if (string_index[i] == 0) {
926
- continue;
927
- }
928
- if (libusb_get_string_descriptor_ascii(handle, string_index[i], (unsigned char*)string, 128) >= 0) {
929
- printf(" String (0x%02X): \"%s\"\n", string_index[i], string);
930
- }
931
- }
932
- // Read the OS String Descriptor
933
- if (libusb_get_string_descriptor_ascii(handle, 0xEE, (unsigned char*)string, 128) >= 0) {
934
- printf(" String (0x%02X): \"%s\"\n", 0xEE, string);
935
- // If this is a Microsoft OS String Descriptor,
936
- // attempt to read the WinUSB extended Feature Descriptors
937
- if (strncmp(string, "MSFT100", 7) == 0)
938
- read_ms_winsub_feature_descriptors(handle, string[7], first_iface);
939
- }
940
-
941
- switch(test_mode) {
942
- case USE_PS3:
943
- CALL_CHECK(display_ps3_status(handle));
944
- break;
945
- case USE_XBOX:
946
- CALL_CHECK(display_xbox_status(handle));
947
- CALL_CHECK(set_xbox_actuators(handle, 128, 222));
948
- msleep(2000);
949
- CALL_CHECK(set_xbox_actuators(handle, 0, 0));
950
- break;
951
- case USE_HID:
952
- test_hid(handle, endpoint_in);
953
- break;
954
- case USE_SCSI:
955
- CALL_CHECK(test_mass_storage(handle, endpoint_in, endpoint_out));
956
- case USE_GENERIC:
957
- break;
958
- }
959
-
960
- printf("\n");
961
- for (iface = 0; iface<nb_ifaces; iface++) {
962
- printf("Releasing interface %d...\n", iface);
963
- libusb_release_interface(handle, iface);
964
- }
965
-
966
- printf("Closing device...\n");
967
- libusb_close(handle);
968
-
969
- return 0;
970
- }
971
-
972
- int main(int argc, char** argv)
973
- {
974
- bool show_help = false;
975
- bool debug_mode = false;
976
- const struct libusb_version* version;
977
- int j, r;
978
- size_t i, arglen;
979
- unsigned tmp_vid, tmp_pid;
980
- uint16_t endian_test = 0xBE00;
981
- char *error_lang = NULL, *old_dbg_str = NULL, str[256];
982
-
983
- // Default to generic, expecting VID:PID
984
- VID = 0;
985
- PID = 0;
986
- test_mode = USE_GENERIC;
987
-
988
- if (((uint8_t*)&endian_test)[0] == 0xBE) {
989
- printf("Despite their natural superiority for end users, big endian\n"
990
- "CPUs are not supported with this program, sorry.\n");
991
- return 0;
992
- }
993
-
994
- if (argc >= 2) {
995
- for (j = 1; j<argc; j++) {
996
- arglen = strlen(argv[j]);
997
- if ( ((argv[j][0] == '-') || (argv[j][0] == '/'))
998
- && (arglen >= 2) ) {
999
- switch(argv[j][1]) {
1000
- case 'd':
1001
- debug_mode = true;
1002
- break;
1003
- case 'i':
1004
- extra_info = true;
1005
- break;
1006
- case 'w':
1007
- force_device_request = true;
1008
- break;
1009
- case 'b':
1010
- if ((j+1 >= argc) || (argv[j+1][0] == '-') || (argv[j+1][0] == '/')) {
1011
- printf(" Option -b requires a file name\n");
1012
- return 1;
1013
- }
1014
- binary_name = argv[++j];
1015
- binary_dump = true;
1016
- break;
1017
- case 'l':
1018
- if ((j+1 >= argc) || (argv[j+1][0] == '-') || (argv[j+1][0] == '/')) {
1019
- printf(" Option -l requires an ISO 639-1 language parameter\n");
1020
- return 1;
1021
- }
1022
- error_lang = argv[++j];
1023
- break;
1024
- case 'j':
1025
- // OLIMEX ARM-USB-TINY JTAG, 2 channel composite device - 2 interfaces
1026
- if (!VID && !PID) {
1027
- VID = 0x15BA;
1028
- PID = 0x0004;
1029
- }
1030
- break;
1031
- case 'k':
1032
- // Generic 2 GB USB Key (SCSI Transparent/Bulk Only) - 1 interface
1033
- if (!VID && !PID) {
1034
- VID = 0x0204;
1035
- PID = 0x6025;
1036
- }
1037
- break;
1038
- // The following tests will force VID:PID if already provided
1039
- case 'p':
1040
- // Sony PS3 Controller - 1 interface
1041
- VID = 0x054C;
1042
- PID = 0x0268;
1043
- test_mode = USE_PS3;
1044
- break;
1045
- case 's':
1046
- // Microsoft Sidewinder Precision Pro Joystick - 1 HID interface
1047
- VID = 0x045E;
1048
- PID = 0x0008;
1049
- test_mode = USE_HID;
1050
- break;
1051
- case 'x':
1052
- // Microsoft XBox Controller Type S - 1 interface
1053
- VID = 0x045E;
1054
- PID = 0x0289;
1055
- test_mode = USE_XBOX;
1056
- break;
1057
- default:
1058
- show_help = true;
1059
- break;
1060
- }
1061
- } else {
1062
- for (i=0; i<arglen; i++) {
1063
- if (argv[j][i] == ':')
1064
- break;
1065
- }
1066
- if (i != arglen) {
1067
- if (sscanf(argv[j], "%x:%x" , &tmp_vid, &tmp_pid) != 2) {
1068
- printf(" Please specify VID & PID as \"vid:pid\" in hexadecimal format\n");
1069
- return 1;
1070
- }
1071
- VID = (uint16_t)tmp_vid;
1072
- PID = (uint16_t)tmp_pid;
1073
- } else {
1074
- show_help = true;
1075
- }
1076
- }
1077
- }
1078
- }
1079
-
1080
- if ((show_help) || (argc == 1) || (argc > 7)) {
1081
- printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] [-x] [-s] [-p] [-w] [vid:pid]\n", argv[0]);
1082
- printf(" -h : display usage\n");
1083
- printf(" -d : enable debug output\n");
1084
- printf(" -i : print topology and speed info\n");
1085
- printf(" -j : test composite FTDI based JTAG device\n");
1086
- printf(" -k : test Mass Storage device\n");
1087
- printf(" -b file : dump Mass Storage data to file 'file'\n");
1088
- printf(" -p : test Sony PS3 SixAxis controller\n");
1089
- printf(" -s : test Microsoft Sidewinder Precision Pro (HID)\n");
1090
- printf(" -x : test Microsoft XBox Controller Type S\n");
1091
- printf(" -l lang : language to report errors in (ISO 639-1)\n");
1092
- printf(" -w : force the use of device requests when querying WCID descriptors\n");
1093
- printf("If only the vid:pid is provided, xusb attempts to run the most appropriate test\n");
1094
- return 0;
1095
- }
1096
-
1097
- // xusb is commonly used as a debug tool, so it's convenient to have debug output during libusb_init(),
1098
- // but since we can't call on libusb_set_debug() before libusb_init(), we use the env variable method
1099
- old_dbg_str = getenv("LIBUSB_DEBUG");
1100
- if (debug_mode) {
1101
- if (putenv("LIBUSB_DEBUG=4") != 0) // LIBUSB_LOG_LEVEL_DEBUG
1102
- printf("Unable to set debug level");
1103
- }
1104
-
1105
- version = libusb_get_version();
1106
- printf("Using libusb v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);
1107
- r = libusb_init(NULL);
1108
- if (r < 0)
1109
- return r;
1110
-
1111
- // If not set externally, and no debug option was given, use info log level
1112
- if ((old_dbg_str == NULL) && (!debug_mode))
1113
- libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_INFO);
1114
- if (error_lang != NULL) {
1115
- r = libusb_setlocale(error_lang);
1116
- if (r < 0)
1117
- printf("Invalid or unsupported locale '%s': %s\n", error_lang, libusb_strerror((enum libusb_error)r));
1118
- }
1119
-
1120
- test_device(VID, PID);
1121
-
1122
- libusb_exit(NULL);
1123
-
1124
- if (debug_mode) {
1125
- snprintf(str, sizeof(str), "LIBUSB_DEBUG=%s", (old_dbg_str == NULL)?"":old_dbg_str);
1126
- str[sizeof(str) - 1] = 0; // Windows may not NUL terminate the string
1127
- }
1128
-
1129
- return 0;
1130
- }