libusb 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Gemfile +1 -0
  5. data/History.md +10 -0
  6. data/README.md +19 -6
  7. data/Rakefile +1 -1
  8. data/ext/extconf.rb +17 -1
  9. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
  10. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
  11. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
  12. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
  13. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
  14. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
  15. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
  16. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
  17. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
  18. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
  19. data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
  20. data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
  21. data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
  22. data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
  23. data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
  24. data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
  25. data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
  26. data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
  27. data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
  28. data/ext/libusbx-1.0.17/android/README +114 -0
  29. data/ext/libusbx-1.0.17/android/config.h +90 -0
  30. data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
  31. data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
  32. data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
  33. data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
  34. data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
  35. data/ext/libusbx-1.0.17/compile +347 -0
  36. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
  37. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
  38. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
  39. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
  40. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
  41. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
  42. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
  43. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
  44. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
  45. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
  46. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
  47. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
  48. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
  49. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
  50. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
  51. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
  52. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
  53. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
  54. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
  55. data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
  56. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
  57. data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
  58. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
  59. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
  60. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
  61. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
  62. data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
  63. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
  64. data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
  65. data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
  66. data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
  67. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
  68. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
  69. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
  70. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
  71. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
  72. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
  73. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
  74. data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
  75. data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
  76. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
  77. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
  78. data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
  79. data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
  80. data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
  81. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
  82. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
  83. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
  84. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
  85. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
  86. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
  87. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
  88. data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
  89. data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
  90. data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
  91. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
  92. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
  93. data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
  94. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
  95. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
  96. data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
  97. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
  98. data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
  99. data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
  100. data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
  101. data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
  102. data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
  103. data/ext/libusbx-1.0.17/missing +215 -0
  104. data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
  105. data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
  106. data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
  107. data/ext/libusbx-1.0.17/tests/stress.c +160 -0
  108. data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
  109. data/lib/libusb.rb +4 -0
  110. data/lib/libusb/call.rb +43 -1
  111. data/lib/libusb/constants.rb +5 -0
  112. data/lib/libusb/context.rb +100 -0
  113. data/lib/libusb/dev_handle.rb +27 -0
  114. data/lib/libusb/device.rb +10 -4
  115. data/lib/libusb/version_gem.rb +1 -1
  116. data/test/test_libusb_capability.rb +2 -2
  117. data/test/test_libusb_compat.rb +2 -2
  118. data/test/test_libusb_compat_mass_storage.rb +2 -2
  119. data/test/test_libusb_descriptors.rb +4 -2
  120. data/test/test_libusb_event_machine.rb +2 -2
  121. data/test/test_libusb_gc.rb +2 -2
  122. data/test/test_libusb_hotplug.rb +115 -0
  123. data/test/test_libusb_iso_transfer.rb +3 -3
  124. data/test/test_libusb_mass_storage.rb +6 -16
  125. data/test/test_libusb_mass_storage2.rb +26 -3
  126. data/test/test_libusb_structs.rb +2 -2
  127. data/test/test_libusb_threads.rb +2 -2
  128. data/test/test_libusb_version.rb +2 -2
  129. metadata +127 -68
  130. metadata.gz.sig +0 -0
  131. data/ext/libusbx-1.0.14/THANKS +0 -7
  132. data/ext/libusbx-1.0.14/compile +0 -143
  133. data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
  134. data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
  135. data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
  136. data/ext/libusbx-1.0.14/missing +0 -376
