descriptor.c 23 KB

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