Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(917)

Side by Side Diff: third_party/libusb/src/libusb/descriptor.c

Issue 19713005: Update libusb 1.0.9 to libusbx 1.0.16 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
1 /* 2 /*
2 * USB descriptor handling functions for libusb 3 * USB descriptor handling functions for libusbx
3 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org> 4 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
4 * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com> 5 * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
5 * 6 *
6 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
10 * 11 *
11 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 15 * Lesser General Public License for more details.
(...skipping 17 matching lines...) Expand all
32 #define ENDPOINT_DESC_LENGTH 7 33 #define ENDPOINT_DESC_LENGTH 7
33 #define ENDPOINT_AUDIO_DESC_LENGTH 9 34 #define ENDPOINT_AUDIO_DESC_LENGTH 9
34 35
35 /** @defgroup desc USB descriptors 36 /** @defgroup desc USB descriptors
36 * This page details how to examine the various standard USB descriptors 37 * This page details how to examine the various standard USB descriptors
37 * for detected devices 38 * for detected devices
38 */ 39 */
39 40
40 /* set host_endian if the w values are already in host endian format, 41 /* set host_endian if the w values are already in host endian format,
41 * as opposed to bus endian. */ 42 * as opposed to bus endian. */
42 int usbi_parse_descriptor(unsigned char *source, const char *descriptor, 43 int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
43 void *dest, int host_endian) 44 void *dest, int host_endian)
44 { 45 {
45 » unsigned char *sp = source, *dp = dest; 46 » const unsigned char *sp = source;
47 » unsigned char *dp = dest;
46 uint16_t w; 48 uint16_t w;
47 const char *cp; 49 const char *cp;
50 uint32_t d;
48 51
49 for (cp = descriptor; *cp; cp++) { 52 for (cp = descriptor; *cp; cp++) {
50 switch (*cp) { 53 switch (*cp) {
51 case 'b': /* 8-bit byte */ 54 case 'b': /* 8-bit byte */
52 *dp++ = *sp++; 55 *dp++ = *sp++;
53 break; 56 break;
54 case 'w': /* 16-bit word, convert from little endi an to CPU */ 57 case 'w': /* 16-bit word, convert from little endi an to CPU */
55 dp += ((uintptr_t)dp & 1); /* Align to word boundary */ 58 dp += ((uintptr_t)dp & 1); /* Align to word boundary */
56 59
57 if (host_endian) { 60 if (host_endian) {
58 memcpy(dp, sp, 2); 61 memcpy(dp, sp, 2);
59 } else { 62 } else {
60 w = (sp[1] << 8) | sp[0]; 63 w = (sp[1] << 8) | sp[0];
61 *((uint16_t *)dp) = w; 64 *((uint16_t *)dp) = w;
62 } 65 }
63 sp += 2; 66 sp += 2;
64 dp += 2; 67 dp += 2;
65 break; 68 break;
69 case 'd': /* 32-bit word, convert from little endi an to CPU */
70 dp += ((uintptr_t)dp & 1); /* Align to word boundary */
71
72 if (host_endian) {
73 memcpy(dp, sp, 4);
74 } else {
75 d = (sp[3] << 24) | (sp[2] << 16) |
76 (sp[1] << 8) | sp[0];
77 *((uint32_t *)dp) = d;
78 }
79 sp += 4;
80 dp += 4;
81 break;
82 case 'u': /* 16 byte UUID */
83 memcpy(dp, sp, 16);
84 sp += 16;
85 dp += 16;
86 break;
66 } 87 }
67 } 88 }
68 89
69 return (int) (sp - source); 90 return (int) (sp - source);
70 } 91 }
71 92
72 static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint) 93 static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
73 { 94 {
74 if (endpoint->extra) 95 if (endpoint->extra)
75 free((unsigned char *) endpoint->extra); 96 free((unsigned char *) endpoint->extra);
76 } 97 }
77 98
78 static int parse_endpoint(struct libusb_context *ctx, 99 static int parse_endpoint(struct libusb_context *ctx,
79 struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer, 100 struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer,
80 int size, int host_endian) 101 int size, int host_endian)
81 { 102 {
82 struct usb_descriptor_header header; 103 struct usb_descriptor_header header;
83 unsigned char *extra; 104 unsigned char *extra;
84 unsigned char *begin; 105 unsigned char *begin;
85 int parsed = 0; 106 int parsed = 0;
86 int len; 107 int len;
87 108
88 » usbi_parse_descriptor(buffer, "bb", &header, 0); 109 » if (size < DESC_HEADER_LENGTH) {
89 110 » » usbi_err(ctx, "short endpoint descriptor read %d/%d",
90 » /* Everything should be fine being passed into here, but we sanity */ 111 » » » size, DESC_HEADER_LENGTH);
91 » /* check JIC */ 112 » » return LIBUSB_ERROR_IO;
92 » if (header.bLength > size) {
93 » » usbi_err(ctx, "ran out of descriptors parsing");
94 » » return -1;
95 } 113 }
96 114
115 usbi_parse_descriptor(buffer, "bb", &header, 0);
97 if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) { 116 if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) {
98 usbi_err(ctx, "unexpected descriptor %x (expected %x)", 117 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
99 header.bDescriptorType, LIBUSB_DT_ENDPOINT); 118 header.bDescriptorType, LIBUSB_DT_ENDPOINT);
100 return parsed; 119 return parsed;
101 } 120 }
102 121 » if (header.bLength > size) {
122 » » usbi_warn(ctx, "short endpoint descriptor read %d/%d",
123 » » » size, header.bLength);
124 » » return parsed;
125 » }
103 if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH) 126 if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH)
104 usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian) ; 127 usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian) ;
105 else if (header.bLength >= ENDPOINT_DESC_LENGTH) 128 else if (header.bLength >= ENDPOINT_DESC_LENGTH)
106 usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian); 129 usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian);
130 else {
131 usbi_err(ctx, "invalid endpoint bLength (%d)", header.bLength);
132 return LIBUSB_ERROR_IO;
133 }
107 134
108 buffer += header.bLength; 135 buffer += header.bLength;
109 size -= header.bLength; 136 size -= header.bLength;
110 parsed += header.bLength; 137 parsed += header.bLength;
111 138
112 /* Skip over the rest of the Class Specific or Vendor Specific */ 139 /* Skip over the rest of the Class Specific or Vendor Specific */
113 /* descriptors */ 140 /* descriptors */
114 begin = buffer; 141 begin = buffer;
115 while (size >= DESC_HEADER_LENGTH) { 142 while (size >= DESC_HEADER_LENGTH) {
116 usbi_parse_descriptor(buffer, "bb", &header, 0); 143 usbi_parse_descriptor(buffer, "bb", &header, 0);
117 144 » » if (header.bLength < DESC_HEADER_LENGTH) {
118 » » if (header.bLength < 2) { 145 » » » usbi_err(ctx, "invalid extra ep desc len (%d)",
119 » » » usbi_err(ctx, "invalid descriptor length %d", header.bLe ngth); 146 » » » » header.bLength);
120 » » » return -1; 147 » » » return LIBUSB_ERROR_IO;
148 » » } else if (header.bLength > size) {
149 » » » usbi_warn(ctx, "short extra ep desc read %d/%d",
150 » » » » size, header.bLength);
151 » » » return parsed;
121 } 152 }
122 153
123 /* If we find another "proper" descriptor then we're done */ 154 /* If we find another "proper" descriptor then we're done */
124 if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || 155 if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
125 (header.bDescriptorType == LIBUSB_DT_INTERFACE) || 156 (header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
126 (header.bDescriptorType == LIBUSB_DT_CONFIG) || 157 (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
127 (header.bDescriptorType == LIBUSB_DT_DEVICE)) 158 (header.bDescriptorType == LIBUSB_DT_DEVICE))
128 break; 159 break;
129 160
130 usbi_dbg("skipping descriptor %x", header.bDescriptorType); 161 usbi_dbg("skipping descriptor %x", header.bDescriptorType);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 } 212 }
182 213
183 static int parse_interface(libusb_context *ctx, 214 static int parse_interface(libusb_context *ctx,
184 struct libusb_interface *usb_interface, unsigned char *buffer, int size, 215 struct libusb_interface *usb_interface, unsigned char *buffer, int size,
185 int host_endian) 216 int host_endian)
186 { 217 {
187 int i; 218 int i;
188 int len; 219 int len;
189 int r; 220 int r;
190 int parsed = 0; 221 int parsed = 0;
222 int interface_number = -1;
191 size_t tmp; 223 size_t tmp;
192 struct usb_descriptor_header header; 224 struct usb_descriptor_header header;
193 struct libusb_interface_descriptor *ifp; 225 struct libusb_interface_descriptor *ifp;
194 unsigned char *begin; 226 unsigned char *begin;
195 227
196 usb_interface->num_altsetting = 0; 228 usb_interface->num_altsetting = 0;
197 229
198 while (size >= INTERFACE_DESC_LENGTH) { 230 while (size >= INTERFACE_DESC_LENGTH) {
199 struct libusb_interface_descriptor *altsetting = 231 struct libusb_interface_descriptor *altsetting =
200 (struct libusb_interface_descriptor *) usb_interface->al tsetting; 232 (struct libusb_interface_descriptor *) usb_interface->al tsetting;
201 » » altsetting = realloc(altsetting, 233 » » altsetting = usbi_reallocf(altsetting,
202 sizeof(struct libusb_interface_descriptor) * 234 sizeof(struct libusb_interface_descriptor) *
203 (usb_interface->num_altsetting + 1)); 235 (usb_interface->num_altsetting + 1));
204 if (!altsetting) { 236 if (!altsetting) {
205 r = LIBUSB_ERROR_NO_MEM; 237 r = LIBUSB_ERROR_NO_MEM;
206 goto err; 238 goto err;
207 } 239 }
208 usb_interface->altsetting = altsetting; 240 usb_interface->altsetting = altsetting;
209 241
210 ifp = altsetting + usb_interface->num_altsetting; 242 ifp = altsetting + usb_interface->num_altsetting;
243 usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
244 if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) {
245 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
246 ifp->bDescriptorType, LIBUSB_DT_INTERFACE);
247 return parsed;
248 }
249 if (ifp->bLength < INTERFACE_DESC_LENGTH) {
250 usbi_err(ctx, "invalid interface bLength (%d)",
251 ifp->bLength);
252 r = LIBUSB_ERROR_IO;
253 goto err;
254 }
255 if (ifp->bLength > size) {
256 usbi_warn(ctx, "short intf descriptor read %d/%d",
257 size, ifp->bLength);
258 return parsed;
259 }
260 if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
261 usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoi nts);
262 r = LIBUSB_ERROR_IO;
263 goto err;
264 }
265
211 usb_interface->num_altsetting++; 266 usb_interface->num_altsetting++;
212 usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
213 ifp->extra = NULL; 267 ifp->extra = NULL;
214 ifp->extra_length = 0; 268 ifp->extra_length = 0;
215 ifp->endpoint = NULL; 269 ifp->endpoint = NULL;
216 270
271 if (interface_number == -1)
272 interface_number = ifp->bInterfaceNumber;
273
217 /* Skip over the interface */ 274 /* Skip over the interface */
218 buffer += ifp->bLength; 275 buffer += ifp->bLength;
219 parsed += ifp->bLength; 276 parsed += ifp->bLength;
220 size -= ifp->bLength; 277 size -= ifp->bLength;
221 278
222 begin = buffer; 279 begin = buffer;
223 280
224 /* Skip over any interface, class or vendor descriptors */ 281 /* Skip over any interface, class or vendor descriptors */
225 while (size >= DESC_HEADER_LENGTH) { 282 while (size >= DESC_HEADER_LENGTH) {
226 usbi_parse_descriptor(buffer, "bb", &header, 0); 283 usbi_parse_descriptor(buffer, "bb", &header, 0);
227 » » » if (header.bLength < 2) { 284 » » » if (header.bLength < DESC_HEADER_LENGTH) {
228 » » » » usbi_err(ctx, "invalid descriptor of length %d", 285 » » » » usbi_err(ctx,
229 » » » » » header.bLength); 286 » » » » » "invalid extra intf desc len (%d)",
287 » » » » » header.bLength);
230 r = LIBUSB_ERROR_IO; 288 r = LIBUSB_ERROR_IO;
231 goto err; 289 goto err;
290 } else if (header.bLength > size) {
291 usbi_warn(ctx,
292 "short extra intf desc read %d/%d",
293 size, header.bLength);
294 return parsed;
232 } 295 }
233 296
234 /* If we find another "proper" descriptor then we're don e */ 297 /* If we find another "proper" descriptor then we're don e */
235 if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) || 298 if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
236 (header.bDescriptorType == LIBUSB_DT_END POINT) || 299 (header.bDescriptorType == LIBUSB_DT_END POINT) ||
237 (header.bDescriptorType == LIBUSB_DT_CON FIG) || 300 (header.bDescriptorType == LIBUSB_DT_CON FIG) ||
238 (header.bDescriptorType == LIBUSB_DT_DEV ICE)) 301 (header.bDescriptorType == LIBUSB_DT_DEV ICE))
239 break; 302 break;
240 303
241 buffer += header.bLength; 304 buffer += header.bLength;
242 parsed += header.bLength; 305 parsed += header.bLength;
243 size -= header.bLength; 306 size -= header.bLength;
244 } 307 }
245 308
246 /* Copy any unknown descriptors into a storage area for */ 309 /* Copy any unknown descriptors into a storage area for */
247 /* drivers to later parse */ 310 /* drivers to later parse */
248 len = (int)(buffer - begin); 311 len = (int)(buffer - begin);
249 if (len) { 312 if (len) {
250 ifp->extra = malloc(len); 313 ifp->extra = malloc(len);
251 if (!ifp->extra) { 314 if (!ifp->extra) {
252 r = LIBUSB_ERROR_NO_MEM; 315 r = LIBUSB_ERROR_NO_MEM;
253 goto err; 316 goto err;
254 } 317 }
255 memcpy((unsigned char *) ifp->extra, begin, len); 318 memcpy((unsigned char *) ifp->extra, begin, len);
256 ifp->extra_length = len; 319 ifp->extra_length = len;
257 } 320 }
258 321
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->bNumEndpoi nts);
270 r = LIBUSB_ERROR_IO;
271 goto err;
272 }
273
274 if (ifp->bNumEndpoints > 0) { 322 if (ifp->bNumEndpoints > 0) {
275 struct libusb_endpoint_descriptor *endpoint; 323 struct libusb_endpoint_descriptor *endpoint;
276 tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint _descriptor); 324 tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint _descriptor);
277 endpoint = malloc(tmp); 325 endpoint = malloc(tmp);
278 ifp->endpoint = endpoint; 326 ifp->endpoint = endpoint;
279 if (!endpoint) { 327 if (!endpoint) {
280 r = LIBUSB_ERROR_NO_MEM; 328 r = LIBUSB_ERROR_NO_MEM;
281 goto err; 329 goto err;
282 } 330 }
283 331
284 memset(endpoint, 0, tmp); 332 memset(endpoint, 0, tmp);
285 for (i = 0; i < ifp->bNumEndpoints; i++) { 333 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 pa rsing");
290 r = LIBUSB_ERROR_IO;
291 goto err;
292 }
293
294 r = parse_endpoint(ctx, endpoint + i, buffer, si ze, 334 r = parse_endpoint(ctx, endpoint + i, buffer, si ze,
295 host_endian); 335 host_endian);
296 if (r < 0) 336 if (r < 0)
297 goto err; 337 goto err;
338 if (r == 0) {
339 ifp->bNumEndpoints = (uint8_t)i;
340 break;;
341 }
298 342
299 buffer += r; 343 buffer += r;
300 parsed += r; 344 parsed += r;
301 size -= r; 345 size -= r;
302 } 346 }
303 } 347 }
304 348
305 /* We check to see if it's an alternate to this one */ 349 /* We check to see if it's an alternate to this one */
306 ifp = (struct libusb_interface_descriptor *) buffer; 350 ifp = (struct libusb_interface_descriptor *) buffer;
307 if (size < LIBUSB_DT_INTERFACE_SIZE || 351 if (size < LIBUSB_DT_INTERFACE_SIZE ||
308 ifp->bDescriptorType != LIBUSB_DT_INTERFACE || 352 ifp->bDescriptorType != LIBUSB_DT_INTERFACE ||
309 » » » » !ifp->bAlternateSetting) 353 » » » » ifp->bInterfaceNumber != interface_number)
310 return parsed; 354 return parsed;
311 } 355 }
312 356
313 return parsed; 357 return parsed;
314 err: 358 err:
315 clear_interface(usb_interface); 359 clear_interface(usb_interface);
316 return r; 360 return r;
317 } 361 }
318 362
319 static void clear_configuration(struct libusb_config_descriptor *config) 363 static void clear_configuration(struct libusb_config_descriptor *config)
320 { 364 {
321 if (config->interface) { 365 if (config->interface) {
322 int i; 366 int i;
323 for (i = 0; i < config->bNumInterfaces; i++) 367 for (i = 0; i < config->bNumInterfaces; i++)
324 clear_interface((struct libusb_interface *) 368 clear_interface((struct libusb_interface *)
325 config->interface + i); 369 config->interface + i);
326 free((void *) config->interface); 370 free((void *) config->interface);
327 } 371 }
328 if (config->extra) 372 if (config->extra)
329 free((void *) config->extra); 373 free((void *) config->extra);
330 } 374 }
331 375
332 static int parse_configuration(struct libusb_context *ctx, 376 static int parse_configuration(struct libusb_context *ctx,
333 struct libusb_config_descriptor *config, unsigned char *buffer, 377 struct libusb_config_descriptor *config, unsigned char *buffer,
334 » int host_endian) 378 » int size, int host_endian)
335 { 379 {
336 int i; 380 int i;
337 int r; 381 int r;
338 int size;
339 size_t tmp; 382 size_t tmp;
340 struct usb_descriptor_header header; 383 struct usb_descriptor_header header;
341 struct libusb_interface *usb_interface; 384 struct libusb_interface *usb_interface;
342 385
386 if (size < LIBUSB_DT_CONFIG_SIZE) {
387 usbi_err(ctx, "short config descriptor read %d/%d",
388 size, LIBUSB_DT_CONFIG_SIZE);
389 return LIBUSB_ERROR_IO;
390 }
391
343 usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian); 392 usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian);
344 » size = config->wTotalLength; 393 » if (config->bDescriptorType != LIBUSB_DT_CONFIG) {
345 394 » » usbi_err(ctx, "unexpected descriptor %x (expected %x)",
395 » » » config->bDescriptorType, LIBUSB_DT_CONFIG);
396 » » return LIBUSB_ERROR_IO;
397 » }
398 » if (config->bLength < LIBUSB_DT_CONFIG_SIZE) {
399 » » usbi_err(ctx, "invalid config bLength (%d)", config->bLength);
400 » » return LIBUSB_ERROR_IO;
401 » }
402 » if (config->bLength > size) {
403 » » usbi_err(ctx, "short config descriptor read %d/%d",
404 » » » size, config->bLength);
405 » » return LIBUSB_ERROR_IO;
406 » }
346 if (config->bNumInterfaces > USB_MAXINTERFACES) { 407 if (config->bNumInterfaces > USB_MAXINTERFACES) {
347 usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces ); 408 usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces );
348 return LIBUSB_ERROR_IO; 409 return LIBUSB_ERROR_IO;
349 } 410 }
350 411
351 tmp = config->bNumInterfaces * sizeof(struct libusb_interface); 412 tmp = config->bNumInterfaces * sizeof(struct libusb_interface);
352 usb_interface = malloc(tmp); 413 usb_interface = malloc(tmp);
353 config->interface = usb_interface; 414 config->interface = usb_interface;
354 if (!config->interface) 415 if (!config->interface)
355 return LIBUSB_ERROR_NO_MEM; 416 return LIBUSB_ERROR_NO_MEM;
356 417
357 memset(usb_interface, 0, tmp); 418 memset(usb_interface, 0, tmp);
358 buffer += config->bLength; 419 buffer += config->bLength;
359 size -= config->bLength; 420 size -= config->bLength;
360 421
361 config->extra = NULL; 422 config->extra = NULL;
362 config->extra_length = 0; 423 config->extra_length = 0;
363 424
364 for (i = 0; i < config->bNumInterfaces; i++) { 425 for (i = 0; i < config->bNumInterfaces; i++) {
365 int len; 426 int len;
366 unsigned char *begin; 427 unsigned char *begin;
367 428
368 /* Skip over the rest of the Class Specific or Vendor */ 429 /* Skip over the rest of the Class Specific or Vendor */
369 /* Specific descriptors */ 430 /* Specific descriptors */
370 begin = buffer; 431 begin = buffer;
371 while (size >= DESC_HEADER_LENGTH) { 432 while (size >= DESC_HEADER_LENGTH) {
372 usbi_parse_descriptor(buffer, "bb", &header, 0); 433 usbi_parse_descriptor(buffer, "bb", &header, 0);
373 434
374 » » » if ((header.bLength > size) || 435 » » » if (header.bLength < DESC_HEADER_LENGTH) {
375 » » » » » (header.bLength < DESC_HEADER_LENGTH)) { 436 » » » » usbi_err(ctx,
376 » » » » usbi_err(ctx, "invalid descriptor length of %d", 437 » » » » » "invalid extra config desc len (%d)",
377 » » » » » header.bLength); 438 » » » » » header.bLength);
378 r = LIBUSB_ERROR_IO; 439 r = LIBUSB_ERROR_IO;
379 goto err; 440 goto err;
441 } else if (header.bLength > size) {
442 usbi_warn(ctx,
443 "short extra config desc read %d/%d",
444 size, header.bLength);
445 config->bNumInterfaces = (uint8_t)i;
446 return size;
380 } 447 }
381 448
382 /* If we find another "proper" descriptor then we're don e */ 449 /* If we find another "proper" descriptor then we're don e */
383 if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || 450 if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
384 (header.bDescriptorType == LIBUSB_DT_INT ERFACE) || 451 (header.bDescriptorType == LIBUSB_DT_INT ERFACE) ||
385 (header.bDescriptorType == LIBUSB_DT_CON FIG) || 452 (header.bDescriptorType == LIBUSB_DT_CON FIG) ||
386 (header.bDescriptorType == LIBUSB_DT_DEV ICE)) 453 (header.bDescriptorType == LIBUSB_DT_DEV ICE))
387 break; 454 break;
388 455
389 usbi_dbg("skipping descriptor 0x%x\n", header.bDescripto rType); 456 usbi_dbg("skipping descriptor 0x%x\n", header.bDescripto rType);
(...skipping 14 matching lines...) Expand all
404 } 471 }
405 472
406 memcpy((unsigned char *) config->extra, begin, l en); 473 memcpy((unsigned char *) config->extra, begin, l en);
407 config->extra_length = len; 474 config->extra_length = len;
408 } 475 }
409 } 476 }
410 477
411 r = parse_interface(ctx, usb_interface + i, buffer, size, host_e ndian); 478 r = parse_interface(ctx, usb_interface + i, buffer, size, host_e ndian);
412 if (r < 0) 479 if (r < 0)
413 goto err; 480 goto err;
481 if (r == 0) {
482 config->bNumInterfaces = (uint8_t)i;
483 break;
484 }
414 485
415 buffer += r; 486 buffer += r;
416 size -= r; 487 size -= r;
417 } 488 }
418 489
419 return size; 490 return size;
420 491
421 err: 492 err:
422 clear_configuration(config); 493 clear_configuration(config);
423 return r; 494 return r;
424 } 495 }
425 496
497 static int raw_desc_to_config(struct libusb_context *ctx,
498 unsigned char *buf, int size, int host_endian,
499 struct libusb_config_descriptor **config)
500 {
501 struct libusb_config_descriptor *_config = malloc(sizeof(*_config));
502 int r;
503
504 if (!_config)
505 return LIBUSB_ERROR_NO_MEM;
506
507 r = parse_configuration(ctx, _config, buf, size, host_endian);
508 if (r < 0) {
509 usbi_err(ctx, "parse_configuration failed with error %d", r);
510 free(_config);
511 return r;
512 } else if (r > 0) {
513 usbi_warn(ctx, "still %d bytes of descriptor data left", r);
514 }
515
516 *config = _config;
517 return LIBUSB_SUCCESS;
518 }
519
520 int usbi_device_cache_descriptor(libusb_device *dev)
521 {
522 int r, host_endian = 0;
523
524 r = usbi_backend->get_device_descriptor(dev, (unsigned char *) &dev->dev ice_descriptor,
525 &host_endian);
526 if (r < 0)
527 return r;
528
529 if (!host_endian) {
530 dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_d escriptor.bcdUSB);
531 dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device _descriptor.idVendor);
532 dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->devic e_descriptor.idProduct);
533 dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->devic e_descriptor.bcdDevice);
534 }
535
536 return LIBUSB_SUCCESS;
537 }
538
426 /** \ingroup desc 539 /** \ingroup desc
427 * Get the USB device descriptor for a given device. 540 * Get the USB device descriptor for a given device.
428 * 541 *
429 * This is a non-blocking function; the device descriptor is cached in memory. 542 * This is a non-blocking function; the device descriptor is cached in memory.
430 * 543 *
544 * Note since libusbx-1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102, this
545 * function always succeeds.
546 *
431 * \param dev the device 547 * \param dev the device
432 * \param desc output location for the descriptor data 548 * \param desc output location for the descriptor data
433 * \returns 0 on success or a LIBUSB_ERROR code on failure 549 * \returns 0 on success or a LIBUSB_ERROR code on failure
434 */ 550 */
435 int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev, 551 int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
436 struct libusb_device_descriptor *desc) 552 struct libusb_device_descriptor *desc)
437 { 553 {
438 unsigned char raw_desc[DEVICE_DESC_LENGTH];
439 int host_endian = 0;
440 int r;
441
442 usbi_dbg(""); 554 usbi_dbg("");
443 » r = usbi_backend->get_device_descriptor(dev, raw_desc, &host_endian); 555 » memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor ,
444 » if (r < 0) 556 » sizeof (dev->device_descriptor));
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; 557 return 0;
455 } 558 }
456 559
457 /** \ingroup desc 560 /** \ingroup desc
458 * Get the USB configuration descriptor for the currently active configuration. 561 * Get the USB configuration descriptor for the currently active configuration.
459 * This is a non-blocking function which does not involve any requests being 562 * This is a non-blocking function which does not involve any requests being
460 * sent to the device. 563 * sent to the device.
461 * 564 *
462 * \param dev a device 565 * \param dev a device
463 * \param config output location for the USB configuration descriptor. Only 566 * \param config output location for the USB configuration descriptor. Only
464 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() 567 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
465 * after use. 568 * after use.
466 * \returns 0 on success 569 * \returns 0 on success
467 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state 570 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
468 * \returns another LIBUSB_ERROR code on error 571 * \returns another LIBUSB_ERROR code on error
469 * \see libusb_get_config_descriptor 572 * \see libusb_get_config_descriptor
470 */ 573 */
471 int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev, 574 int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
472 struct libusb_config_descriptor **config) 575 struct libusb_config_descriptor **config)
473 { 576 {
474 » struct libusb_config_descriptor *_config = malloc(sizeof(*_config)); 577 » struct libusb_config_descriptor _config;
475 » unsigned char tmp[8]; 578 » unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
476 unsigned char *buf = NULL; 579 unsigned char *buf = NULL;
477 int host_endian = 0; 580 int host_endian = 0;
478 int r; 581 int r;
479 582
480 » usbi_dbg(""); 583 » r = usbi_backend->get_active_config_descriptor(dev, tmp,
481 » if (!_config) 584 » » LIBUSB_DT_CONFIG_SIZE, &host_endian);
585 » if (r < 0)
586 » » return r;
587 » if (r < LIBUSB_DT_CONFIG_SIZE) {
588 » » usbi_err(dev->ctx, "short config descriptor read %d/%d",
589 » » » r, LIBUSB_DT_CONFIG_SIZE);
590 » » return LIBUSB_ERROR_IO;
591 » }
592
593 » usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
594 » buf = malloc(_config.wTotalLength);
595 » if (!buf)
482 return LIBUSB_ERROR_NO_MEM; 596 return LIBUSB_ERROR_NO_MEM;
483 597
484 r = usbi_backend->get_active_config_descriptor(dev, tmp, sizeof(tmp),
485 &host_endian);
486 if (r < 0)
487 goto err;
488
489 usbi_parse_descriptor(tmp, "bbw", _config, host_endian);
490 buf = malloc(_config->wTotalLength);
491 if (!buf) {
492 r = LIBUSB_ERROR_NO_MEM;
493 goto err;
494 }
495
496 r = usbi_backend->get_active_config_descriptor(dev, buf, 598 r = usbi_backend->get_active_config_descriptor(dev, buf,
497 » » _config->wTotalLength, &host_endian); 599 » » _config.wTotalLength, &host_endian);
498 » if (r < 0) 600 » if (r >= 0)
499 » » goto err; 601 » » r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
500
501 » r = parse_configuration(dev->ctx, _config, buf, host_endian);
502 » if (r < 0) {
503 » » usbi_err(dev->ctx, "parse_configuration failed with error %d", r );
504 » » goto err;
505 » } else if (r > 0) {
506 » » usbi_warn(dev->ctx, "descriptor data still left");
507 » }
508 602
509 free(buf); 603 free(buf);
510 *config = _config;
511 return 0;
512
513 err:
514 free(_config);
515 if (buf)
516 free(buf);
517 return r; 604 return r;
518 } 605 }
519 606
520 /** \ingroup desc 607 /** \ingroup desc
521 * Get a USB configuration descriptor based on its index. 608 * Get a USB configuration descriptor based on its index.
522 * This is a non-blocking function which does not involve any requests being 609 * This is a non-blocking function which does not involve any requests being
523 * sent to the device. 610 * sent to the device.
524 * 611 *
525 * \param dev a device 612 * \param dev a device
526 * \param config_index the index of the configuration you wish to retrieve 613 * \param config_index the index of the configuration you wish to retrieve
527 * \param config output location for the USB configuration descriptor. Only 614 * \param config output location for the USB configuration descriptor. Only
528 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() 615 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
529 * after use. 616 * after use.
530 * \returns 0 on success 617 * \returns 0 on success
531 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist 618 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
532 * \returns another LIBUSB_ERROR code on error 619 * \returns another LIBUSB_ERROR code on error
533 * \see libusb_get_active_config_descriptor() 620 * \see libusb_get_active_config_descriptor()
534 * \see libusb_get_config_descriptor_by_value() 621 * \see libusb_get_config_descriptor_by_value()
535 */ 622 */
536 int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, 623 int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
537 uint8_t config_index, struct libusb_config_descriptor **config) 624 uint8_t config_index, struct libusb_config_descriptor **config)
538 { 625 {
539 » struct libusb_config_descriptor *_config; 626 » struct libusb_config_descriptor _config;
540 » unsigned char tmp[8]; 627 » unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
541 unsigned char *buf = NULL; 628 unsigned char *buf = NULL;
542 int host_endian = 0; 629 int host_endian = 0;
543 int r; 630 int r;
544 631
545 usbi_dbg("index %d", config_index); 632 usbi_dbg("index %d", config_index);
546 if (config_index >= dev->num_configurations) 633 if (config_index >= dev->num_configurations)
547 return LIBUSB_ERROR_NOT_FOUND; 634 return LIBUSB_ERROR_NOT_FOUND;
548 635
549 » _config = malloc(sizeof(*_config)); 636 » r = usbi_backend->get_config_descriptor(dev, config_index, tmp,
550 » if (!_config) 637 » » LIBUSB_DT_CONFIG_SIZE, &host_endian);
638 » if (r < 0)
639 » » return r;
640 » if (r < LIBUSB_DT_CONFIG_SIZE) {
641 » » usbi_err(dev->ctx, "short config descriptor read %d/%d",
642 » » » r, LIBUSB_DT_CONFIG_SIZE);
643 » » return LIBUSB_ERROR_IO;
644 » }
645
646 » usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
647 » buf = malloc(_config.wTotalLength);
648 » if (!buf)
551 return LIBUSB_ERROR_NO_MEM; 649 return LIBUSB_ERROR_NO_MEM;
552 650
553 r = usbi_backend->get_config_descriptor(dev, config_index, tmp,
554 sizeof(tmp), &host_endian);
555 if (r < 0)
556 goto err;
557
558 usbi_parse_descriptor(tmp, "bbw", _config, host_endian);
559 buf = malloc(_config->wTotalLength);
560 if (!buf) {
561 r = LIBUSB_ERROR_NO_MEM;
562 goto err;
563 }
564
565 host_endian = 0;
566 r = usbi_backend->get_config_descriptor(dev, config_index, buf, 651 r = usbi_backend->get_config_descriptor(dev, config_index, buf,
567 » » _config->wTotalLength, &host_endian); 652 » » _config.wTotalLength, &host_endian);
568 » if (r < 0) 653 » if (r >= 0)
569 » » goto err; 654 » » r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
570
571 » r = parse_configuration(dev->ctx, _config, buf, host_endian);
572 » if (r < 0) {
573 » » usbi_err(dev->ctx, "parse_configuration failed with error %d", r );
574 » » goto err;
575 » } else if (r > 0) {
576 » » usbi_warn(dev->ctx, "descriptor data still left");
577 » }
578 655
579 free(buf); 656 free(buf);
580 *config = _config;
581 return 0;
582
583 err:
584 free(_config);
585 if (buf)
586 free(buf);
587 return r; 657 return r;
588 } 658 }
589 659
590 /* iterate through all configurations, returning the index of the configuration 660 /* iterate through all configurations, returning the index of the configuration
591 * matching a specific bConfigurationValue in the idx output parameter, or -1 661 * matching a specific bConfigurationValue in the idx output parameter, or -1
592 * if the config was not found. 662 * if the config was not found.
593 * returns 0 or a LIBUSB_ERROR code 663 * returns 0 or a LIBUSB_ERROR code
594 */ 664 */
595 int usbi_get_config_index_by_value(struct libusb_device *dev, 665 int usbi_get_config_index_by_value(struct libusb_device *dev,
596 uint8_t bConfigurationValue, int *idx) 666 uint8_t bConfigurationValue, int *idx)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 * after use. 698 * after use.
629 * \returns 0 on success 699 * \returns 0 on success
630 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist 700 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
631 * \returns another LIBUSB_ERROR code on error 701 * \returns another LIBUSB_ERROR code on error
632 * \see libusb_get_active_config_descriptor() 702 * \see libusb_get_active_config_descriptor()
633 * \see libusb_get_config_descriptor() 703 * \see libusb_get_config_descriptor()
634 */ 704 */
635 int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev, 705 int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
636 uint8_t bConfigurationValue, struct libusb_config_descriptor **config) 706 uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
637 { 707 {
638 » int idx; 708 » int r, idx, host_endian;
639 » int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx); 709 » unsigned char *buf = NULL;
710
711 » if (usbi_backend->get_config_descriptor_by_value) {
712 » » r = usbi_backend->get_config_descriptor_by_value(dev,
713 » » » bConfigurationValue, &buf, &host_endian);
714 » » if (r < 0)
715 » » » return r;
716 » » return raw_desc_to_config(dev->ctx, buf, r, host_endian, config) ;
717 » }
718
719 » r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
640 if (r < 0) 720 if (r < 0)
641 return r; 721 return r;
642 else if (idx == -1) 722 else if (idx == -1)
643 return LIBUSB_ERROR_NOT_FOUND; 723 return LIBUSB_ERROR_NOT_FOUND;
644 else 724 else
645 return libusb_get_config_descriptor(dev, (uint8_t) idx, config); 725 return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
646 } 726 }
647 727
648 /** \ingroup desc 728 /** \ingroup desc
649 * Free a configuration descriptor obtained from 729 * Free a configuration descriptor obtained from
650 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). 730 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
651 * It is safe to call this function with a NULL config parameter, in which 731 * It is safe to call this function with a NULL config parameter, in which
652 * case the function simply returns. 732 * case the function simply returns.
653 * 733 *
654 * \param config the configuration descriptor to free 734 * \param config the configuration descriptor to free
655 */ 735 */
656 void API_EXPORTED libusb_free_config_descriptor( 736 void API_EXPORTED libusb_free_config_descriptor(
657 struct libusb_config_descriptor *config) 737 struct libusb_config_descriptor *config)
658 { 738 {
659 if (!config) 739 if (!config)
660 return; 740 return;
661 741
662 clear_configuration(config); 742 clear_configuration(config);
663 free(config); 743 free(config);
664 } 744 }
665 745
666 /** \ingroup desc 746 /** \ingroup desc
747 * Get an endpoints superspeed endpoint companion descriptor (if any)
748 *
749 * \param ctx the context to operate on, or NULL for the default context
750 * \param endpoint endpoint descriptor from which to get the superspeed
751 * endpoint companion descriptor
752 * \param ep_comp output location for the superspeed endpoint companion
753 * descriptor. Only valid if 0 was returned. Must be freed with
754 * libusb_free_ss_endpoint_companion_descriptor() after use.
755 * \returns 0 on success
756 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
757 * \returns another LIBUSB_ERROR code on error
758 */
759 int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
760 struct libusb_context *ctx,
761 const struct libusb_endpoint_descriptor *endpoint,
762 struct libusb_ss_endpoint_companion_descriptor **ep_comp)
763 {
764 struct usb_descriptor_header header;
765 int size = endpoint->extra_length;
766 const unsigned char *buffer = endpoint->extra;
767
768 *ep_comp = NULL;
769
770 while (size >= DESC_HEADER_LENGTH) {
771 usbi_parse_descriptor(buffer, "bb", &header, 0);
772 if (header.bLength < 2 || header.bLength > size) {
773 usbi_err(ctx, "invalid descriptor length %d",
774 header.bLength);
775 return LIBUSB_ERROR_IO;
776 }
777 if (header.bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
778 buffer += header.bLength;
779 size -= header.bLength;
780 continue;
781 }
782 if (header.bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) {
783 usbi_err(ctx, "invalid ss-ep-comp-desc length %d",
784 header.bLength);
785 return LIBUSB_ERROR_IO;
786 }
787 *ep_comp = malloc(sizeof(**ep_comp));
788 if (*ep_comp == NULL)
789 return LIBUSB_ERROR_NO_MEM;
790 usbi_parse_descriptor(buffer, "bbbbw", *ep_comp, 0);
791 return LIBUSB_SUCCESS;
792 }
793 return LIBUSB_ERROR_NOT_FOUND;
794 }
795
796 /** \ingroup desc
797 * Free a superspeed endpoint companion descriptor obtained from
798 * libusb_get_ss_endpoint_companion_descriptor().
799 * It is safe to call this function with a NULL ep_comp parameter, in which
800 * case the function simply returns.
801 *
802 * \param ep_comp the superspeed endpoint companion descriptor to free
803 */
804 void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor(
805 struct libusb_ss_endpoint_companion_descriptor *ep_comp)
806 {
807 free(ep_comp);
808 }
809
810 static int parse_bos(struct libusb_context *ctx,
811 struct libusb_bos_descriptor **bos,
812 unsigned char *buffer, int size, int host_endian)
813 {
814 struct libusb_bos_descriptor bos_header, *_bos;
815 struct libusb_bos_dev_capability_descriptor dev_cap;
816 int i;
817
818 if (size < LIBUSB_DT_BOS_SIZE) {
819 usbi_err(ctx, "short bos descriptor read %d/%d",
820 size, LIBUSB_DT_BOS_SIZE);
821 return LIBUSB_ERROR_IO;
822 }
823
824 usbi_parse_descriptor(buffer, "bbwb", &bos_header, host_endian);
825 if (bos_header.bDescriptorType != LIBUSB_DT_BOS) {
826 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
827 bos_header.bDescriptorType, LIBUSB_DT_BOS);
828 return LIBUSB_ERROR_IO;
829 }
830 if (bos_header.bLength < LIBUSB_DT_BOS_SIZE) {
831 usbi_err(ctx, "invalid bos bLength (%d)", bos_header.bLength);
832 return LIBUSB_ERROR_IO;
833 }
834 if (bos_header.bLength > size) {
835 usbi_err(ctx, "short bos descriptor read %d/%d",
836 size, bos_header.bLength);
837 return LIBUSB_ERROR_IO;
838 }
839
840 _bos = calloc (1,
841 sizeof(*_bos) + bos_header.bNumDeviceCaps * sizeof(void *));
842 if (!_bos)
843 return LIBUSB_ERROR_NO_MEM;
844
845 usbi_parse_descriptor(buffer, "bbwb", _bos, host_endian);
846 buffer += bos_header.bLength;
847 size -= bos_header.bLength;
848
849 /* Get the device capability descriptors */
850 for (i = 0; i < bos_header.bNumDeviceCaps; i++) {
851 if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
852 usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
853 size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
854 break;
855 }
856 usbi_parse_descriptor(buffer, "bbb", &dev_cap, host_endian);
857 if (dev_cap.bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
858 usbi_warn(ctx, "unexpected descriptor %x (expected %x)",
859 dev_cap.bDescriptorType, LIBUSB_DT_DEVICE_CAPA BILITY);
860 break;
861 }
862 if (dev_cap.bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
863 usbi_err(ctx, "invalid dev-cap bLength (%d)",
864 dev_cap.bLength);
865 libusb_free_bos_descriptor(_bos);
866 return LIBUSB_ERROR_IO;
867 }
868 if (dev_cap.bLength > size) {
869 usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
870 size, dev_cap.bLength);
871 break;
872 }
873
874 _bos->dev_capability[i] = malloc(dev_cap.bLength);
875 if (!_bos->dev_capability[i]) {
876 libusb_free_bos_descriptor(_bos);
877 return LIBUSB_ERROR_NO_MEM;
878 }
879 memcpy(_bos->dev_capability[i], buffer, dev_cap.bLength);
880 buffer += dev_cap.bLength;
881 size -= dev_cap.bLength;
882 }
883 _bos->bNumDeviceCaps = (uint8_t)i;
884 *bos = _bos;
885
886 return LIBUSB_SUCCESS;
887 }
888
889 /** \ingroup desc
890 * Get a Binary Object Store (BOS) descriptor
891 * This is a BLOCKING function, which will send requests to the device.
892 *
893 * \param handle the handle of an open libusb device
894 * \param bos output location for the BOS descriptor. Only valid if 0 was return ed.
895 * Must be freed with \ref libusb_free_bos_descriptor() after use.
896 * \returns 0 on success
897 * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
898 * \returns another LIBUSB_ERROR code on error
899 */
900 int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle,
901 struct libusb_bos_descriptor **bos)
902 {
903 struct libusb_bos_descriptor _bos;
904 uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0};
905 unsigned char *bos_data = NULL;
906 const int host_endian = 0;
907 int r;
908
909 /* Read the BOS. This generates 2 requests on the bus,
910 * one for the header, and one for the full BOS */
911 r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_header,
912 LIBUSB_DT_BOS_SIZE);
913 if (r < 0) {
914 if (r != LIBUSB_ERROR_PIPE)
915 usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r) ;
916 return r;
917 }
918 if (r < LIBUSB_DT_BOS_SIZE) {
919 usbi_err(handle->dev->ctx, "short BOS read %d/%d",
920 r, LIBUSB_DT_BOS_SIZE);
921 return LIBUSB_ERROR_IO;
922 }
923
924 usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian);
925 usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities",
926 _bos.wTotalLength, _bos.bNumDeviceCaps);
927 bos_data = calloc(_bos.wTotalLength, 1);
928 if (bos_data == NULL)
929 return LIBUSB_ERROR_NO_MEM;
930
931 r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_data,
932 _bos.wTotalLength);
933 if (r >= 0)
934 r = parse_bos(handle->dev->ctx, bos, bos_data, r, host_endian);
935 else
936 usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);
937
938 free(bos_data);
939 return r;
940 }
941
942 /** \ingroup desc
943 * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
944 * It is safe to call this function with a NULL bos parameter, in which
945 * case the function simply returns.
946 *
947 * \param bos the BOS descriptor to free
948 */
949 void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
950 {
951 int i;
952
953 if (!bos)
954 return;
955
956 for (i = 0; i < bos->bNumDeviceCaps; i++)
957 free(bos->dev_capability[i]);
958 free(bos);
959 }
960
961 /** \ingroup desc
962 * Get an USB 2.0 Extension descriptor
963 *
964 * \param ctx the context to operate on, or NULL for the default context
965 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
966 * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
967 * LIBUSB_BT_USB_2_0_EXTENSION
968 * \param usb_2_0_extension output location for the USB 2.0 Extension
969 * descriptor. Only valid if 0 was returned. Must be freed with
970 * libusb_free_usb_2_0_extension_descriptor() after use.
971 * \returns 0 on success
972 * \returns a LIBUSB_ERROR code on error
973 */
974 int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
975 struct libusb_context *ctx,
976 struct libusb_bos_dev_capability_descriptor *dev_cap,
977 struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
978 {
979 struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension;
980 const int host_endian = 0;
981
982 if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) {
983 usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
984 dev_cap->bDevCapabilityType,
985 LIBUSB_BT_USB_2_0_EXTENSION);
986 return LIBUSB_ERROR_INVALID_PARAM;
987 }
988 if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) {
989 usbi_err(ctx, "short dev-cap descriptor read %d/%d",
990 dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE);
991 return LIBUSB_ERROR_IO;
992 }
993
994 _usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension));
995 if (!_usb_2_0_extension)
996 return LIBUSB_ERROR_NO_MEM;
997
998 usbi_parse_descriptor((unsigned char *)dev_cap, "bbbd",
999 _usb_2_0_extension, host_endian);
1000
1001 *usb_2_0_extension = _usb_2_0_extension;
1002 return LIBUSB_SUCCESS;
1003 }
1004
1005 /** \ingroup desc
1006 * Free a USB 2.0 Extension descriptor obtained from
1007 * libusb_get_usb_2_0_extension_descriptor().
1008 * It is safe to call this function with a NULL usb_2_0_extension parameter,
1009 * in which case the function simply returns.
1010 *
1011 * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
1012 */
1013 void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
1014 struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
1015 {
1016 free(usb_2_0_extension);
1017 }
1018
1019 /** \ingroup desc
1020 * Get a SuperSpeed USB Device Capability descriptor
1021 *
1022 * \param ctx the context to operate on, or NULL for the default context
1023 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1024 * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1025 * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1026 * \param ss_usb_device_cap output location for the SuperSpeed USB Device
1027 * Capability descriptor. Only valid if 0 was returned. Must be freed with
1028 * libusb_free_ss_usb_device_capability_descriptor() after use.
1029 * \returns 0 on success
1030 * \returns a LIBUSB_ERROR code on error
1031 */
1032 int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
1033 struct libusb_context *ctx,
1034 struct libusb_bos_dev_capability_descriptor *dev_cap,
1035 struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
1036 {
1037 struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap;
1038 const int host_endian = 0;
1039
1040 if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
1041 usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
1042 dev_cap->bDevCapabilityType,
1043 LIBUSB_BT_SS_USB_DEVICE_CAPABILITY);
1044 return LIBUSB_ERROR_INVALID_PARAM;
1045 }
1046 if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) {
1047 usbi_err(ctx, "short dev-cap descriptor read %d/%d",
1048 dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SI ZE);
1049 return LIBUSB_ERROR_IO;
1050 }
1051
1052 _ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap));
1053 if (!_ss_usb_device_cap)
1054 return LIBUSB_ERROR_NO_MEM;
1055
1056 usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw",
1057 _ss_usb_device_cap, host_endian);
1058
1059 *ss_usb_device_cap = _ss_usb_device_cap;
1060 return LIBUSB_SUCCESS;
1061 }
1062
1063 /** \ingroup desc
1064 * Free a SuperSpeed USB Device Capability descriptor obtained from
1065 * libusb_get_ss_usb_device_capability_descriptor().
1066 * It is safe to call this function with a NULL ss_usb_device_cap
1067 * parameter, in which case the function simply returns.
1068 *
1069 * \param ss_usb_device_cap the USB 2.0 Extension descriptor to free
1070 */
1071 void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
1072 struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
1073 {
1074 free(ss_usb_device_cap);
1075 }
1076
1077 /** \ingroup desc
1078 * Get a Container ID descriptor
1079 *
1080 * \param ctx the context to operate on, or NULL for the default context
1081 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1082 * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
1083 * LIBUSB_BT_CONTAINER_ID
1084 * \param container_id output location for the Container ID descriptor.
1085 * Only valid if 0 was returned. Must be freed with
1086 * libusb_free_container_id_descriptor() after use.
1087 * \returns 0 on success
1088 * \returns a LIBUSB_ERROR code on error
1089 */
1090 int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx,
1091 struct libusb_bos_dev_capability_descriptor *dev_cap,
1092 struct libusb_container_id_descriptor **container_id)
1093 {
1094 struct libusb_container_id_descriptor *_container_id;
1095 const int host_endian = 0;
1096
1097 if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) {
1098 usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
1099 dev_cap->bDevCapabilityType,
1100 LIBUSB_BT_CONTAINER_ID);
1101 return LIBUSB_ERROR_INVALID_PARAM;
1102 }
1103 if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) {
1104 usbi_err(ctx, "short dev-cap descriptor read %d/%d",
1105 dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE);
1106 return LIBUSB_ERROR_IO;
1107 }
1108
1109 _container_id = malloc(sizeof(*_container_id));
1110 if (!_container_id)
1111 return LIBUSB_ERROR_NO_MEM;
1112
1113 usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbu",
1114 _container_id, host_endian);
1115
1116 *container_id = _container_id;
1117 return LIBUSB_SUCCESS;
1118 }
1119
1120 /** \ingroup desc
1121 * Free a Container ID descriptor obtained from
1122 * libusb_get_container_id_descriptor().
1123 * It is safe to call this function with a NULL container_id parameter,
1124 * in which case the function simply returns.
1125 *
1126 * \param container_id the USB 2.0 Extension descriptor to free
1127 */
1128 void API_EXPORTED libusb_free_container_id_descriptor(
1129 struct libusb_container_id_descriptor *container_id)
1130 {
1131 free(container_id);
1132 }
1133
1134 /** \ingroup desc
667 * Retrieve a string descriptor in C style ASCII. 1135 * Retrieve a string descriptor in C style ASCII.
668 * 1136 *
669 * Wrapper around libusb_get_string_descriptor(). Uses the first language 1137 * Wrapper around libusb_get_string_descriptor(). Uses the first language
670 * supported by the device. 1138 * supported by the device.
671 * 1139 *
672 * \param dev a device handle 1140 * \param dev a device handle
673 * \param desc_index the index of the descriptor to retrieve 1141 * \param desc_index the index of the descriptor to retrieve
674 * \param data output buffer for ASCII string descriptor 1142 * \param data output buffer for ASCII string descriptor
675 * \param length size of data buffer 1143 * \param length size of data buffer
676 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure 1144 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 if (tbuf[1] != LIBUSB_DT_STRING) 1179 if (tbuf[1] != LIBUSB_DT_STRING)
712 return LIBUSB_ERROR_IO; 1180 return LIBUSB_ERROR_IO;
713 1181
714 if (tbuf[0] > r) 1182 if (tbuf[0] > r)
715 return LIBUSB_ERROR_IO; 1183 return LIBUSB_ERROR_IO;
716 1184
717 for (di = 0, si = 2; si < tbuf[0]; si += 2) { 1185 for (di = 0, si = 2; si < tbuf[0]; si += 2) {
718 if (di >= (length - 1)) 1186 if (di >= (length - 1))
719 break; 1187 break;
720 1188
721 » » if (tbuf[si + 1]) /* high byte */ 1189 » » if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */
722 data[di++] = '?'; 1190 data[di++] = '?';
723 else 1191 else
724 data[di++] = tbuf[si]; 1192 data[di++] = tbuf[si];
725 } 1193 }
726 1194
727 data[di] = 0; 1195 data[di] = 0;
728 return di; 1196 return di;
729 } 1197 }
730
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698