@@ -1,731 +0,0 @@
1
- /*
2
- * USB descriptor handling functions for libusbx
3
- * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
4
- * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
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 <errno.h>
22
- #include <stdint.h>
23
- #include <stdlib.h>
24
- #include <string.h>
25
-
26
- #include "libusbi.h"
27
-
28
- #define DESC_HEADER_LENGTH 2
29
- #define DEVICE_DESC_LENGTH 18
30
- #define CONFIG_DESC_LENGTH 9
31
- #define INTERFACE_DESC_LENGTH 9
32
- #define ENDPOINT_DESC_LENGTH 7
33
- #define ENDPOINT_AUDIO_DESC_LENGTH 9
34
-
35
- /** @defgroup desc USB descriptors
36
- * This page details how to examine the various standard USB descriptors
37
- * for detected devices
38
- */
39
-
40
- /* set host_endian if the w values are already in host endian format,
41
- * as opposed to bus endian. */
42
- int usbi_parse_descriptor(unsigned char *source, const char *descriptor,
43
- void *dest, int host_endian)
44
- {
45
- unsigned char *sp = source, *dp = dest;
46
- uint16_t w;
47
- const char *cp;
48
-
49
- for (cp = descriptor; *cp; cp++) {
50
- switch (*cp) {
51
- case 'b': /* 8-bit byte */
52
- *dp++ = *sp++;
53
- break;
54
- case 'w': /* 16-bit word, convert from little endian to CPU */
55
- dp += ((uintptr_t)dp & 1); /* Align to word boundary */
56
-
57
- if (host_endian) {
58
- memcpy(dp, sp, 2);
59
- } else {
60
- w = (sp[1] << 8) | sp[0];
61
- *((uint16_t *)dp) = w;
62
- }
63
- sp += 2;
64
- dp += 2;
65
- break;
66
- }
67
- }
68
-
69
- return (int) (sp - source);
70
- }
71
-
72
- static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
73
- {
74
- if (endpoint->extra)
75
- free((unsigned char *) endpoint->extra);
76
- }
77
-
78
- static int parse_endpoint(struct libusb_context *ctx,
79
- struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer,
80
- int size, int host_endian)
81
- {
82
- struct usb_descriptor_header header;
83
- unsigned char *extra;
84
- unsigned char *begin;
85
- int parsed = 0;
86
- int len;
87
-
88
- usbi_parse_descriptor(buffer, "bb", &header, 0);
89
-
90
- /* Everything should be fine being passed into here, but we sanity */
91
- /* check JIC */
92
- if (header.bLength > size) {
93
- usbi_err(ctx, "ran out of descriptors parsing");
94
- return -1;
95
- }
96
-
97
- if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) {
98
- usbi_err(ctx, "unexpected descriptor %x (expected %x)",
99
- header.bDescriptorType, LIBUSB_DT_ENDPOINT);
100
- return parsed;
101
- }
102
-
103
- if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH)
104
- usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian);
105
- else if (header.bLength >= ENDPOINT_DESC_LENGTH)
106
- usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian);
107
-
108
- buffer += header.bLength;
109
- size -= header.bLength;
110
- parsed += header.bLength;
111
-
112
- /* Skip over the rest of the Class Specific or Vendor Specific */
113
- /* descriptors */
114
- begin = buffer;
115
- while (size >= DESC_HEADER_LENGTH) {
116
- usbi_parse_descriptor(buffer, "bb", &header, 0);
117
-
118
- if (header.bLength < 2) {
119
- usbi_err(ctx, "invalid descriptor length %d", header.bLength);
120
- return -1;
121
- }
122
-
123
- /* If we find another "proper" descriptor then we're done */
124
- if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
125
- (header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
126
- (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
127
- (header.bDescriptorType == LIBUSB_DT_DEVICE))
128
- break;
129
-
130
- usbi_dbg("skipping descriptor %x", header.bDescriptorType);
131
- buffer += header.bLength;
132
- size -= header.bLength;
133
- parsed += header.bLength;
134
- }
135
-
136
- /* Copy any unknown descriptors into a storage area for drivers */
137
- /* to later parse */
138
- len = (int)(buffer - begin);
139
- if (!len) {
140
- endpoint->extra = NULL;
141
- endpoint->extra_length = 0;
142
- return parsed;
143
- }
144
-
145
- extra = malloc(len);
146
- endpoint->extra = extra;
147
- if (!extra) {
148
- endpoint->extra_length = 0;
149
- return LIBUSB_ERROR_NO_MEM;
150
- }
151
-
152
- memcpy(extra, begin, len);
153
- endpoint->extra_length = len;
154
-
155
- return parsed;
156
- }
157
-
158
- static void clear_interface(struct libusb_interface *usb_interface)
159
- {
160
- int i;
161
- int j;
162
-
163
- if (usb_interface->altsetting) {
164
- for (i = 0; i < usb_interface->num_altsetting; i++) {
165
- struct libusb_interface_descriptor *ifp =
166
- (struct libusb_interface_descriptor *)
167
- usb_interface->altsetting + i;
168
- if (ifp->extra)
169
- free((void *) ifp->extra);
170
- if (ifp->endpoint) {
171
- for (j = 0; j < ifp->bNumEndpoints; j++)
172
- clear_endpoint((struct libusb_endpoint_descriptor *)
173
- ifp->endpoint + j);
174
- free((void *) ifp->endpoint);
175
- }
176
- }
177
- free((void *) usb_interface->altsetting);
178
- usb_interface->altsetting = NULL;
179
- }
180
-
181
- }
182
-
183
- static int parse_interface(libusb_context *ctx,
184
- struct libusb_interface *usb_interface, unsigned char *buffer, int size,
185
- int host_endian)
186
- {
187
- int i;
188
- int len;
189
- int r;
190
- int parsed = 0;
191
- size_t tmp;
192
- struct usb_descriptor_header header;
193
- struct libusb_interface_descriptor *ifp;
194
- unsigned char *begin;
195
-
196
- usb_interface->num_altsetting = 0;
197
-
198
- while (size >= INTERFACE_DESC_LENGTH) {
199
- struct libusb_interface_descriptor *altsetting =
200
- (struct libusb_interface_descriptor *) usb_interface->altsetting;
201
- altsetting = usbi_reallocf(altsetting,
202
- sizeof(struct libusb_interface_descriptor) *
203
- (usb_interface->num_altsetting + 1));
204
- if (!altsetting) {
205
- r = LIBUSB_ERROR_NO_MEM;
206
- goto err;
207
- }
208
- usb_interface->altsetting = altsetting;
209
-
210
- ifp = altsetting + usb_interface->num_altsetting;
211
- usb_interface->num_altsetting++;
212
- usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
213
- ifp->extra = NULL;
214
- ifp->extra_length = 0;
215
- ifp->endpoint = NULL;
216
-
217
- /* Skip over the interface */
218
- buffer += ifp->bLength;
219
- parsed += ifp->bLength;
220
- size -= ifp->bLength;
221
-
222
- begin = buffer;
223
-
224
- /* Skip over any interface, class or vendor descriptors */
225
- while (size >= DESC_HEADER_LENGTH) {
226
- usbi_parse_descriptor(buffer, "bb", &header, 0);
227
- if (header.bLength < 2) {
228
- usbi_err(ctx, "invalid descriptor of length %d",
229
- header.bLength);
230
- r = LIBUSB_ERROR_IO;
231
- goto err;
232
- }
233
-
234
- /* If we find another "proper" descriptor then we're done */
235
- if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
236
- (header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
237
- (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
238
- (header.bDescriptorType == LIBUSB_DT_DEVICE))
239
- break;
240
-
241
- buffer += header.bLength;
242
- parsed += header.bLength;
243
- size -= header.bLength;
244
- }
245
-
246
- /* Copy any unknown descriptors into a storage area for */
247
- /* drivers to later parse */
248
- len = (int)(buffer - begin);
249
- if (len) {
250
- ifp->extra = malloc(len);
251
- if (!ifp->extra) {
252
- r = LIBUSB_ERROR_NO_MEM;
253
- goto err;
254
- }
255
- memcpy((unsigned char *) ifp->extra, begin, len);
256
- ifp->extra_length = len;
257
- }
258
-
259
- /* Did we hit an unexpected descriptor? */
260
- if (size >= DESC_HEADER_LENGTH) {
261
- usbi_parse_descriptor(buffer, "bb", &header, 0);
262
- if ((header.bDescriptorType == LIBUSB_DT_CONFIG) ||
263
- (header.bDescriptorType == LIBUSB_DT_DEVICE)) {
264
- return parsed;
265
- }
266
- }
267
-
268
- if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
269
- usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints);
270
- r = LIBUSB_ERROR_IO;
271
- goto err;
272
- }
273
-
274
- if (ifp->bNumEndpoints > 0) {
275
- struct libusb_endpoint_descriptor *endpoint;
276
- tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint_descriptor);
277
- endpoint = malloc(tmp);
278
- ifp->endpoint = endpoint;
279
- if (!endpoint) {
280
- r = LIBUSB_ERROR_NO_MEM;
281
- goto err;
282
- }
283
-
284
- memset(endpoint, 0, tmp);
285
- for (i = 0; i < ifp->bNumEndpoints; i++) {
286
- usbi_parse_descriptor(buffer, "bb", &header, 0);
287
-
288
- if (header.bLength > size) {
289
- usbi_err(ctx, "ran out of descriptors parsing");
290
- r = LIBUSB_ERROR_IO;
291
- goto err;
292
- }
293
-
294
- r = parse_endpoint(ctx, endpoint + i, buffer, size,
295
- host_endian);
296
- if (r < 0)
297
- goto err;
298
-
299
- buffer += r;
300
- parsed += r;
301
- size -= r;
302
- }
303
- }
304
-
305
- /* We check to see if it's an alternate to this one */
306
- ifp = (struct libusb_interface_descriptor *) buffer;
307
- if (size < LIBUSB_DT_INTERFACE_SIZE ||
308
- ifp->bDescriptorType != LIBUSB_DT_INTERFACE ||
309
- !ifp->bAlternateSetting)
310
- return parsed;
311
- }
312
-
313
- return parsed;
314
- err:
315
- clear_interface(usb_interface);
316
- return r;
317
- }
318
-
319
- static void clear_configuration(struct libusb_config_descriptor *config)
320
- {
321
- if (config->interface) {
322
- int i;
323
- for (i = 0; i < config->bNumInterfaces; i++)
324
- clear_interface((struct libusb_interface *)
325
- config->interface + i);
326
- free((void *) config->interface);
327
- }
328
- if (config->extra)
329
- free((void *) config->extra);
330
- }
331
-
332
- static int parse_configuration(struct libusb_context *ctx,
333
- struct libusb_config_descriptor *config, unsigned char *buffer,
334
- int host_endian)
335
- {
336
- int i;
337
- int r;
338
- int size;
339
- size_t tmp;
340
- struct usb_descriptor_header header;
341
- struct libusb_interface *usb_interface;
342
-
343
- usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian);
344
- size = config->wTotalLength;
345
-
346
- if (config->bNumInterfaces > USB_MAXINTERFACES) {
347
- usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces);
348
- return LIBUSB_ERROR_IO;
349
- }
350
-
351
- tmp = config->bNumInterfaces * sizeof(struct libusb_interface);
352
- usb_interface = malloc(tmp);
353
- config->interface = usb_interface;
354
- if (!config->interface)
355
- return LIBUSB_ERROR_NO_MEM;
356
-
357
- memset(usb_interface, 0, tmp);
358
- buffer += config->bLength;
359
- size -= config->bLength;
360
-
361
- config->extra = NULL;
362
- config->extra_length = 0;
363
-
364
- for (i = 0; i < config->bNumInterfaces; i++) {
365
- int len;
366
- unsigned char *begin;
367
-
368
- /* Skip over the rest of the Class Specific or Vendor */
369
- /* Specific descriptors */
370
- begin = buffer;
371
- while (size >= DESC_HEADER_LENGTH) {
372
- usbi_parse_descriptor(buffer, "bb", &header, 0);
373
-
374
- if ((header.bLength > size) ||
375
- (header.bLength < DESC_HEADER_LENGTH)) {
376
- usbi_err(ctx, "invalid descriptor length of %d",
377
- header.bLength);
378
- r = LIBUSB_ERROR_IO;
379
- goto err;
380
- }
381
-
382
- /* If we find another "proper" descriptor then we're done */
383
- if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
384
- (header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
385
- (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
386
- (header.bDescriptorType == LIBUSB_DT_DEVICE))
387
- break;
388
-
389
- usbi_dbg("skipping descriptor 0x%x\n", header.bDescriptorType);
390
- buffer += header.bLength;
391
- size -= header.bLength;
392
- }
393
-
394
- /* Copy any unknown descriptors into a storage area for */
395
- /* drivers to later parse */
396
- len = (int)(buffer - begin);
397
- if (len) {
398
- /* FIXME: We should realloc and append here */
399
- if (!config->extra_length) {
400
- config->extra = malloc(len);
401
- if (!config->extra) {
402
- r = LIBUSB_ERROR_NO_MEM;
403
- goto err;
404
- }
405
-
406
- memcpy((unsigned char *) config->extra, begin, len);
407
- config->extra_length = len;
408
- }
409
- }
410
-
411
- r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian);
412
- if (r < 0)
413
- goto err;
414
-
415
- buffer += r;
416
- size -= r;
417
- }
418
-
419
- return size;
420
-
421
- err:
422
- clear_configuration(config);
423
- return r;
424
- }
425
-
426
- /** \ingroup desc
427
- * Get the USB device descriptor for a given device.
428
- *
429
- * This is a non-blocking function; the device descriptor is cached in memory.
430
- *
431
- * \param dev the device
432
- * \param desc output location for the descriptor data
433
- * \returns 0 on success or a LIBUSB_ERROR code on failure
434
- */
435
- int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
436
- struct libusb_device_descriptor *desc)
437
- {
438
- unsigned char raw_desc[DEVICE_DESC_LENGTH];
439
- int host_endian = 0;
440
- int r;
441
-
442
- usbi_dbg("");
443
- r = usbi_backend->get_device_descriptor(dev, raw_desc, &host_endian);
444
- if (r < 0)
445
- return r;
446
-
447
- memcpy((unsigned char *) desc, raw_desc, sizeof(raw_desc));
448
- if (!host_endian) {
449
- desc->bcdUSB = libusb_le16_to_cpu(desc->bcdUSB);
450
- desc->idVendor = libusb_le16_to_cpu(desc->idVendor);
451
- desc->idProduct = libusb_le16_to_cpu(desc->idProduct);
452
- desc->bcdDevice = libusb_le16_to_cpu(desc->bcdDevice);
453
- }
454
- return 0;
455
- }
456
-
457
- /** \ingroup desc
458
- * Get the USB configuration descriptor for the currently active configuration.
459
- * This is a non-blocking function which does not involve any requests being
460
- * sent to the device.
461
- *
462
- * \param dev a device
463
- * \param config output location for the USB configuration descriptor. Only
464
- * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
465
- * after use.
466
- * \returns 0 on success
467
- * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
468
- * \returns another LIBUSB_ERROR code on error
469
- * \see libusb_get_config_descriptor
470
- */
471
- int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
472
- struct libusb_config_descriptor **config)
473
- {
474
- struct libusb_config_descriptor *_config = malloc(sizeof(*_config));
475
- unsigned char tmp[8];
476
- unsigned char *buf = NULL;
477
- int host_endian = 0;
478
- int r;
479
-
480
- usbi_dbg("");
481
- if (!_config)
482
- return LIBUSB_ERROR_NO_MEM;
483
-
484
- r = usbi_backend->get_active_config_descriptor(dev, tmp, sizeof(tmp),
485
- &host_endian);
486
- if (r < 0)
487
- goto err;
488
-
489
- _config->wTotalLength = 0;
490
- usbi_parse_descriptor(tmp, "bbw", _config, host_endian);
491
- if (_config->wTotalLength != 0)
492
- buf = malloc(_config->wTotalLength);
493
- if (!buf) {
494
- r = LIBUSB_ERROR_NO_MEM;
495
- goto err;
496
- }
497
-
498
- r = usbi_backend->get_active_config_descriptor(dev, buf,
499
- _config->wTotalLength, &host_endian);
500
- if (r < 0)
501
- goto err;
502
-
503
- r = parse_configuration(dev->ctx, _config, buf, host_endian);
504
- if (r < 0) {
505
- usbi_err(dev->ctx, "parse_configuration failed with error %d", r);
506
- goto err;
507
- } else if (r > 0) {
508
- usbi_warn(dev->ctx, "descriptor data still left");
509
- }
510
-
511
- free(buf);
512
- *config = _config;
513
- return 0;
514
-
515
- err:
516
- free(_config);
517
- if (buf)
518
- free(buf);
519
- return r;
520
- }
521
-
522
- /** \ingroup desc
523
- * Get a USB configuration descriptor based on its index.
524
- * This is a non-blocking function which does not involve any requests being
525
- * sent to the device.
526
- *
527
- * \param dev a device
528
- * \param config_index the index of the configuration you wish to retrieve
529
- * \param config output location for the USB configuration descriptor. Only
530
- * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
531
- * after use.
532
- * \returns 0 on success
533
- * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
534
- * \returns another LIBUSB_ERROR code on error
535
- * \see libusb_get_active_config_descriptor()
536
- * \see libusb_get_config_descriptor_by_value()
537
- */
538
- int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
539
- uint8_t config_index, struct libusb_config_descriptor **config)
540
- {
541
- struct libusb_config_descriptor *_config;
542
- unsigned char tmp[8];
543
- unsigned char *buf = NULL;
544
- int host_endian = 0;
545
- int r;
546
-
547
- usbi_dbg("index %d", config_index);
548
- if (config_index >= dev->num_configurations)
549
- return LIBUSB_ERROR_NOT_FOUND;
550
-
551
- _config = malloc(sizeof(*_config));
552
- if (!_config)
553
- return LIBUSB_ERROR_NO_MEM;
554
-
555
- r = usbi_backend->get_config_descriptor(dev, config_index, tmp,
556
- sizeof(tmp), &host_endian);
557
- if (r < 0)
558
- goto err;
559
-
560
- usbi_parse_descriptor(tmp, "bbw", _config, host_endian);
561
- buf = malloc(_config->wTotalLength);
562
- if (!buf) {
563
- r = LIBUSB_ERROR_NO_MEM;
564
- goto err;
565
- }
566
-
567
- host_endian = 0;
568
- r = usbi_backend->get_config_descriptor(dev, config_index, buf,
569
- _config->wTotalLength, &host_endian);
570
- if (r < 0)
571
- goto err;
572
-
573
- r = parse_configuration(dev->ctx, _config, buf, host_endian);
574
- if (r < 0) {
575
- usbi_err(dev->ctx, "parse_configuration failed with error %d", r);
576
- goto err;
577
- } else if (r > 0) {
578
- usbi_warn(dev->ctx, "descriptor data still left");
579
- }
580
-
581
- free(buf);
582
- *config = _config;
583
- return 0;
584
-
585
- err:
586
- free(_config);
587
- if (buf)
588
- free(buf);
589
- return r;
590
- }
591
-
592
- /* iterate through all configurations, returning the index of the configuration
593
- * matching a specific bConfigurationValue in the idx output parameter, or -1
594
- * if the config was not found.
595
- * returns 0 or a LIBUSB_ERROR code
596
- */
597
- int usbi_get_config_index_by_value(struct libusb_device *dev,
598
- uint8_t bConfigurationValue, int *idx)
599
- {
600
- uint8_t i;
601
-
602
- usbi_dbg("value %d", bConfigurationValue);
603
- for (i = 0; i < dev->num_configurations; i++) {
604
- unsigned char tmp[6];
605
- int host_endian;
606
- int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp),
607
- &host_endian);
608
- if (r < 0)
609
- return r;
610
- if (tmp[5] == bConfigurationValue) {
611
- *idx = i;
612
- return 0;
613
- }
614
- }
615
-
616
- *idx = -1;
617
- return 0;
618
- }
619
-
620
- /** \ingroup desc
621
- * Get a USB configuration descriptor with a specific bConfigurationValue.
622
- * This is a non-blocking function which does not involve any requests being
623
- * sent to the device.
624
- *
625
- * \param dev a device
626
- * \param bConfigurationValue the bConfigurationValue of the configuration you
627
- * wish to retrieve
628
- * \param config output location for the USB configuration descriptor. Only
629
- * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
630
- * after use.
631
- * \returns 0 on success
632
- * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
633
- * \returns another LIBUSB_ERROR code on error
634
- * \see libusb_get_active_config_descriptor()
635
- * \see libusb_get_config_descriptor()
636
- */
637
- int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
638
- uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
639
- {
640
- int idx;
641
- int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
642
- if (r < 0)
643
- return r;
644
- else if (idx == -1)
645
- return LIBUSB_ERROR_NOT_FOUND;
646
- else
647
- return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
648
- }
649
-
650
- /** \ingroup desc
651
- * Free a configuration descriptor obtained from
652
- * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
653
- * It is safe to call this function with a NULL config parameter, in which
654
- * case the function simply returns.
655
- *
656
- * \param config the configuration descriptor to free
657
- */
658
- void API_EXPORTED libusb_free_config_descriptor(
659
- struct libusb_config_descriptor *config)
660
- {
661
- if (!config)
662
- return;
663
-
664
- clear_configuration(config);
665
- free(config);
666
- }
667
-
668
- /** \ingroup desc
669
- * Retrieve a string descriptor in C style ASCII.
670
- *
671
- * Wrapper around libusb_get_string_descriptor(). Uses the first language
672
- * supported by the device.
673
- *
674
- * \param dev a device handle
675
- * \param desc_index the index of the descriptor to retrieve
676
- * \param data output buffer for ASCII string descriptor
677
- * \param length size of data buffer
678
- * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
679
- */
680
- int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
681
- uint8_t desc_index, unsigned char *data, int length)
682
- {
683
- unsigned char tbuf[255]; /* Some devices choke on size > 255 */
684
- int r, si, di;
685
- uint16_t langid;
686
-
687
- /* Asking for the zero'th index is special - it returns a string
688
- * descriptor that contains all the language IDs supported by the
689
- * device. Typically there aren't many - often only one. Language
690
- * IDs are 16 bit numbers, and they start at the third byte in the
691
- * descriptor. There's also no point in trying to read descriptor 0
692
- * with this function. See USB 2.0 specification section 9.6.7 for
693
- * more information.
694
- */
695
-
696
- if (desc_index == 0)
697
- return LIBUSB_ERROR_INVALID_PARAM;
698
-
699
- r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf));
700
- if (r < 0)
701
- return r;
702
-
703
- if (r < 4)
704
- return LIBUSB_ERROR_IO;
705
-
706
- langid = tbuf[2] | (tbuf[3] << 8);
707
-
708
- r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf,
709
- sizeof(tbuf));
710
- if (r < 0)
711
- return r;
712
-
713
- if (tbuf[1] != LIBUSB_DT_STRING)
714
- return LIBUSB_ERROR_IO;
715
-
716
- if (tbuf[0] > r)
717
- return LIBUSB_ERROR_IO;
718
-
719
- for (di = 0, si = 2; si < tbuf[0]; si += 2) {
720
- if (di >= (length - 1))
721
- break;
722
-
723
- if (tbuf[si + 1]) /* high byte */
724
- data[di++] = '?';
725
- else
726
- data[di++] = tbuf[si];
727
- }
728
-
729
- data[di] = 0;
730
- return di;
731
- }