libusb 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -0
- data/History.md +10 -0
- data/README.md +19 -6
- data/Rakefile +1 -1
- data/ext/extconf.rb +17 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
- data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
- data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
- data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
- data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
- data/ext/libusbx-1.0.17/android/README +114 -0
- data/ext/libusbx-1.0.17/android/config.h +90 -0
- data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
- data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
- data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
- data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
- data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
- data/ext/libusbx-1.0.17/compile +347 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
- data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
- data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
- data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
- data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
- data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
- data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
- data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
- data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
- data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
- data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
- data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
- data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
- data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
- data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
- data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
- data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
- data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
- data/ext/libusbx-1.0.17/missing +215 -0
- data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
- data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
- data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
- data/ext/libusbx-1.0.17/tests/stress.c +160 -0
- data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
- data/lib/libusb.rb +4 -0
- data/lib/libusb/call.rb +43 -1
- data/lib/libusb/constants.rb +5 -0
- data/lib/libusb/context.rb +100 -0
- data/lib/libusb/dev_handle.rb +27 -0
- data/lib/libusb/device.rb +10 -4
- data/lib/libusb/version_gem.rb +1 -1
- data/test/test_libusb_capability.rb +2 -2
- data/test/test_libusb_compat.rb +2 -2
- data/test/test_libusb_compat_mass_storage.rb +2 -2
- data/test/test_libusb_descriptors.rb +4 -2
- data/test/test_libusb_event_machine.rb +2 -2
- data/test/test_libusb_gc.rb +2 -2
- data/test/test_libusb_hotplug.rb +115 -0
- data/test/test_libusb_iso_transfer.rb +3 -3
- data/test/test_libusb_mass_storage.rb +6 -16
- data/test/test_libusb_mass_storage2.rb +26 -3
- data/test/test_libusb_structs.rb +2 -2
- data/test/test_libusb_threads.rb +2 -2
- data/test/test_libusb_version.rb +2 -2
- metadata +127 -68
- metadata.gz.sig +0 -0
- data/ext/libusbx-1.0.14/THANKS +0 -7
- data/ext/libusbx-1.0.14/compile +0 -143
- data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
- data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
- data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
- data/ext/libusbx-1.0.14/missing +0 -376
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,97 @@
|
|
1
|
+
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
|
2
|
+
/*
|
3
|
+
* libusb example program for hotplug API
|
4
|
+
* Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.ccom>
|
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 <stdlib.h>
|
22
|
+
#include <stdio.h>
|
23
|
+
|
24
|
+
#include "libusb.h"
|
25
|
+
|
26
|
+
int done = 0;
|
27
|
+
libusb_device_handle *handle;
|
28
|
+
|
29
|
+
static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
|
30
|
+
{
|
31
|
+
struct libusb_device_descriptor desc;
|
32
|
+
int rc;
|
33
|
+
|
34
|
+
rc = libusb_get_device_descriptor(dev, &desc);
|
35
|
+
if (LIBUSB_SUCCESS != rc) {
|
36
|
+
fprintf (stderr, "Error getting device descriptor\n");
|
37
|
+
}
|
38
|
+
|
39
|
+
printf ("Device attached: %04x:%04x\n", desc.idVendor, desc.idProduct);
|
40
|
+
|
41
|
+
libusb_open (dev, &handle);
|
42
|
+
|
43
|
+
done++;
|
44
|
+
|
45
|
+
return 0;
|
46
|
+
}
|
47
|
+
|
48
|
+
static int LIBUSB_CALL hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
|
49
|
+
{
|
50
|
+
printf ("Device detached\n");
|
51
|
+
|
52
|
+
libusb_close (handle);
|
53
|
+
|
54
|
+
done++;
|
55
|
+
return 0;
|
56
|
+
}
|
57
|
+
|
58
|
+
int main(int argc, char *argv[])
|
59
|
+
{
|
60
|
+
libusb_hotplug_callback_handle hp[2];
|
61
|
+
int product_id, vendor_id, class_id;
|
62
|
+
int rc;
|
63
|
+
|
64
|
+
vendor_id = (argc > 1) ? strtol (argv[1], NULL, 0) : 0x045a;
|
65
|
+
product_id = (argc > 2) ? strtol (argv[2], NULL, 0) : 0x5005;
|
66
|
+
class_id = (argc > 3) ? strtol (argv[3], NULL, 0) : LIBUSB_HOTPLUG_MATCH_ANY;
|
67
|
+
|
68
|
+
libusb_init (NULL);
|
69
|
+
|
70
|
+
if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
|
71
|
+
printf ("Hotplug capabilites are not supported on this platform\n");
|
72
|
+
libusb_exit (NULL);
|
73
|
+
return EXIT_FAILURE;
|
74
|
+
}
|
75
|
+
|
76
|
+
rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id,
|
77
|
+
product_id, class_id, hotplug_callback, NULL, &hp[0]);
|
78
|
+
if (LIBUSB_SUCCESS != rc) {
|
79
|
+
fprintf (stderr, "Error registering callback 0\n");
|
80
|
+
libusb_exit (NULL);
|
81
|
+
return EXIT_FAILURE;
|
82
|
+
}
|
83
|
+
|
84
|
+
rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id,
|
85
|
+
product_id,class_id, hotplug_callback_detach, NULL, &hp[1]);
|
86
|
+
if (LIBUSB_SUCCESS != rc) {
|
87
|
+
fprintf (stderr, "Error registering callback 1\n");
|
88
|
+
libusb_exit (NULL);
|
89
|
+
return EXIT_FAILURE;
|
90
|
+
}
|
91
|
+
|
92
|
+
while (done < 2) {
|
93
|
+
libusb_handle_events (NULL);
|
94
|
+
}
|
95
|
+
|
96
|
+
libusb_exit (NULL);
|
97
|
+
}
|
@@ -18,14 +18,14 @@
|
|
18
18
|
*/
|
19
19
|
|
20
20
|
#include <stdio.h>
|
21
|
-
#include <sys/types.h>
|
22
21
|
|
23
|
-
#include
|
22
|
+
#include "libusb.h"
|
24
23
|
|
25
24
|
static void print_devs(libusb_device **devs)
|
26
25
|
{
|
27
26
|
libusb_device *dev;
|
28
|
-
int i = 0;
|
27
|
+
int i = 0, j = 0;
|
28
|
+
uint8_t path[8];
|
29
29
|
|
30
30
|
while ((dev = devs[i++]) != NULL) {
|
31
31
|
struct libusb_device_descriptor desc;
|
@@ -35,9 +35,17 @@ static void print_devs(libusb_device **devs)
|
|
35
35
|
return;
|
36
36
|
}
|
37
37
|
|
38
|
-
printf("%04x:%04x (bus %d, device %d)
|
38
|
+
printf("%04x:%04x (bus %d, device %d)",
|
39
39
|
desc.idVendor, desc.idProduct,
|
40
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");
|
41
49
|
}
|
42
50
|
}
|
43
51
|
|
@@ -0,0 +1,193 @@
|
|
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
|
+
}
|
@@ -33,10 +33,6 @@
|
|
33
33
|
#define msleep(msecs) usleep(1000*msecs)
|
34
34
|
#endif
|
35
35
|
|
36
|
-
#if !defined(_MSC_VER) || _MSC_VER<=1200
|
37
|
-
#define sscanf_s sscanf
|
38
|
-
#endif
|
39
|
-
|
40
36
|
#if !defined(bool)
|
41
37
|
#define bool int
|
42
38
|
#endif
|
@@ -47,15 +43,14 @@
|
|
47
43
|
#define false (!true)
|
48
44
|
#endif
|
49
45
|
|
50
|
-
|
51
46
|
// Future versions of libusbx will use usb_interface instead of interface
|
52
47
|
// in libusb_config_descriptor => catter for that
|
53
48
|
#define usb_interface interface
|
54
49
|
|
55
50
|
// Global variables
|
56
|
-
bool binary_dump = false;
|
57
|
-
bool extra_info = false;
|
58
|
-
const char* binary_name = NULL;
|
51
|
+
static bool binary_dump = false;
|
52
|
+
static bool extra_info = false;
|
53
|
+
static const char* binary_name = NULL;
|
59
54
|
|
60
55
|
static int perr(char const *format, ...)
|
61
56
|
{
|
@@ -69,7 +64,7 @@ static int perr(char const *format, ...)
|
|
69
64
|
return r;
|
70
65
|
}
|
71
66
|
|
72
|
-
#define ERR_EXIT(errcode) do { perr(" %s\n",
|
67
|
+
#define ERR_EXIT(errcode) do { perr(" %s\n", libusb_strerror((enum libusb_error)errcode)); return -1; } while (0)
|
73
68
|
#define CALL_CHECK(fcall) do { r=fcall; if (r < 0) ERR_EXIT(r); } while (0);
|
74
69
|
#define B(x) (((x)!=0)?1:0)
|
75
70
|
#define be_to_int32(buf) (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|(buf)[3])
|
@@ -133,14 +128,14 @@ static uint8_t cdb_length[256] = {
|
|
133
128
|
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // F
|
134
129
|
};
|
135
130
|
|
136
|
-
enum test_type {
|
131
|
+
static enum test_type {
|
137
132
|
USE_GENERIC,
|
138
133
|
USE_PS3,
|
139
134
|
USE_XBOX,
|
140
135
|
USE_SCSI,
|
141
136
|
USE_HID,
|
142
137
|
} test_mode;
|
143
|
-
uint16_t VID, PID;
|
138
|
+
static uint16_t VID, PID;
|
144
139
|
|
145
140
|
static void display_buffer_hex(unsigned char *buffer, unsigned size)
|
146
141
|
{
|
@@ -170,6 +165,16 @@ static void display_buffer_hex(unsigned char *buffer, unsigned size)
|
|
170
165
|
printf("\n" );
|
171
166
|
}
|
172
167
|
|
168
|
+
static char* uuid_to_string(const uint8_t* uuid)
|
169
|
+
{
|
170
|
+
static char uuid_string[40];
|
171
|
+
if (uuid == NULL) return NULL;
|
172
|
+
sprintf(uuid_string, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
173
|
+
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
|
174
|
+
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
|
175
|
+
return uuid_string;
|
176
|
+
}
|
177
|
+
|
173
178
|
// The PS3 Controller is really a HID device that got its HID Report Descriptors
|
174
179
|
// removed by Sony
|
175
180
|
static int display_ps3_status(libusb_device_handle *handle)
|
@@ -349,7 +354,7 @@ static int send_mass_storage_command(libusb_device_handle *handle, uint8_t endpo
|
|
349
354
|
i++;
|
350
355
|
} while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
|
351
356
|
if (r != LIBUSB_SUCCESS) {
|
352
|
-
perr(" send_mass_storage_command: %s\n",
|
357
|
+
perr(" send_mass_storage_command: %s\n", libusb_strerror((enum libusb_error)r));
|
353
358
|
return -1;
|
354
359
|
}
|
355
360
|
|
@@ -373,7 +378,7 @@ static int get_mass_storage_status(libusb_device_handle *handle, uint8_t endpoin
|
|
373
378
|
i++;
|
374
379
|
} while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
|
375
380
|
if (r != LIBUSB_SUCCESS) {
|
376
|
-
perr(" get_mass_storage_status: %s\n",
|
381
|
+
perr(" get_mass_storage_status: %s\n", libusb_strerror((enum libusb_error)r));
|
377
382
|
return -1;
|
378
383
|
}
|
379
384
|
if (size != 13) {
|
@@ -455,7 +460,7 @@ static int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in,
|
|
455
460
|
if (r == 0) {
|
456
461
|
lun = 0;
|
457
462
|
} else if (r < 0) {
|
458
|
-
perr(" Failed: %s",
|
463
|
+
perr(" Failed: %s", libusb_strerror((enum libusb_error)r));
|
459
464
|
}
|
460
465
|
printf(" Max LUN = %d\n", lun);
|
461
466
|
|
@@ -633,7 +638,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
|
|
633
638
|
libusb_clear_halt(handle, 0);
|
634
639
|
break;
|
635
640
|
default:
|
636
|
-
printf(" Error: %s\n",
|
641
|
+
printf(" Error: %s\n", libusb_strerror((enum libusb_error)r));
|
637
642
|
break;
|
638
643
|
}
|
639
644
|
}
|
@@ -664,7 +669,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
|
|
664
669
|
libusb_clear_halt(handle, 0);
|
665
670
|
break;
|
666
671
|
default:
|
667
|
-
printf(" Error: %s\n",
|
672
|
+
printf(" Error: %s\n", libusb_strerror((enum libusb_error)r));
|
668
673
|
break;
|
669
674
|
}
|
670
675
|
}
|
@@ -675,7 +680,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
|
|
675
680
|
if (r >= 0) {
|
676
681
|
display_buffer_hex(report_buffer, size);
|
677
682
|
} else {
|
678
|
-
printf(" %s\n",
|
683
|
+
printf(" %s\n", libusb_strerror((enum libusb_error)r));
|
679
684
|
}
|
680
685
|
|
681
686
|
free(report_buffer);
|
@@ -693,11 +698,12 @@ static void read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
|
|
693
698
|
void* le_type_punning_IS_fine;
|
694
699
|
struct {
|
695
700
|
const char* desc;
|
701
|
+
uint8_t recipient;
|
696
702
|
uint16_t index;
|
697
703
|
uint16_t header_size;
|
698
704
|
} os_fd[2] = {
|
699
|
-
{"Extended Compat ID", 0x0004, 0x10},
|
700
|
-
{"Extended Properties", 0x0005, 0x0A}
|
705
|
+
{"Extended Compat ID", LIBUSB_RECIPIENT_DEVICE, 0x0004, 0x10},
|
706
|
+
{"Extended Properties", LIBUSB_RECIPIENT_INTERFACE, 0x0005, 0x0A}
|
701
707
|
};
|
702
708
|
|
703
709
|
if (iface_number < 0) return;
|
@@ -706,10 +712,10 @@ static void read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
|
|
706
712
|
printf("\nReading %s OS Feature Descriptor (wIndex = 0x%04d):\n", os_fd[i].desc, os_fd[i].index);
|
707
713
|
|
708
714
|
// Read the header part
|
709
|
-
r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|
|
715
|
+
r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
|
710
716
|
bRequest, (uint16_t)(((iface_number)<< 8)|0x00), os_fd[i].index, os_desc, os_fd[i].header_size, 1000);
|
711
717
|
if (r < os_fd[i].header_size) {
|
712
|
-
perr(" Failed: %s", (r<0)?
|
718
|
+
perr(" Failed: %s", (r<0)?libusb_strerror((enum libusb_error)r):"header size is too small");
|
713
719
|
return;
|
714
720
|
}
|
715
721
|
le_type_punning_IS_fine = (void*)os_desc;
|
@@ -719,10 +725,10 @@ static void read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
|
|
719
725
|
}
|
720
726
|
|
721
727
|
// Read the full feature descriptor
|
722
|
-
r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|
|
728
|
+
r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
|
723
729
|
bRequest, (uint16_t)(((iface_number)<< 8)|0x00), os_fd[i].index, os_desc, (uint16_t)length, 1000);
|
724
730
|
if (r < 0) {
|
725
|
-
perr(" Failed: %s",
|
731
|
+
perr(" Failed: %s", libusb_strerror((enum libusb_error)r));
|
726
732
|
return;
|
727
733
|
} else {
|
728
734
|
display_buffer_hex(os_desc, r);
|
@@ -730,19 +736,55 @@ static void read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
|
|
730
736
|
}
|
731
737
|
}
|
732
738
|
|
739
|
+
static void print_device_cap(struct libusb_bos_dev_capability_descriptor *dev_cap)
|
740
|
+
{
|
741
|
+
switch(dev_cap->bDevCapabilityType) {
|
742
|
+
case LIBUSB_BT_USB_2_0_EXTENSION: {
|
743
|
+
struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext = NULL;
|
744
|
+
libusb_get_usb_2_0_extension_descriptor(NULL, dev_cap, &usb_2_0_ext);
|
745
|
+
if (usb_2_0_ext) {
|
746
|
+
printf(" USB 2.0 extension:\n");
|
747
|
+
printf(" attributes : %02X\n", usb_2_0_ext->bmAttributes);
|
748
|
+
libusb_free_usb_2_0_extension_descriptor(usb_2_0_ext);
|
749
|
+
}
|
750
|
+
break;
|
751
|
+
}
|
752
|
+
case LIBUSB_BT_SS_USB_DEVICE_CAPABILITY: {
|
753
|
+
struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap = NULL;
|
754
|
+
libusb_get_ss_usb_device_capability_descriptor(NULL, dev_cap, &ss_usb_device_cap);
|
755
|
+
if (ss_usb_device_cap) {
|
756
|
+
printf(" USB 3.0 capabilities:\n");
|
757
|
+
printf(" attributes : %02X\n", ss_usb_device_cap->bmAttributes);
|
758
|
+
printf(" supported speeds : %04X\n", ss_usb_device_cap->wSpeedSupported);
|
759
|
+
printf(" supported functionality: %02X\n", ss_usb_device_cap->bFunctionalitySupport);
|
760
|
+
libusb_free_ss_usb_device_capability_descriptor(ss_usb_device_cap);
|
761
|
+
}
|
762
|
+
break;
|
763
|
+
}
|
764
|
+
case LIBUSB_BT_CONTAINER_ID: {
|
765
|
+
struct libusb_container_id_descriptor *container_id = NULL;
|
766
|
+
libusb_get_container_id_descriptor(NULL, dev_cap, &container_id);
|
767
|
+
if (container_id) {
|
768
|
+
printf(" Container ID:\n %s\n", uuid_to_string(container_id->ContainerID));
|
769
|
+
libusb_free_container_id_descriptor(container_id);
|
770
|
+
}
|
771
|
+
break;
|
772
|
+
}
|
773
|
+
default:
|
774
|
+
printf(" Unknown BOS device capability %02x:\n", dev_cap->bDevCapabilityType);
|
775
|
+
}
|
776
|
+
}
|
777
|
+
|
733
778
|
static int test_device(uint16_t vid, uint16_t pid)
|
734
779
|
{
|
735
780
|
libusb_device_handle *handle;
|
736
781
|
libusb_device *dev;
|
737
782
|
uint8_t bus, port_path[8];
|
783
|
+
struct libusb_bos_descriptor *bos_desc;
|
738
784
|
struct libusb_config_descriptor *conf_desc;
|
739
785
|
const struct libusb_endpoint_descriptor *endpoint;
|
740
786
|
int i, j, k, r;
|
741
787
|
int iface, nb_ifaces, first_iface = -1;
|
742
|
-
#if defined(__linux__)
|
743
|
-
// Attaching/detaching the kernel driver is only relevant for Linux
|
744
|
-
int iface_detached = -1;
|
745
|
-
#endif
|
746
788
|
struct libusb_device_descriptor dev_desc;
|
747
789
|
const char* speed_name[5] = { "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)",
|
748
790
|
"480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)"};
|
@@ -761,7 +803,7 @@ static int test_device(uint16_t vid, uint16_t pid)
|
|
761
803
|
dev = libusb_get_device(handle);
|
762
804
|
bus = libusb_get_bus_number(dev);
|
763
805
|
if (extra_info) {
|
764
|
-
r =
|
806
|
+
r = libusb_get_port_numbers(dev, port_path, sizeof(port_path));
|
765
807
|
if (r > 0) {
|
766
808
|
printf("\nDevice properties:\n");
|
767
809
|
printf(" bus number: %d\n", bus);
|
@@ -790,7 +832,17 @@ static int test_device(uint16_t vid, uint16_t pid)
|
|
790
832
|
string_index[1] = dev_desc.iProduct;
|
791
833
|
string_index[2] = dev_desc.iSerialNumber;
|
792
834
|
|
793
|
-
printf("\nReading
|
835
|
+
printf("\nReading BOS descriptor: ");
|
836
|
+
if (libusb_get_bos_descriptor(handle, &bos_desc) == LIBUSB_SUCCESS) {
|
837
|
+
printf("%d caps\n", bos_desc->bNumDeviceCaps);
|
838
|
+
for (i = 0; i < bos_desc->bNumDeviceCaps; i++)
|
839
|
+
print_device_cap(bos_desc->dev_capability[i]);
|
840
|
+
libusb_free_bos_descriptor(bos_desc);
|
841
|
+
} else {
|
842
|
+
printf("no descriptor\n");
|
843
|
+
}
|
844
|
+
|
845
|
+
printf("\nReading first configuration descriptor:\n");
|
794
846
|
CALL_CHECK(libusb_get_config_descriptor(dev, 0, &conf_desc));
|
795
847
|
nb_ifaces = conf_desc->bNumInterfaces;
|
796
848
|
printf(" nb interfaces: %d\n", nb_ifaces);
|
@@ -814,6 +866,7 @@ static int test_device(uint16_t vid, uint16_t pid)
|
|
814
866
|
test_mode = USE_SCSI;
|
815
867
|
}
|
816
868
|
for (k=0; k<conf_desc->usb_interface[i].altsetting[j].bNumEndpoints; k++) {
|
869
|
+
struct libusb_ss_endpoint_companion_descriptor *ep_comp = NULL;
|
817
870
|
endpoint = &conf_desc->usb_interface[i].altsetting[j].endpoint[k];
|
818
871
|
printf(" endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress);
|
819
872
|
// Use the first interrupt or bulk IN/OUT endpoints as default for testing
|
@@ -828,25 +881,22 @@ static int test_device(uint16_t vid, uint16_t pid)
|
|
828
881
|
}
|
829
882
|
printf(" max packet size: %04X\n", endpoint->wMaxPacketSize);
|
830
883
|
printf(" polling interval: %02X\n", endpoint->bInterval);
|
884
|
+
libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);
|
885
|
+
if (ep_comp) {
|
886
|
+
printf(" max burst: %02X (USB 3.0)\n", ep_comp->bMaxBurst);
|
887
|
+
printf(" bytes per interval: %04X (USB 3.0)\n", ep_comp->wBytesPerInterval);
|
888
|
+
libusb_free_ss_endpoint_companion_descriptor(ep_comp);
|
889
|
+
}
|
831
890
|
}
|
832
891
|
}
|
833
892
|
}
|
834
893
|
libusb_free_config_descriptor(conf_desc);
|
835
894
|
|
895
|
+
libusb_set_auto_detach_kernel_driver(handle, 1);
|
836
896
|
for (iface = 0; iface < nb_ifaces; iface++)
|
837
897
|
{
|
838
898
|
printf("\nClaiming interface %d...\n", iface);
|
839
899
|
r = libusb_claim_interface(handle, iface);
|
840
|
-
#if defined(__linux__)
|
841
|
-
if ((r != LIBUSB_SUCCESS) && (iface == 0)) {
|
842
|
-
// Maybe we need to detach the driver
|
843
|
-
perr(" Failed. Trying to detach driver...\n");
|
844
|
-
libusb_detach_kernel_driver(handle, iface);
|
845
|
-
iface_detached = iface;
|
846
|
-
printf(" Claiming interface again...\n");
|
847
|
-
r = libusb_claim_interface(handle, iface);
|
848
|
-
}
|
849
|
-
#endif
|
850
900
|
if (r != LIBUSB_SUCCESS) {
|
851
901
|
perr(" Failed.\n");
|
852
902
|
}
|
@@ -895,13 +945,6 @@ static int test_device(uint16_t vid, uint16_t pid)
|
|
895
945
|
libusb_release_interface(handle, iface);
|
896
946
|
}
|
897
947
|
|
898
|
-
#if defined(__linux__)
|
899
|
-
if (iface_detached >= 0) {
|
900
|
-
printf("Re-attaching kernel driver...\n");
|
901
|
-
libusb_attach_kernel_driver(handle, iface_detached);
|
902
|
-
}
|
903
|
-
#endif
|
904
|
-
|
905
948
|
printf("Closing device...\n");
|
906
949
|
libusb_close(handle);
|
907
950
|
|
@@ -917,6 +960,7 @@ int main(int argc, char** argv)
|
|
917
960
|
size_t i, arglen;
|
918
961
|
unsigned tmp_vid, tmp_pid;
|
919
962
|
uint16_t endian_test = 0xBE00;
|
963
|
+
char* error_lang = NULL;
|
920
964
|
|
921
965
|
// Default to generic, expecting VID:PID
|
922
966
|
VID = 0;
|
@@ -943,12 +987,19 @@ int main(int argc, char** argv)
|
|
943
987
|
break;
|
944
988
|
case 'b':
|
945
989
|
if ((j+1 >= argc) || (argv[j+1][0] == '-') || (argv[j+1][0] == '/')) {
|
946
|
-
printf(" Option -b requires a file name");
|
990
|
+
printf(" Option -b requires a file name\n");
|
947
991
|
return 1;
|
948
992
|
}
|
949
993
|
binary_name = argv[++j];
|
950
994
|
binary_dump = true;
|
951
995
|
break;
|
996
|
+
case 'l':
|
997
|
+
if ((j+1 >= argc) || (argv[j+1][0] == '-') || (argv[j+1][0] == '/')) {
|
998
|
+
printf(" Option -l requires an ISO 639-1 language parameter\n");
|
999
|
+
return 1;
|
1000
|
+
}
|
1001
|
+
error_lang = argv[++j];
|
1002
|
+
break;
|
952
1003
|
case 'j':
|
953
1004
|
// OLIMEX ARM-USB-TINY JTAG, 2 channel composite device - 2 interfaces
|
954
1005
|
if (!VID && !PID) {
|
@@ -992,7 +1043,7 @@ int main(int argc, char** argv)
|
|
992
1043
|
break;
|
993
1044
|
}
|
994
1045
|
if (i != arglen) {
|
995
|
-
if (
|
1046
|
+
if (sscanf(argv[j], "%x:%x" , &tmp_vid, &tmp_pid) != 2) {
|
996
1047
|
printf(" Please specify VID & PID as \"vid:pid\" in hexadecimal format\n");
|
997
1048
|
return 1;
|
998
1049
|
}
|
@@ -1006,7 +1057,7 @@ int main(int argc, char** argv)
|
|
1006
1057
|
}
|
1007
1058
|
|
1008
1059
|
if ((show_help) || (argc == 1) || (argc > 7)) {
|
1009
|
-
printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-j] [-x] [-s] [-p] [vid:pid]\n", argv[0]);
|
1060
|
+
printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] [-x] [-s] [-p] [vid:pid]\n", argv[0]);
|
1010
1061
|
printf(" -h : display usage\n");
|
1011
1062
|
printf(" -d : enable debug output\n");
|
1012
1063
|
printf(" -i : print topology and speed info\n");
|
@@ -1016,6 +1067,7 @@ int main(int argc, char** argv)
|
|
1016
1067
|
printf(" -p : test Sony PS3 SixAxis controller\n");
|
1017
1068
|
printf(" -s : test Microsoft Sidewinder Precision Pro (HID)\n");
|
1018
1069
|
printf(" -x : test Microsoft XBox Controller Type S\n");
|
1070
|
+
printf(" -l lang : language to report errors in (ISO 639-1)\n");
|
1019
1071
|
printf("If only the vid:pid is provided, xusb attempts to run the most appropriate test\n");
|
1020
1072
|
return 0;
|
1021
1073
|
}
|
@@ -1027,6 +1079,11 @@ int main(int argc, char** argv)
|
|
1027
1079
|
return r;
|
1028
1080
|
|
1029
1081
|
libusb_set_debug(NULL, debug_mode?LIBUSB_LOG_LEVEL_DEBUG:LIBUSB_LOG_LEVEL_INFO);
|
1082
|
+
if (error_lang != NULL) {
|
1083
|
+
r = libusb_setlocale(error_lang);
|
1084
|
+
if (r < 0)
|
1085
|
+
printf("Invalid or unsupported locale '%s': %s\n", error_lang, libusb_strerror((enum libusb_error)r));
|
1086
|
+
}
|
1030
1087
|
|
1031
1088
|
test_device(VID, PID);
|
1032
1089
|
|