Coverage Report

Created: 2026-10-17 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libusb/libusb/descriptor.c
Line
Count
Source
1
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
2
/*
3
 * USB descriptor handling functions for libusb
4
 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
5
 * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
6
 *
7
 * SPDX-License-Identifier: LGPL-2.1-or-later
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
24
#include "libusbi.h"
25
26
#include <string.h>
27
28
0
#define DESC_HEADER_LENGTH  2
29
30
/** @defgroup libusb_desc USB descriptors
31
 * This page details how to examine the various standard USB descriptors
32
 * for detected devices
33
 */
34
35
static inline uint16_t ReadLittleEndian16(const uint8_t p[2])
36
0
{
37
0
  return (uint16_t)((uint16_t)p[1] << 8 |
38
0
        (uint16_t)p[0]);
39
0
}
40
41
static inline uint32_t ReadLittleEndian32(const uint8_t p[4])
42
0
{
43
0
  return ((uint32_t)p[3] << 24 |
44
0
      (uint32_t)p[2] << 16 |
45
0
      (uint32_t)p[1] << 8 |
46
0
      (uint32_t)p[0]);
47
0
}
48
49
static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
50
0
{
51
0
  free((void *)endpoint->extra);
52
0
}
53
54
static int parse_endpoint(struct libusb_context *ctx,
55
  struct libusb_endpoint_descriptor *endpoint, const uint8_t *buffer, int size)
56
0
{
57
0
  const struct usbi_descriptor_header *header;
58
0
  const uint8_t *begin;
59
0
  void *extra;
60
0
  int parsed = 0;
61
62
0
  if (size < DESC_HEADER_LENGTH) {
63
0
    usbi_err(ctx, "short endpoint descriptor read %d/%d",
64
0
       size, DESC_HEADER_LENGTH);
65
0
    return LIBUSB_ERROR_IO;
66
0
  }
67
68
0
  header = (const struct usbi_descriptor_header *)buffer;
69
0
  if (header->bDescriptorType != LIBUSB_DT_ENDPOINT) {
70
0
    usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
71
0
      header->bDescriptorType, LIBUSB_DT_ENDPOINT);
72
0
    return parsed;
73
0
  } else if (header->bLength < LIBUSB_DT_ENDPOINT_SIZE) {
74
0
    usbi_err(ctx, "invalid endpoint bLength (%u)", header->bLength);
75
0
    return LIBUSB_ERROR_IO;
76
0
  } else if (header->bLength > size) {
77
0
    usbi_warn(ctx, "short endpoint descriptor read %d/%u",
78
0
        size, header->bLength);
79
0
    return parsed;
80
0
  }
81
82
0
  endpoint->bLength = buffer[0];
83
0
  endpoint->bDescriptorType = buffer[1];
84
0
  endpoint->bEndpointAddress = buffer[2];
85
0
  endpoint->bmAttributes = buffer[3];
86
0
  endpoint->wMaxPacketSize = ReadLittleEndian16(&buffer[4]);
87
0
  endpoint->bInterval = buffer[6];
88
0
  if (header->bLength >= LIBUSB_DT_ENDPOINT_AUDIO_SIZE) {
89
0
    endpoint->bRefresh = buffer[7];
90
0
    endpoint->bSynchAddress = buffer[8];
91
0
  }
92
93
0
  buffer += header->bLength;
94
0
  size -= header->bLength;
95
0
  parsed += header->bLength;
96
97
  /* Skip over the rest of the Class Specific or Vendor Specific */
98
  /*  descriptors */
99
0
  begin = buffer;
100
0
  while (size >= DESC_HEADER_LENGTH) {
101
0
    header = (const struct usbi_descriptor_header *)buffer;
102
0
    if (header->bLength < DESC_HEADER_LENGTH) {
103
0
      usbi_err(ctx, "invalid extra ep desc len (%u)",
104
0
         header->bLength);
105
0
      return LIBUSB_ERROR_IO;
106
0
    } else if (header->bLength > size) {
107
0
      usbi_warn(ctx, "short extra ep desc read %d/%u",
108
0
          size, header->bLength);
109
0
      return parsed;
110
0
    }
111
112
    /* If we find another "proper" descriptor then we're done  */
113
0
    if (header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
114
0
        header->bDescriptorType == LIBUSB_DT_INTERFACE ||
115
0
        header->bDescriptorType == LIBUSB_DT_CONFIG ||
116
0
        header->bDescriptorType == LIBUSB_DT_DEVICE)
117
0
      break;
118
119
0
    usbi_dbg(ctx, "skipping descriptor 0x%x", header->bDescriptorType);
120
0
    buffer += header->bLength;
121
0
    size -= header->bLength;
122
0
    parsed += header->bLength;
123
0
  }
124
125
  /* Copy any unknown descriptors into a storage area for drivers */
126
  /*  to later parse */
127
0
  ptrdiff_t len = buffer - begin;
128
0
  if (len <= 0)
129
0
    return parsed;
130
131
0
  extra = malloc((size_t)len);
132
0
  if (!extra)
133
0
    return LIBUSB_ERROR_NO_MEM;
134
135
0
  memcpy(extra, begin, (size_t)len);
136
0
  endpoint->extra = (const unsigned char *)extra;
137
0
  endpoint->extra_length = (int)len;
138
139
0
  return parsed;
140
0
}
141
142
static void clear_interface(struct libusb_interface *usb_interface)
143
0
{
144
0
  int i;
145
146
0
  if (usb_interface->altsetting) {
147
0
    for (i = 0; i < usb_interface->num_altsetting; i++) {
148
0
      struct libusb_interface_descriptor *ifp =
149
0
        (struct libusb_interface_descriptor *)
150
0
        usb_interface->altsetting + i;
151
152
0
      free((void *)ifp->extra);
153
0
      ifp->extra = NULL;
154
0
      ifp->extra_length = 0;
155
0
      if (ifp->endpoint) {
156
0
        uint8_t j;
157
158
0
        for (j = 0; j < ifp->bNumEndpoints; j++)
159
0
          clear_endpoint((struct libusb_endpoint_descriptor *)
160
0
                   ifp->endpoint + j);
161
0
      }
162
0
      free((void *)ifp->endpoint);
163
0
      ifp->endpoint = NULL;
164
0
      ifp->bNumEndpoints = 0;
165
0
    }
166
0
  }
167
0
  free((void *)usb_interface->altsetting);
168
0
  usb_interface->altsetting = NULL;
169
0
  usb_interface->num_altsetting = 0;
170
0
}
171
172
static int parse_interface(libusb_context *ctx,
173
  struct libusb_interface *usb_interface, const uint8_t *buffer, int size)
174
0
{
175
0
  int r;
176
0
  int parsed = 0;
177
0
  int interface_number = -1;
178
0
  const struct usbi_descriptor_header *header;
179
0
  const struct usbi_interface_descriptor *if_desc;
180
0
  struct libusb_interface_descriptor *ifp;
181
0
  const uint8_t *begin;
182
183
0
  while (size >= LIBUSB_DT_INTERFACE_SIZE) {
184
0
    uint8_t bLength = buffer[0];
185
0
    uint8_t bDescriptorType = buffer[1];
186
0
    uint8_t bInterfaceNumber = buffer[2];
187
0
    uint8_t bAlternateSetting = buffer[3];
188
0
    uint8_t bNumEndpoints = buffer[4];
189
0
    uint8_t bInterfaceClass = buffer[5];
190
0
    uint8_t bInterfaceSubClass = buffer[6];
191
0
    uint8_t bInterfaceProtocol = buffer[7];
192
0
    uint8_t iInterface = buffer[8];
193
194
0
    if (bDescriptorType != LIBUSB_DT_INTERFACE) {
195
0
      usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
196
0
         bDescriptorType, LIBUSB_DT_INTERFACE);
197
0
      return parsed;
198
0
    } else if (bLength < LIBUSB_DT_INTERFACE_SIZE) {
199
0
      usbi_err(ctx, "invalid interface bLength (%u)",
200
0
         bLength);
201
0
      r = LIBUSB_ERROR_IO;
202
0
      goto err;
203
0
    } else if (bLength > size) {
204
0
      usbi_warn(ctx, "short intf descriptor read %d/%u",
205
0
         size, bLength);
206
0
      return parsed;
207
0
    } else if (bNumEndpoints > USB_MAXENDPOINTS) {
208
0
      usbi_err(ctx, "too many endpoints (%u)", bNumEndpoints);
209
0
      r = LIBUSB_ERROR_IO;
210
0
      goto err;
211
0
    }
212
213
0
    struct libusb_interface_descriptor *altsetting;
214
0
    altsetting = (struct libusb_interface_descriptor *)realloc((void *)usb_interface->altsetting,
215
0
      sizeof(*altsetting) * (size_t)(usb_interface->num_altsetting + 1));
216
0
    if (!altsetting) {
217
0
      r = LIBUSB_ERROR_NO_MEM;
218
0
      goto err;
219
0
    }
220
221
0
    ifp = altsetting + usb_interface->num_altsetting;
222
0
    ifp->bLength = bLength;
223
0
    ifp->bDescriptorType = bDescriptorType;
224
0
    ifp->bInterfaceNumber = bInterfaceNumber;
225
0
    ifp->bAlternateSetting = bAlternateSetting;
226
0
    ifp->bNumEndpoints = bNumEndpoints;
227
0
    ifp->bInterfaceClass = bInterfaceClass;
228
0
    ifp->bInterfaceSubClass = bInterfaceSubClass;
229
0
    ifp->bInterfaceProtocol = bInterfaceProtocol;
230
0
    ifp->iInterface = iInterface;
231
0
    ifp->extra = NULL;
232
0
    ifp->extra_length = 0;
233
0
    ifp->endpoint = NULL;
234
235
0
    usb_interface->altsetting = altsetting;
236
0
    usb_interface->num_altsetting++;
237
238
0
    if (interface_number == -1)
239
0
      interface_number = ifp->bInterfaceNumber;
240
241
    /* Skip over the interface */
242
0
    buffer += ifp->bLength;
243
0
    parsed += ifp->bLength;
244
0
    size -= ifp->bLength;
245
246
0
    begin = buffer;
247
248
    /* Skip over any interface, class or vendor descriptors */
249
0
    while (size >= DESC_HEADER_LENGTH) {
250
0
      header = (const struct usbi_descriptor_header *)buffer;
251
0
      if (header->bLength < DESC_HEADER_LENGTH) {
252
0
        usbi_err(ctx,
253
0
           "invalid extra intf desc len (%u)",
254
0
           header->bLength);
255
0
        r = LIBUSB_ERROR_IO;
256
0
        goto err;
257
0
      } else if (header->bLength > size) {
258
0
        usbi_warn(ctx,
259
0
            "short extra intf desc read %d/%u",
260
0
            size, header->bLength);
261
        /* Keep the invariant: bNumEndpoints > 0 implies
262
         * endpoint != NULL. The endpoint array isn't
263
         * allocated yet on this early return. */
264
0
        ifp->bNumEndpoints = 0;
265
0
        return parsed;
266
0
      }
267
268
      /* If we find another "proper" descriptor then we're done */
269
0
      if (header->bDescriptorType == LIBUSB_DT_INTERFACE ||
270
0
          header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
271
0
          header->bDescriptorType == LIBUSB_DT_CONFIG ||
272
0
          header->bDescriptorType == LIBUSB_DT_DEVICE)
273
0
        break;
274
275
0
      buffer += header->bLength;
276
0
      parsed += header->bLength;
277
0
      size -= header->bLength;
278
0
    }
279
280
    /* Copy any unknown descriptors into a storage area for */
281
    /*  drivers to later parse */
282
0
    ptrdiff_t len = buffer - begin;
283
0
    if (len > 0) {
284
0
      void *extra = malloc((size_t)len);
285
286
0
      if (!extra) {
287
0
        r = LIBUSB_ERROR_NO_MEM;
288
0
        goto err;
289
0
      }
290
291
0
      memcpy(extra, begin, (size_t)len);
292
0
      ifp->extra = (const unsigned char *)extra;
293
0
      ifp->extra_length = (int)len;
294
0
    }
295
296
0
    if (ifp->bNumEndpoints > 0) {
297
0
      struct libusb_endpoint_descriptor *endpoint;
298
0
      uint8_t i;
299
300
0
      endpoint = (struct libusb_endpoint_descriptor *)calloc(ifp->bNumEndpoints, sizeof(*endpoint));
301
0
      if (!endpoint) {
302
0
        r = LIBUSB_ERROR_NO_MEM;
303
0
        goto err;
304
0
      }
305
306
0
      ifp->endpoint = endpoint;
307
0
      for (i = 0; i < ifp->bNumEndpoints; i++) {
308
0
        r = parse_endpoint(ctx, endpoint + i, buffer, size);
309
0
        if (r < 0)
310
0
          goto err;
311
0
        if (r == 0) {
312
0
          ifp->bNumEndpoints = i;
313
0
          break;
314
0
        }
315
316
0
        buffer += r;
317
0
        parsed += r;
318
0
        size -= r;
319
0
      }
320
0
    }
321
322
    /* We check to see if it's an alternate to this one */
323
0
    if_desc = (const struct usbi_interface_descriptor *)buffer;
324
0
    if (size < LIBUSB_DT_INTERFACE_SIZE ||
325
0
        if_desc->bDescriptorType != LIBUSB_DT_INTERFACE ||
326
0
        if_desc->bInterfaceNumber != interface_number)
327
0
      return parsed;
328
0
  }
329
330
0
  return parsed;
331
0
err:
332
0
  clear_interface(usb_interface);
333
0
  return r;
334
0
}
335
336
static void clear_configuration(struct libusb_config_descriptor *config)
337
0
{
338
0
  uint8_t i;
339
340
0
  if (config->interface) {
341
0
    for (i = 0; i < config->bNumInterfaces; i++)
342
0
      clear_interface((struct libusb_interface *)
343
0
          config->interface + i);
344
0
  }
345
0
  free((void *)config->interface);
346
0
  config->interface = NULL;
347
0
  config->bNumInterfaces = 0;
348
0
  free((void *)config->extra);
349
0
  config->extra = NULL;
350
0
  config->extra_length = 0;
351
0
}
352
353
static int parse_configuration(struct libusb_context *ctx,
354
  struct libusb_config_descriptor *config, const uint8_t *buffer, int size)
355
0
{
356
0
  uint8_t i;
357
0
  int r;
358
0
  const struct usbi_descriptor_header *header;
359
0
  struct libusb_interface *usb_interface;
360
361
0
  if (size < LIBUSB_DT_CONFIG_SIZE) {
362
0
    usbi_err(ctx, "short config descriptor read %d/%d",
363
0
       size, LIBUSB_DT_CONFIG_SIZE);
364
0
    return LIBUSB_ERROR_IO;
365
0
  }
366
367
0
  uint8_t bLength = buffer[0];
368
0
  uint8_t bDescriptorType = buffer[1];
369
0
  uint16_t wTotalLength = ReadLittleEndian16(&buffer[2]);
370
0
  uint8_t bNumInterfaces = buffer[4];
371
0
  uint8_t bConfigurationValue = buffer[5];
372
0
  uint8_t iConfiguration = buffer[6];
373
0
  uint8_t bmAttributes = buffer[7];
374
0
  uint8_t MaxPower = buffer[8];
375
376
0
  if (bDescriptorType != LIBUSB_DT_CONFIG) {
377
0
    usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
378
0
       bDescriptorType, LIBUSB_DT_CONFIG);
379
0
    return LIBUSB_ERROR_IO;
380
0
  } else if (bLength < LIBUSB_DT_CONFIG_SIZE) {
381
0
    usbi_err(ctx, "invalid config bLength (%u)", bLength);
382
0
    return LIBUSB_ERROR_IO;
383
0
  } else if (bLength > size) {
384
0
    usbi_err(ctx, "short config descriptor read %d/%u",
385
0
       size, bLength);
386
0
    return LIBUSB_ERROR_IO;
387
0
  } else if (bNumInterfaces > USB_MAXINTERFACES) {
388
0
    usbi_err(ctx, "too many interfaces (%u)", bNumInterfaces);
389
0
    return LIBUSB_ERROR_IO;
390
0
  }
391
392
0
  usb_interface = (struct libusb_interface *)calloc(bNumInterfaces, sizeof(*usb_interface));
393
0
  if (!usb_interface)
394
0
    return LIBUSB_ERROR_NO_MEM;
395
396
0
  buffer += bLength;
397
0
  size -= bLength;
398
399
0
  for (i = 0; i < bNumInterfaces; i++) {
400
0
    const uint8_t *begin;
401
402
    /* Skip over the rest of the Class Specific or Vendor */
403
    /*  Specific descriptors */
404
0
    begin = buffer;
405
0
    while (size >= DESC_HEADER_LENGTH) {
406
0
      header = (const struct usbi_descriptor_header *)buffer;
407
0
      if (header->bLength < DESC_HEADER_LENGTH) {
408
0
        usbi_err(ctx,
409
0
           "invalid extra config desc len (%u)",
410
0
           header->bLength);
411
0
        r = LIBUSB_ERROR_IO;
412
0
        goto err;
413
0
      } else if (header->bLength > size) {
414
0
        usbi_warn(ctx,
415
0
            "short extra config desc read %d/%u",
416
0
            size, header->bLength);
417
0
        bNumInterfaces = i;
418
0
        goto finish;
419
0
      }
420
421
      /* If we find another "proper" descriptor then we're done */
422
0
      if (header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
423
0
          header->bDescriptorType == LIBUSB_DT_INTERFACE ||
424
0
          header->bDescriptorType == LIBUSB_DT_CONFIG ||
425
0
          header->bDescriptorType == LIBUSB_DT_DEVICE)
426
0
        break;
427
428
0
      usbi_dbg(ctx, "skipping descriptor 0x%x", header->bDescriptorType);
429
0
      buffer += header->bLength;
430
0
      size -= header->bLength;
431
0
    }
432
433
    /* Copy any unknown descriptors into a storage area for */
434
    /*  drivers to later parse */
435
0
    ptrdiff_t len = buffer - begin;
436
0
    if (len > 0) {
437
0
      size_t new_extra_len = (size_t)(config->extra_length) + (size_t)len;
438
0
      uint8_t *new_extra = (uint8_t *)realloc((void *)config->extra, new_extra_len);
439
440
0
      if (!new_extra) {
441
0
        r = LIBUSB_ERROR_NO_MEM;
442
0
        goto err;
443
0
      }
444
445
0
      memcpy(new_extra + config->extra_length, begin, (size_t)len);
446
0
      config->extra = new_extra;
447
0
      config->extra_length = (int)new_extra_len;
448
0
    }
449
450
0
    r = parse_interface(ctx, usb_interface + i, buffer, size);
451
0
    if (r < 0)
452
0
      goto err;
453
0
    if (r == 0) {
454
0
      bNumInterfaces = i;
455
0
      break;
456
0
    }
457
458
0
    buffer += r;
459
0
    size -= r;
460
0
  }
461
462
0
finish:
463
0
  config->interface = usb_interface;
464
0
  config->bNumInterfaces = bNumInterfaces;
465
0
  config->bLength = bLength;
466
0
  config->bDescriptorType = bDescriptorType;
467
0
  config->wTotalLength = wTotalLength;
468
0
  config->bConfigurationValue = bConfigurationValue;
469
0
  config->iConfiguration = iConfiguration;
470
0
  config->bmAttributes = bmAttributes;
471
0
  config->MaxPower = MaxPower;
472
473
0
  return size;
474
475
0
err:
476
  /* Even though we've failed, set these 2 fields so clear_configuration() can dealloc memory. */
477
0
  config->interface = usb_interface;
478
0
  config->bNumInterfaces = bNumInterfaces;
479
480
0
  clear_configuration(config);
481
0
  return r;
482
0
}
483
484
static int raw_desc_to_config(struct libusb_context *ctx,
485
  const uint8_t *buf, int size, struct libusb_config_descriptor **config)
486
0
{
487
0
  struct libusb_config_descriptor *_config = (struct libusb_config_descriptor *)calloc(1, sizeof(*_config));
488
0
  int r;
489
490
0
  if (!_config)
491
0
    return LIBUSB_ERROR_NO_MEM;
492
493
0
  r = parse_configuration(ctx, _config, buf, size);
494
0
  if (r < 0) {
495
0
    usbi_err(ctx, "parse_configuration failed with error %d", r);
496
0
    free(_config);
497
0
    return r;
498
0
  } else if (r > 0) {
499
0
    usbi_warn(ctx, "still %d bytes of descriptor data left", r);
500
0
  }
501
502
0
  *config = _config;
503
0
  return LIBUSB_SUCCESS;
504
0
}
505
506
static int get_active_config_descriptor(struct libusb_device *dev,
507
  uint8_t *buffer, size_t size)
508
0
{
509
0
  int r = usbi_backend.get_active_config_descriptor(dev, buffer, size);
510
511
0
  if (r < 0)
512
0
    return r;
513
514
0
  if (r < LIBUSB_DT_CONFIG_SIZE) {
515
0
    usbi_err(usbi_device_ctx(dev), "short config descriptor read %d/%d",
516
0
       r, LIBUSB_DT_CONFIG_SIZE);
517
0
    return LIBUSB_ERROR_IO;
518
0
  } else if (r != (int)size) {
519
0
    usbi_warn(usbi_device_ctx(dev), "short config descriptor read %d/%d",
520
0
       r, (int)size);
521
0
  }
522
523
0
  return r;
524
0
}
525
526
static int get_config_descriptor(struct libusb_device *dev, uint8_t config_idx,
527
  uint8_t *buffer, size_t size)
528
0
{
529
0
  int r = usbi_backend.get_config_descriptor(dev, config_idx, buffer, size);
530
531
0
  if (r < 0)
532
0
    return r;
533
0
  if (r < LIBUSB_DT_CONFIG_SIZE) {
534
0
    usbi_err(usbi_device_ctx(dev), "short config descriptor read %d/%d",
535
0
       r, LIBUSB_DT_CONFIG_SIZE);
536
0
    return LIBUSB_ERROR_IO;
537
0
  } else if (r != (int)size) {
538
0
    usbi_warn(usbi_device_ctx(dev), "short config descriptor read %d/%d",
539
0
       r, (int)size);
540
0
  }
541
542
0
  return r;
543
0
}
544
545
/** \ingroup libusb_desc
546
 * Get the USB device descriptor for a given device.
547
 *
548
 * This is a non-blocking function; the device descriptor is cached in memory.
549
 *
550
 * Note since libusb-1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102, this
551
 * function always succeeds.
552
 *
553
 * \param dev the device
554
 * \param desc output location for the descriptor data
555
 * \returns 0 on success or a LIBUSB_ERROR code on failure
556
 */
557
int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
558
  struct libusb_device_descriptor *desc)
559
0
{
560
0
  usbi_dbg(usbi_device_ctx(dev), " ");
561
0
  static_assert(sizeof(dev->device_descriptor) == LIBUSB_DT_DEVICE_SIZE,
562
0
          "struct libusb_device_descriptor is not expected size");
563
0
  *desc = dev->device_descriptor;
564
0
  return 0;
565
0
}
566
567
/** \ingroup libusb_desc
568
 * Get the USB configuration descriptor for the currently active configuration.
569
 * This is a non-blocking function which does not involve any requests being
570
 * sent to the device.
571
 *
572
 * \param dev a device
573
 * \param config output location for the USB configuration descriptor. Only
574
 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
575
 * after use.
576
 * \returns 0 on success
577
 * \returns \ref LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
578
 * \returns another LIBUSB_ERROR code on error
579
 * \see libusb_get_config_descriptor
580
 */
581
int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
582
  struct libusb_config_descriptor **config)
583
0
{
584
0
  union usbi_config_desc_buf _config;
585
0
  uint16_t config_len;
586
0
  uint8_t *buf;
587
0
  int r;
588
589
0
  r = get_active_config_descriptor(dev, _config.buf, sizeof(_config.buf));
590
0
  if (r < 0)
591
0
    return r;
592
593
0
  config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
594
0
  buf = (uint8_t *)malloc(config_len);
595
0
  if (!buf)
596
0
    return LIBUSB_ERROR_NO_MEM;
597
598
0
  r = get_active_config_descriptor(dev, buf, config_len);
599
0
  if (r >= 0)
600
0
    r = raw_desc_to_config(usbi_device_ctx(dev), buf, r, config);
601
602
0
  free(buf);
603
0
  return r;
604
0
}
605
606
/** \ingroup libusb_desc
607
 * Get a USB configuration descriptor based on its index.
608
 * This is a non-blocking function which does not involve any requests being
609
 * sent to the device.
610
 *
611
 * \param dev a device
612
 * \param config_index the index of the configuration you wish to retrieve
613
 * \param config output location for the USB configuration descriptor. Only
614
 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
615
 * after use.
616
 * \returns 0 on success
617
 * \returns \ref LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
618
 * \returns another LIBUSB_ERROR code on error
619
 * \see libusb_get_active_config_descriptor()
620
 * \see libusb_get_config_descriptor_by_value()
621
 */
622
int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
623
  uint8_t config_index, struct libusb_config_descriptor **config)
624
0
{
625
0
  union usbi_config_desc_buf _config;
626
0
  uint16_t config_len;
627
0
  uint8_t *buf;
628
0
  int r;
629
630
0
  usbi_dbg(usbi_device_ctx(dev), "index %u", config_index);
631
0
  if (config_index >= dev->device_descriptor.bNumConfigurations)
632
0
    return LIBUSB_ERROR_NOT_FOUND;
633
634
0
  r = get_config_descriptor(dev, config_index, _config.buf, sizeof(_config.buf));
635
0
  if (r < 0)
636
0
    return r;
637
638
0
  config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
639
0
  buf = (uint8_t *)malloc(config_len);
640
0
  if (!buf)
641
0
    return LIBUSB_ERROR_NO_MEM;
642
643
0
  r = get_config_descriptor(dev, config_index, buf, config_len);
644
0
  if (r >= 0)
645
0
    r = raw_desc_to_config(usbi_device_ctx(dev), buf, r, config);
646
647
0
  free(buf);
648
0
  return r;
649
0
}
650
651
/** \ingroup libusb_desc
652
 * Get a USB configuration descriptor with a specific bConfigurationValue.
653
 * This is a non-blocking function which does not involve any requests being
654
 * sent to the device.
655
 *
656
 * \param dev a device
657
 * \param bConfigurationValue the bConfigurationValue of the configuration you
658
 * wish to retrieve
659
 * \param config output location for the USB configuration descriptor. Only
660
 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
661
 * after use.
662
 * \returns 0 on success
663
 * \returns \ref LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
664
 * \returns another LIBUSB_ERROR code on error
665
 * \see libusb_get_active_config_descriptor()
666
 * \see libusb_get_config_descriptor()
667
 */
668
int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
669
  uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
670
0
{
671
0
  uint8_t idx;
672
0
  int r;
673
674
0
  if (usbi_backend.get_config_descriptor_by_value) {
675
0
    void *buf;
676
677
0
    r = usbi_backend.get_config_descriptor_by_value(dev,
678
0
      bConfigurationValue, &buf);
679
0
    if (r < 0)
680
0
      return r;
681
682
0
    return raw_desc_to_config(usbi_device_ctx(dev), (uint8_t *)buf, r, config);
683
0
  }
684
685
0
  usbi_dbg(usbi_device_ctx(dev), "value %u", bConfigurationValue);
686
0
  for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
687
0
    union usbi_config_desc_buf _config;
688
689
0
    r = get_config_descriptor(dev, idx, _config.buf, sizeof(_config.buf));
690
0
    if (r < 0)
691
0
      return r;
692
693
0
    if (_config.desc.bConfigurationValue == bConfigurationValue)
694
0
      return libusb_get_config_descriptor(dev, idx, config);
695
0
  }
696
697
0
  return LIBUSB_ERROR_NOT_FOUND;
698
0
}
699
700
/** \ingroup libusb_desc
701
 * Free a configuration descriptor obtained from
702
 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
703
 * It is safe to call this function with a NULL config parameter, in which
704
 * case the function simply returns.
705
 *
706
 * \param config the configuration descriptor to free
707
 */
708
void API_EXPORTED libusb_free_config_descriptor(
709
  struct libusb_config_descriptor *config)
710
0
{
711
0
  if (!config)
712
0
    return;
713
714
0
  clear_configuration(config);
715
0
  free(config);
716
0
}
717
718
/** \ingroup libusb_desc
719
 * Get an endpoints superspeed endpoint companion descriptor (if any)
720
 *
721
 * \param ctx the context to operate on, or NULL for the default context
722
 * \param endpoint endpoint descriptor from which to get the superspeed
723
 * endpoint companion descriptor
724
 * \param ep_comp output location for the superspeed endpoint companion
725
 * descriptor. Only valid if 0 was returned. Must be freed with
726
 * libusb_free_ss_endpoint_companion_descriptor() after use.
727
 * \returns 0 on success
728
 * \returns \ref LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
729
 * \returns another LIBUSB_ERROR code on error
730
 */
731
int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
732
  libusb_context *ctx,
733
  const struct libusb_endpoint_descriptor *endpoint,
734
  struct libusb_ss_endpoint_companion_descriptor **ep_comp)
735
0
{
736
0
  const struct usbi_descriptor_header *header;
737
0
  const uint8_t *buffer = endpoint->extra;
738
0
  int size = endpoint->extra_length;
739
740
0
  *ep_comp = NULL;
741
742
0
  while (size >= DESC_HEADER_LENGTH) {
743
0
    header = (const struct usbi_descriptor_header *)buffer;
744
0
    if (header->bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
745
0
      if (header->bLength < DESC_HEADER_LENGTH) {
746
0
        usbi_err(ctx, "invalid descriptor length %u",
747
0
           header->bLength);
748
0
        return LIBUSB_ERROR_IO;
749
0
      }
750
0
      buffer += header->bLength;
751
0
      size -= header->bLength;
752
0
      continue;
753
0
    } else if (header->bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) {
754
0
      usbi_err(ctx, "invalid ss-ep-comp-desc length %u",
755
0
         header->bLength);
756
0
      return LIBUSB_ERROR_IO;
757
0
    } else if (header->bLength > size) {
758
0
      usbi_err(ctx, "short ss-ep-comp-desc read %d/%u",
759
0
         size, header->bLength);
760
0
      return LIBUSB_ERROR_IO;
761
0
    }
762
763
0
    *ep_comp = (struct libusb_ss_endpoint_companion_descriptor *)malloc(sizeof(**ep_comp));
764
0
    if (!*ep_comp)
765
0
      return LIBUSB_ERROR_NO_MEM;
766
0
    (*ep_comp)->bLength = buffer[0];
767
0
    (*ep_comp)->bDescriptorType = buffer[1];
768
0
    (*ep_comp)->bMaxBurst = buffer[2];
769
0
    (*ep_comp)->bmAttributes = buffer[3];
770
0
    (*ep_comp)->wBytesPerInterval = ReadLittleEndian16(&buffer[4]);
771
0
    return LIBUSB_SUCCESS;
772
0
  }
773
0
  return LIBUSB_ERROR_NOT_FOUND;
774
0
}
775
776
/** \ingroup libusb_desc
777
 * Free a superspeed endpoint companion descriptor obtained from
778
 * libusb_get_ss_endpoint_companion_descriptor().
779
 * It is safe to call this function with a NULL ep_comp parameter, in which
780
 * case the function simply returns.
781
 *
782
 * \param ep_comp the superspeed endpoint companion descriptor to free
783
 */
784
void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor(
785
  struct libusb_ss_endpoint_companion_descriptor *ep_comp)
786
0
{
787
0
  free(ep_comp);
788
0
}
789
790
static int parse_bos(struct libusb_context *ctx,
791
  struct libusb_bos_descriptor **bos,
792
  const uint8_t *buffer, int size)
793
0
{
794
0
  struct libusb_bos_descriptor *_bos;
795
0
  const struct usbi_bos_descriptor *bos_desc;
796
0
  const struct usbi_descriptor_header *header;
797
0
  uint8_t i;
798
799
0
  if (size < LIBUSB_DT_BOS_SIZE) {
800
0
    usbi_err(ctx, "short bos descriptor read %d/%d",
801
0
       size, LIBUSB_DT_BOS_SIZE);
802
0
    return LIBUSB_ERROR_IO;
803
0
  }
804
805
0
  bos_desc = (const struct usbi_bos_descriptor *)buffer;
806
0
  if (bos_desc->bDescriptorType != LIBUSB_DT_BOS) {
807
0
    usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
808
0
       bos_desc->bDescriptorType, LIBUSB_DT_BOS);
809
0
    return LIBUSB_ERROR_IO;
810
0
  } else if (bos_desc->bLength < LIBUSB_DT_BOS_SIZE) {
811
0
    usbi_err(ctx, "invalid bos bLength (%u)", bos_desc->bLength);
812
0
    return LIBUSB_ERROR_IO;
813
0
  } else if (bos_desc->bLength > size) {
814
0
    usbi_err(ctx, "short bos descriptor read %d/%u",
815
0
       size, bos_desc->bLength);
816
0
    return LIBUSB_ERROR_IO;
817
0
  }
818
819
0
  _bos = (struct libusb_bos_descriptor *)calloc(1, sizeof(*_bos) + (bos_desc->bNumDeviceCaps * sizeof(void *)));
820
0
  if (!_bos)
821
0
    return LIBUSB_ERROR_NO_MEM;
822
823
0
  _bos->bLength = buffer[0];
824
0
  _bos->bDescriptorType = buffer[1];
825
0
  _bos->wTotalLength = ReadLittleEndian16(&buffer[2]);
826
0
  _bos->bNumDeviceCaps = buffer[4];
827
0
  buffer += _bos->bLength;
828
0
  size -= _bos->bLength;
829
830
  /* Get the device capability descriptors */
831
0
  for (i = 0; i < _bos->bNumDeviceCaps; i++) {
832
0
    if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
833
0
      usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
834
0
          size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
835
0
      break;
836
0
    }
837
0
    header = (const struct usbi_descriptor_header *)buffer;
838
0
    if (header->bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
839
0
      usbi_warn(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
840
0
          header->bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY);
841
0
      break;
842
0
    } else if (header->bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
843
0
      usbi_err(ctx, "invalid dev-cap bLength (%u)",
844
0
         header->bLength);
845
0
      libusb_free_bos_descriptor(_bos);
846
0
      return LIBUSB_ERROR_IO;
847
0
    } else if (header->bLength > size) {
848
0
      usbi_warn(ctx, "short dev-cap descriptor read %d/%u",
849
0
          size, header->bLength);
850
0
      break;
851
0
    }
852
853
0
    _bos->dev_capability[i] = (struct libusb_bos_dev_capability_descriptor *)malloc(header->bLength);
854
0
    if (!_bos->dev_capability[i]) {
855
0
      libusb_free_bos_descriptor(_bos);
856
0
      return LIBUSB_ERROR_NO_MEM;
857
0
    }
858
0
    memcpy(_bos->dev_capability[i], buffer, header->bLength);
859
0
    buffer += header->bLength;
860
0
    size -= header->bLength;
861
0
  }
862
0
  _bos->bNumDeviceCaps = i;
863
0
  *bos = _bos;
864
865
0
  return LIBUSB_SUCCESS;
866
0
}
867
868
/** \ingroup libusb_desc
869
 * Get a Binary Object Store (BOS) descriptor
870
 * This is a BLOCKING function, which will send requests to the device.
871
 *
872
 * \param dev_handle the handle of an open libusb device
873
 * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
874
 * Must be freed with \ref libusb_free_bos_descriptor() after use.
875
 * \returns 0 on success
876
 * \returns \ref LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
877
 * \returns another LIBUSB_ERROR code on error
878
 */
879
int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *dev_handle,
880
  struct libusb_bos_descriptor **bos)
881
0
{
882
0
  union usbi_bos_desc_buf _bos;
883
0
  uint16_t bos_len;
884
0
  uint8_t *bos_data;
885
0
  int r;
886
0
  struct libusb_context *ctx = usbi_handle_ctx(dev_handle);
887
888
  /* Read the BOS. This generates 2 requests on the bus,
889
   * one for the header, and one for the full BOS */
890
0
  r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, _bos.buf, sizeof(_bos.buf));
891
0
  if (r < 0) {
892
0
    if (r != LIBUSB_ERROR_PIPE)
893
0
      usbi_err(ctx, "failed to read BOS (%d)", r);
894
0
    return r;
895
0
  }
896
0
  if (r < LIBUSB_DT_BOS_SIZE) {
897
0
    usbi_err(ctx, "short BOS read %d/%d",
898
0
       r, LIBUSB_DT_BOS_SIZE);
899
0
    return LIBUSB_ERROR_IO;
900
0
  }
901
902
0
  bos_len = libusb_le16_to_cpu(_bos.desc.wTotalLength);
903
0
  usbi_dbg(ctx, "found BOS descriptor: size %u bytes, %u capabilities",
904
0
     bos_len, _bos.desc.bNumDeviceCaps);
905
0
  bos_data = (uint8_t *)calloc(1, bos_len);
906
0
  if (!bos_data)
907
0
    return LIBUSB_ERROR_NO_MEM;
908
909
0
  r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_data, bos_len);
910
0
  if (r >= 0) {
911
0
    if (r != (int)bos_len)
912
0
      usbi_warn(ctx, "short BOS read %d/%u", r, bos_len);
913
0
    r = parse_bos(usbi_handle_ctx(dev_handle), bos, bos_data, r);
914
0
  } else {
915
0
    usbi_err(ctx, "failed to read BOS (%d)", r);
916
0
  }
917
918
0
  free(bos_data);
919
0
  return r;
920
0
}
921
922
/** \ingroup libusb_desc
923
 * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
924
 * It is safe to call this function with a NULL bos parameter, in which
925
 * case the function simply returns.
926
 *
927
 * \param bos the BOS descriptor to free
928
 */
929
void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
930
0
{
931
0
  uint8_t i;
932
933
0
  if (!bos)
934
0
    return;
935
936
0
  for (i = 0; i < bos->bNumDeviceCaps; i++)
937
0
    free(bos->dev_capability[i]);
938
0
  free(bos);
939
0
}
940
941
/** \ingroup libusb_desc
942
 * Get an USB 2.0 Extension descriptor
943
 *
944
 * \param ctx the context to operate on, or NULL for the default context
945
 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
946
 * \ref libusb_bos_type::LIBUSB_BT_USB_2_0_EXTENSION
947
 * LIBUSB_BT_USB_2_0_EXTENSION
948
 * \param usb_2_0_extension output location for the USB 2.0 Extension
949
 * descriptor. Only valid if 0 was returned. Must be freed with
950
 * libusb_free_usb_2_0_extension_descriptor() after use.
951
 * \returns 0 on success
952
 * \returns a LIBUSB_ERROR code on error
953
 */
954
int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
955
  libusb_context *ctx,
956
  struct libusb_bos_dev_capability_descriptor *dev_cap,
957
  struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
958
0
{
959
0
  struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension;
960
961
0
  if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) {
962
0
    usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
963
0
       dev_cap->bDevCapabilityType,
964
0
       LIBUSB_BT_USB_2_0_EXTENSION);
965
0
    return LIBUSB_ERROR_INVALID_PARAM;
966
0
  } else if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) {
967
0
    usbi_err(ctx, "short dev-cap descriptor read %u/%d",
968
0
       dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE);
969
0
    return LIBUSB_ERROR_IO;
970
0
  }
971
972
0
  _usb_2_0_extension = (struct libusb_usb_2_0_extension_descriptor *)malloc(sizeof(*_usb_2_0_extension));
973
0
  if (!_usb_2_0_extension)
974
0
    return LIBUSB_ERROR_NO_MEM;
975
976
0
  _usb_2_0_extension->bLength = dev_cap->bLength;
977
0
  _usb_2_0_extension->bDescriptorType = dev_cap->bDescriptorType;
978
0
  _usb_2_0_extension->bDevCapabilityType = dev_cap->bDevCapabilityType;
979
0
  _usb_2_0_extension->bmAttributes = ReadLittleEndian32(dev_cap->dev_capability_data);
980
981
0
  *usb_2_0_extension = _usb_2_0_extension;
982
0
  return LIBUSB_SUCCESS;
983
0
}
984
985
/** \ingroup libusb_desc
986
 * Free a USB 2.0 Extension descriptor obtained from
987
 * libusb_get_usb_2_0_extension_descriptor().
988
 * It is safe to call this function with a NULL usb_2_0_extension parameter,
989
 * in which case the function simply returns.
990
 *
991
 * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
992
 */
993
void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
994
  struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
995
0
{
996
0
  free(usb_2_0_extension);
997
0
}
998
999
/** \ingroup libusb_desc
1000
 * Get a SuperSpeed USB Device Capability descriptor
1001
 *
1002
 * \param ctx the context to operate on, or NULL for the default context
1003
 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1004
 * \ref libusb_bos_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1005
 * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1006
 * \param ss_usb_device_cap output location for the SuperSpeed USB Device
1007
 * Capability descriptor. Only valid if 0 was returned. Must be freed with
1008
 * libusb_free_ss_usb_device_capability_descriptor() after use.
1009
 * \returns 0 on success
1010
 * \returns a LIBUSB_ERROR code on error
1011
 */
1012
int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
1013
  libusb_context *ctx,
1014
  struct libusb_bos_dev_capability_descriptor *dev_cap,
1015
  struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
1016
0
{
1017
0
  struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap;
1018
1019
0
  if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
1020
0
    usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
1021
0
       dev_cap->bDevCapabilityType,
1022
0
       LIBUSB_BT_SS_USB_DEVICE_CAPABILITY);
1023
0
    return LIBUSB_ERROR_INVALID_PARAM;
1024
0
  } else if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) {
1025
0
    usbi_err(ctx, "short dev-cap descriptor read %u/%d",
1026
0
       dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE);
1027
0
    return LIBUSB_ERROR_IO;
1028
0
  }
1029
1030
0
  _ss_usb_device_cap = (struct libusb_ss_usb_device_capability_descriptor *)malloc(sizeof(*_ss_usb_device_cap));
1031
0
  if (!_ss_usb_device_cap)
1032
0
    return LIBUSB_ERROR_NO_MEM;
1033
1034
0
  _ss_usb_device_cap->bLength = dev_cap->bLength;
1035
0
  _ss_usb_device_cap->bDescriptorType = dev_cap->bDescriptorType;
1036
0
  _ss_usb_device_cap->bDevCapabilityType = dev_cap->bDevCapabilityType;
1037
0
  _ss_usb_device_cap->bmAttributes = dev_cap->dev_capability_data[0];
1038
0
  _ss_usb_device_cap->wSpeedSupported = ReadLittleEndian16(&dev_cap->dev_capability_data[1]);
1039
0
  _ss_usb_device_cap->bFunctionalitySupport = dev_cap->dev_capability_data[3];
1040
0
  _ss_usb_device_cap->bU1DevExitLat = dev_cap->dev_capability_data[4];
1041
0
  _ss_usb_device_cap->bU2DevExitLat = ReadLittleEndian16(&dev_cap->dev_capability_data[5]);
1042
1043
0
  *ss_usb_device_cap = _ss_usb_device_cap;
1044
0
  return LIBUSB_SUCCESS;
1045
0
}
1046
1047
/// @cond DEV
1048
/** \internal \ingroup libusb_desc
1049
 * We use this private struct only to parse a SuperSpeedPlus device capability
1050
 * descriptor according to section 9.6.2.5 of the USB 3.1 specification.
1051
 * We don't expose it.
1052
 */
1053
struct internal_ssplus_capability_descriptor {
1054
  /** The length of the descriptor. Must be equal to LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE */
1055
  uint8_t  bLength;
1056
1057
  /** The type of the descriptor */
1058
  uint8_t  bDescriptorType;
1059
1060
  /** Must be equal to LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY */
1061
  uint8_t  bDevCapabilityType;
1062
1063
  /** Unused */
1064
  uint8_t  bReserved;
1065
1066
  /** Contains the number of SublinkSpeedIDs */
1067
  uint32_t bmAttributes;
1068
1069
  /** Contains the ssid, minRxLaneCount, and minTxLaneCount */
1070
  uint16_t wFunctionalitySupport;
1071
1072
  /** Unused */
1073
  uint16_t wReserved;
1074
};
1075
/// @endcond
1076
1077
/** \ingroup libusb_desc
1078
 * Get a SuperSpeedPlus USB Device Capability descriptor
1079
 *
1080
 * Since version 1.0.28, \ref LIBUSB_API_VERSION >= 0x0100010B
1081
 *
1082
 * \param ctx the context to operate on, or NULL for the default context
1083
 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1084
 * \ref libusb_bos_type::LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY
1085
 * LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY
1086
 * \param ssplus_usb_device_cap output location for the SuperSpeedPlus USB Device
1087
 * Capability descriptor. Only valid if 0 was returned. Must be freed with
1088
 * libusb_free_ssplus_usb_device_capability_descriptor() after use.
1089
 * \returns 0 on success
1090
 * \returns a LIBUSB_ERROR code on error
1091
 */
1092
int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
1093
  libusb_context *ctx,
1094
  struct libusb_bos_dev_capability_descriptor *dev_cap,
1095
  struct libusb_ssplus_usb_device_capability_descriptor **ssplus_usb_device_cap)
1096
0
{
1097
0
  struct libusb_ssplus_usb_device_capability_descriptor *_ssplus_cap;
1098
1099
  /* Use a private struct to reuse our descriptor parsing system. */
1100
0
  struct internal_ssplus_capability_descriptor parsedDescriptor;
1101
1102
  /* Some size/type checks to make sure everything is in order */
1103
0
  if (dev_cap->bDevCapabilityType != LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY) {
1104
0
    usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
1105
0
       dev_cap->bDevCapabilityType,
1106
0
         LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY);
1107
0
    return LIBUSB_ERROR_INVALID_PARAM;
1108
0
  } else if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE) {
1109
0
    usbi_err(ctx, "short dev-cap descriptor read %u/%d",
1110
0
       dev_cap->bLength, LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE);
1111
0
    return LIBUSB_ERROR_IO;
1112
0
  }
1113
1114
0
  const uint8_t* dev_capability_data = dev_cap->dev_capability_data;
1115
0
  parsedDescriptor.bLength = dev_cap->bLength;
1116
0
  parsedDescriptor.bDescriptorType = dev_cap->bDescriptorType;
1117
0
  parsedDescriptor.bDevCapabilityType = dev_cap->bDevCapabilityType;
1118
0
  parsedDescriptor.bReserved = dev_capability_data[0];
1119
0
  parsedDescriptor.bmAttributes = ReadLittleEndian32(&dev_capability_data[1]);
1120
0
  parsedDescriptor.wFunctionalitySupport = ReadLittleEndian16(&dev_capability_data[5]);
1121
0
  parsedDescriptor.wReserved = ReadLittleEndian16(&dev_capability_data[7]);
1122
1123
0
  uint8_t numSublikSpeedAttributes = (parsedDescriptor.bmAttributes & 0xF) + 1;
1124
0
  _ssplus_cap = (struct libusb_ssplus_usb_device_capability_descriptor *)malloc(sizeof(struct libusb_ssplus_usb_device_capability_descriptor) + (numSublikSpeedAttributes * sizeof(struct libusb_ssplus_sublink_attribute)));
1125
0
  if (!_ssplus_cap)
1126
0
    return LIBUSB_ERROR_NO_MEM;
1127
1128
  /* Parse bmAttributes */
1129
0
  _ssplus_cap->numSublinkSpeedAttributes = numSublikSpeedAttributes;
1130
0
  _ssplus_cap->numSublinkSpeedIDs = ((parsedDescriptor.bmAttributes & 0xF0) >> 4) + 1;
1131
1132
  /* Parse wFunctionalitySupport */
1133
0
  _ssplus_cap->ssid = parsedDescriptor.wFunctionalitySupport & 0xF;
1134
0
  _ssplus_cap->minRxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0x0F00) >> 8;
1135
0
  _ssplus_cap->minTxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0xF000) >> 12;
1136
1137
  /* Check that we have enough to read all the sublink attributes */
1138
0
  if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE + (_ssplus_cap->numSublinkSpeedAttributes * sizeof(uint32_t))) {
1139
0
    free(_ssplus_cap);
1140
0
    usbi_err(ctx, "short ssplus capability descriptor, unable to read sublinks: Not enough data");
1141
0
    return LIBUSB_ERROR_IO;
1142
0
  }
1143
1144
  /* Read the attributes */
1145
0
  uint8_t* base = ((uint8_t*)dev_cap) + LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE;
1146
0
  for(uint8_t i = 0 ; i < _ssplus_cap->numSublinkSpeedAttributes ; i++) {
1147
0
    uint32_t attr = ReadLittleEndian32(base + (i * sizeof(uint32_t)));
1148
0
    _ssplus_cap->sublinkSpeedAttributes[i].ssid = attr & 0x0f;
1149
0
    _ssplus_cap->sublinkSpeedAttributes[i].mantissa = attr >> 16;
1150
0
    _ssplus_cap->sublinkSpeedAttributes[i].exponent = (enum libusb_superspeedplus_sublink_attribute_exponent)((attr >> 4) & 0x3);
1151
0
    _ssplus_cap->sublinkSpeedAttributes[i].type = attr & 0x40 ?  LIBUSB_SSPLUS_ATTR_TYPE_ASYM : LIBUSB_SSPLUS_ATTR_TYPE_SYM;
1152
0
    _ssplus_cap->sublinkSpeedAttributes[i].direction = attr & 0x80 ?  LIBUSB_SSPLUS_ATTR_DIR_TX :  LIBUSB_SSPLUS_ATTR_DIR_RX;
1153
0
    _ssplus_cap->sublinkSpeedAttributes[i].protocol = attr & 0x4000 ? LIBUSB_SSPLUS_ATTR_PROT_SSPLUS: LIBUSB_SSPLUS_ATTR_PROT_SS;
1154
0
  }
1155
1156
0
  *ssplus_usb_device_cap = _ssplus_cap;
1157
0
  return LIBUSB_SUCCESS;
1158
0
}
1159
1160
/** \ingroup libusb_desc
1161
 * Free a SuperSpeedPlus USB Device Capability descriptor obtained from
1162
 * libusb_get_ssplus_usb_device_capability_descriptor().
1163
 * It is safe to call this function with a NULL ssplus_usb_device_cap
1164
 * parameter, in which case the function simply returns.
1165
 *
1166
 * Since version 1.0.28, \ref LIBUSB_API_VERSION >= 0x0100010B
1167
 *
1168
 * \param ssplus_usb_device_cap the SuperSpeedPlus USB Device Capability descriptor
1169
 * to free
1170
 */
1171
void API_EXPORTED libusb_free_ssplus_usb_device_capability_descriptor(
1172
  struct libusb_ssplus_usb_device_capability_descriptor *ssplus_usb_device_cap)
1173
0
{
1174
0
  free(ssplus_usb_device_cap);
1175
0
}
1176
1177
1178
1179
/** \ingroup libusb_desc
1180
 * Free a SuperSpeed USB Device Capability descriptor obtained from
1181
 * libusb_get_ss_usb_device_capability_descriptor().
1182
 * It is safe to call this function with a NULL ss_usb_device_cap
1183
 * parameter, in which case the function simply returns.
1184
 *
1185
 * \param ss_usb_device_cap the SuperSpeed USB Device Capability descriptor
1186
 * to free
1187
 */
1188
void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
1189
  struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
1190
0
{
1191
0
  free(ss_usb_device_cap);
1192
0
}
1193
1194
/** \ingroup libusb_desc
1195
 * Get a Container ID descriptor
1196
 *
1197
 * \param ctx the context to operate on, or NULL for the default context
1198
 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1199
 * \ref libusb_bos_type::LIBUSB_BT_CONTAINER_ID
1200
 * LIBUSB_BT_CONTAINER_ID
1201
 * \param container_id output location for the Container ID descriptor.
1202
 * Only valid if 0 was returned. Must be freed with
1203
 * libusb_free_container_id_descriptor() after use.
1204
 * \returns 0 on success
1205
 * \returns a LIBUSB_ERROR code on error
1206
 */
1207
int API_EXPORTED libusb_get_container_id_descriptor(libusb_context *ctx,
1208
  struct libusb_bos_dev_capability_descriptor *dev_cap,
1209
  struct libusb_container_id_descriptor **container_id)
1210
0
{
1211
0
  struct libusb_container_id_descriptor *_container_id;
1212
1213
0
  if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) {
1214
0
    usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
1215
0
       dev_cap->bDevCapabilityType,
1216
0
       LIBUSB_BT_CONTAINER_ID);
1217
0
    return LIBUSB_ERROR_INVALID_PARAM;
1218
0
  } else if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) {
1219
0
    usbi_err(ctx, "short dev-cap descriptor read %u/%d",
1220
0
       dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE);
1221
0
    return LIBUSB_ERROR_IO;
1222
0
  }
1223
1224
0
  _container_id = (struct libusb_container_id_descriptor *)malloc(sizeof(*_container_id));
1225
0
  if (!_container_id)
1226
0
    return LIBUSB_ERROR_NO_MEM;
1227
1228
0
  _container_id->bLength = dev_cap->bLength;
1229
0
  _container_id->bDescriptorType = dev_cap->bDescriptorType;
1230
0
  _container_id->bDevCapabilityType = dev_cap->bDevCapabilityType;
1231
0
  _container_id->bReserved = dev_cap->dev_capability_data[0];
1232
0
  memcpy(_container_id->ContainerID, &dev_cap->dev_capability_data[1], 16);
1233
1234
0
  *container_id = _container_id;
1235
0
  return LIBUSB_SUCCESS;
1236
0
}
1237
1238
/** \ingroup libusb_desc
1239
 * Free a Container ID descriptor obtained from
1240
 * libusb_get_container_id_descriptor().
1241
 * It is safe to call this function with a NULL container_id parameter,
1242
 * in which case the function simply returns.
1243
 *
1244
 * \param container_id the Container ID descriptor to free
1245
 */
1246
void API_EXPORTED libusb_free_container_id_descriptor(
1247
  struct libusb_container_id_descriptor *container_id)
1248
0
{
1249
0
  free(container_id);
1250
0
}
1251
1252
/** \ingroup libusb_desc
1253
 * Get a platform descriptor
1254
 *
1255
 * Since version 1.0.27, \ref LIBUSB_API_VERSION >= 0x0100010A
1256
 *
1257
 * \param ctx the context to operate on, or NULL for the default context
1258
 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1259
 * \ref libusb_bos_type::LIBUSB_BT_PLATFORM_DESCRIPTOR
1260
 * LIBUSB_BT_PLATFORM_DESCRIPTOR
1261
 * \param platform_descriptor output location for the Platform descriptor.
1262
 * Only valid if 0 was returned. Must be freed with
1263
 * libusb_free_platform_descriptor() after use.
1264
 * \returns 0 on success
1265
 * \returns a LIBUSB_ERROR code on error
1266
 */
1267
int API_EXPORTED libusb_get_platform_descriptor(libusb_context *ctx,
1268
  struct libusb_bos_dev_capability_descriptor *dev_cap,
1269
  struct libusb_platform_descriptor **platform_descriptor)
1270
0
{
1271
0
  struct libusb_platform_descriptor *_platform_descriptor;
1272
1273
0
  if (dev_cap->bDevCapabilityType != LIBUSB_BT_PLATFORM_DESCRIPTOR) {
1274
0
    usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
1275
0
       dev_cap->bDevCapabilityType,
1276
0
       LIBUSB_BT_PLATFORM_DESCRIPTOR);
1277
0
    return LIBUSB_ERROR_INVALID_PARAM;
1278
0
  } else if (dev_cap->bLength < LIBUSB_BT_PLATFORM_DESCRIPTOR_MIN_SIZE) {
1279
0
    usbi_err(ctx, "short dev-cap descriptor read %u/%d",
1280
0
       dev_cap->bLength, LIBUSB_BT_PLATFORM_DESCRIPTOR_MIN_SIZE);
1281
0
    return LIBUSB_ERROR_IO;
1282
0
  }
1283
1284
0
  _platform_descriptor = (struct libusb_platform_descriptor *)malloc(dev_cap->bLength);
1285
0
  if (!_platform_descriptor)
1286
0
    return LIBUSB_ERROR_NO_MEM;
1287
1288
0
  _platform_descriptor->bLength = dev_cap->bLength;
1289
0
  _platform_descriptor->bDescriptorType = dev_cap->bDescriptorType;
1290
0
  _platform_descriptor->bDevCapabilityType = dev_cap->bDevCapabilityType;
1291
0
  _platform_descriptor->bReserved = dev_cap->dev_capability_data[0];
1292
0
  memcpy(_platform_descriptor->PlatformCapabilityUUID, &(dev_cap->dev_capability_data[1]), 16);
1293
1294
  /* Capability data is located after reserved byte and 16 byte UUID */
1295
0
  uint8_t* capability_data = dev_cap->dev_capability_data + 1 + 16;
1296
1297
  /* Capability data length is total descriptor length minus initial fields */
1298
0
  size_t capability_data_length = dev_cap->bLength - (3 + 1 + 16);
1299
1300
0
  memcpy(_platform_descriptor->CapabilityData, capability_data, capability_data_length);
1301
1302
0
  *platform_descriptor = _platform_descriptor;
1303
0
  return LIBUSB_SUCCESS;
1304
0
}
1305
1306
/** \ingroup libusb_desc
1307
 * Free a platform descriptor obtained from
1308
 * libusb_get_platform_descriptor().
1309
 * It is safe to call this function with a NULL platform_descriptor parameter,
1310
 * in which case the function simply returns.
1311
 *
1312
 * \param platform_descriptor the Platform descriptor to free
1313
 */
1314
void API_EXPORTED libusb_free_platform_descriptor(
1315
  struct libusb_platform_descriptor *platform_descriptor)
1316
0
{
1317
0
  free(platform_descriptor);
1318
0
}
1319
1320
/** \ingroup libusb_desc
1321
 * Retrieve a string descriptor in C style ASCII.
1322
 *
1323
 * Wrapper around libusb_get_string_descriptor(). Uses the first language
1324
 * supported by the device.
1325
 *
1326
 * \param dev_handle a device handle
1327
 * \param desc_index the index of the descriptor to retrieve
1328
 * \param data output buffer for ASCII string descriptor
1329
 * \param length size of data buffer
1330
 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
1331
 */
1332
int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle,
1333
  uint8_t desc_index, unsigned char *data, int length)
1334
0
{
1335
0
  union usbi_string_desc_buf str;
1336
0
  int r;
1337
0
  uint16_t langid, wdata;
1338
1339
  /* Asking for the zero'th index is special - it returns a string
1340
   * descriptor that contains all the language IDs supported by the
1341
   * device. Typically there aren't many - often only one. Language
1342
   * IDs are 16 bit numbers, and they start at the third byte in the
1343
   * descriptor. There's also no point in trying to read descriptor 0
1344
   * with this function. See USB 2.0 specification section 9.6.7 for
1345
   * more information.
1346
   */
1347
1348
0
  if (desc_index == 0)
1349
0
    return LIBUSB_ERROR_INVALID_PARAM;
1350
1351
0
  r = libusb_get_string_descriptor(dev_handle, 0, 0, str.buf, 4);
1352
0
  if (r < 0)
1353
0
    return r;
1354
0
  else if (r != 4 || str.desc.bLength < 4 || str.desc.bDescriptorType != LIBUSB_DT_STRING) {
1355
0
    usbi_warn(usbi_handle_ctx(dev_handle), "invalid language ID string descriptor");
1356
0
    return LIBUSB_ERROR_IO;
1357
0
  } else if (str.desc.bLength & 1)
1358
0
    usbi_warn(usbi_handle_ctx(dev_handle), "suspicious bLength %u for language ID string descriptor", str.desc.bLength);
1359
1360
0
  langid = libusb_le16_to_cpu(str.desc.wData[0]);
1361
0
  r = libusb_get_string_descriptor(dev_handle, desc_index, langid, str.buf, sizeof(str.buf));
1362
0
  if (r < 0)
1363
0
    return r;
1364
0
  else if (r < DESC_HEADER_LENGTH || str.desc.bLength > r || str.desc.bDescriptorType != LIBUSB_DT_STRING)
1365
0
    return LIBUSB_ERROR_IO;
1366
0
  else if ((str.desc.bLength & 1) || str.desc.bLength != r)
1367
0
    usbi_warn(usbi_handle_ctx(dev_handle), "suspicious bLength %u for string descriptor (read %d)", str.desc.bLength, r);
1368
1369
  /* Stop one byte before the end to leave room for null termination. */
1370
0
  int dest_max = length - 1;
1371
1372
  /* The descriptor has this number of wide characters */
1373
0
  int src_max = (str.desc.bLength - 1 - 1) / 2;
1374
1375
  /* Neither read nor write more than the smallest buffer */
1376
0
  int idx_max = MIN(dest_max, src_max);
1377
1378
0
  int idx;
1379
0
  for (idx = 0; idx < idx_max; ++idx) {
1380
0
    wdata = libusb_le16_to_cpu(str.desc.wData[idx]);
1381
0
    if (wdata < 0x80)
1382
0
      data[idx] = (unsigned char)wdata;
1383
0
    else
1384
0
      data[idx] = '?'; /* non-ASCII */
1385
0
  }
1386
1387
0
  data[idx] = 0; /* null-terminate string */
1388
0
  return idx;
1389
0
}
1390
1391
static int parse_iad_array(struct libusb_context *ctx,
1392
  struct libusb_interface_association_descriptor_array *iad_array,
1393
  const uint8_t *buffer, int size)
1394
0
{
1395
0
  uint8_t i;
1396
0
  struct usbi_descriptor_header header;
1397
0
  int consumed = 0;
1398
0
  const uint8_t *buf = buffer;
1399
0
  struct libusb_interface_association_descriptor *iad;
1400
0
  int iad_length = 0;
1401
1402
0
  iad_array->iad = NULL;
1403
0
  iad_array->length = 0;
1404
1405
0
  if (size < LIBUSB_DT_CONFIG_SIZE) {
1406
0
    usbi_err(ctx, "short config descriptor read %d/%d",
1407
0
       size, LIBUSB_DT_CONFIG_SIZE);
1408
0
    return LIBUSB_ERROR_IO;
1409
0
  }
1410
1411
  /* First pass: Iterate through desc list, count number of IADs */
1412
0
  while (size - consumed >= DESC_HEADER_LENGTH) {
1413
0
    header.bLength = buf[0];
1414
0
    header.bDescriptorType = buf[1];
1415
0
    if (header.bLength < DESC_HEADER_LENGTH) {
1416
0
      usbi_err(ctx, "invalid descriptor bLength %d",
1417
0
         header.bLength);
1418
0
      return LIBUSB_ERROR_IO;
1419
0
    }
1420
0
    else if (header.bLength > size - consumed) {
1421
0
      usbi_warn(ctx, "short config descriptor read %d/%u",
1422
0
            size - consumed, header.bLength);
1423
0
      return LIBUSB_ERROR_IO;
1424
0
    }
1425
0
    if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION)
1426
0
      iad_length++;
1427
0
    buf += header.bLength;
1428
0
    consumed += header.bLength;
1429
0
  }
1430
1431
0
  if (iad_length > 0) {
1432
0
    iad = (struct libusb_interface_association_descriptor *)calloc((size_t)iad_length, sizeof(*iad));
1433
0
    if (!iad)
1434
0
      return LIBUSB_ERROR_NO_MEM;
1435
1436
0
    iad_array->iad = iad;
1437
0
    iad_array->length = iad_length;
1438
1439
    /* Second pass: Iterate through desc list, fill IAD structures */
1440
0
    i = 0;
1441
0
    do {
1442
0
      header.bLength = buffer[0];
1443
0
      header.bDescriptorType = buffer[1];
1444
0
      if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION && (size >= LIBUSB_DT_INTERFACE_ASSOCIATION_SIZE)) {
1445
0
        iad[i].bLength = buffer[0];
1446
0
        iad[i].bDescriptorType = buffer[1];
1447
0
        iad[i].bFirstInterface = buffer[2];
1448
0
        iad[i].bInterfaceCount = buffer[3];
1449
0
        iad[i].bFunctionClass = buffer[4];
1450
0
        iad[i].bFunctionSubClass = buffer[5];
1451
0
        iad[i].bFunctionProtocol = buffer[6];
1452
0
        iad[i].iFunction = buffer[7];
1453
0
        i++;
1454
0
      }
1455
1456
0
      if (size - header.bLength < DESC_HEADER_LENGTH) {
1457
0
        break;
1458
0
      }
1459
1460
0
      size -= header.bLength;
1461
0
      buffer += header.bLength;
1462
0
    } while (1);
1463
0
  }
1464
1465
0
  return LIBUSB_SUCCESS;
1466
0
}
1467
1468
static int raw_desc_to_iad_array(struct libusb_context *ctx, const uint8_t *buf,
1469
    int size, struct libusb_interface_association_descriptor_array **iad_array)
1470
0
{
1471
0
  struct libusb_interface_association_descriptor_array *_iad_array
1472
0
    = (struct libusb_interface_association_descriptor_array *)calloc(1, sizeof(*_iad_array));
1473
0
  int r;
1474
1475
0
  if (!_iad_array)
1476
0
    return LIBUSB_ERROR_NO_MEM;
1477
1478
0
  r = parse_iad_array(ctx, _iad_array, buf, size);
1479
0
  if (r < 0) {
1480
0
    usbi_err(ctx, "parse_iad_array failed with error %d", r);
1481
0
    free(_iad_array);
1482
0
    return r;
1483
0
  }
1484
1485
0
  *iad_array = _iad_array;
1486
0
  return LIBUSB_SUCCESS;
1487
0
}
1488
1489
/** \ingroup libusb_desc
1490
 * Get an array of interface association descriptors (IAD) for a given
1491
 * configuration.
1492
 * This is a non-blocking function which does not involve any requests being
1493
 * sent to the device.
1494
 *
1495
 * \param dev a device
1496
 * \param config_index the index of the configuration you wish to retrieve the
1497
 * IADs for.
1498
 * \param iad_array output location for the array of IADs. Only valid if 0 was
1499
 * returned. Must be freed with libusb_free_interface_association_descriptors()
1500
 * after use. It's possible that a given configuration contains no IADs. In this
1501
 * case the iad_array is still output, but will have 'length' field set to 0, and
1502
 * iad field set to NULL.
1503
 * \returns 0 on success
1504
 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
1505
 * \returns another LIBUSB_ERROR code on error
1506
 * \see libusb_get_active_interface_association_descriptors()
1507
 */
1508
int API_EXPORTED libusb_get_interface_association_descriptors(libusb_device *dev,
1509
  uint8_t config_index, struct libusb_interface_association_descriptor_array **iad_array)
1510
0
{
1511
0
  union usbi_config_desc_buf _config;
1512
0
  uint16_t config_len;
1513
0
  uint8_t *buf;
1514
0
  int r;
1515
1516
0
  if (!iad_array)
1517
0
    return LIBUSB_ERROR_INVALID_PARAM;
1518
1519
0
  usbi_dbg(usbi_device_ctx(dev), "IADs for config index %u", config_index);
1520
0
  if (config_index >= dev->device_descriptor.bNumConfigurations)
1521
0
    return LIBUSB_ERROR_NOT_FOUND;
1522
1523
0
  r = get_config_descriptor(dev, config_index, _config.buf, sizeof(_config.buf));
1524
0
  if (r < 0)
1525
0
    return r;
1526
1527
0
  config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
1528
0
  buf = (uint8_t *)malloc(config_len);
1529
0
  if (!buf)
1530
0
    return LIBUSB_ERROR_NO_MEM;
1531
1532
0
  r = get_config_descriptor(dev, config_index, buf, config_len);
1533
0
  if (r >= 0)
1534
0
    r = raw_desc_to_iad_array(usbi_device_ctx(dev), buf, r, iad_array);
1535
1536
0
  free(buf);
1537
0
  return r;
1538
0
}
1539
1540
/** \ingroup libusb_desc
1541
 * Get an array of interface association descriptors (IAD) for the currently
1542
 * active configuration.
1543
 * This is a non-blocking function which does not involve any requests being
1544
 * sent to the device.
1545
 *
1546
 * \param dev a device
1547
 * \param iad_array output location for the array of IADs. Only valid if 0 was
1548
 * returned. Must be freed with libusb_free_interface_association_descriptors()
1549
 * after use. It's possible that a given configuration contains no IADs. In this
1550
 * case the iad_array is still output, but will have 'length' field set to 0, and
1551
 * iad field set to NULL.
1552
 * \returns 0 on success
1553
 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
1554
 * \returns another LIBUSB_ERROR code on error
1555
 * \see libusb_get_interface_association_descriptors
1556
 */
1557
int API_EXPORTED libusb_get_active_interface_association_descriptors(libusb_device *dev,
1558
  struct libusb_interface_association_descriptor_array **iad_array)
1559
0
{
1560
0
  union usbi_config_desc_buf _config;
1561
0
  uint16_t config_len;
1562
0
  uint8_t *buf;
1563
0
  int r;
1564
1565
0
  if (!iad_array)
1566
0
    return LIBUSB_ERROR_INVALID_PARAM;
1567
1568
0
  r = get_active_config_descriptor(dev, _config.buf, sizeof(_config.buf));
1569
0
  if (r < 0)
1570
0
    return r;
1571
1572
0
  config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
1573
0
  buf = (uint8_t *)malloc(config_len);
1574
0
  if (!buf)
1575
0
    return LIBUSB_ERROR_NO_MEM;
1576
1577
0
  r = get_active_config_descriptor(dev, buf, config_len);
1578
0
  if (r >= 0)
1579
0
    r = raw_desc_to_iad_array(usbi_device_ctx(dev), buf, r, iad_array);
1580
0
  free(buf);
1581
0
  return r;
1582
0
}
1583
1584
/** \ingroup libusb_desc
1585
 * Free an array of interface association descriptors (IADs) obtained from
1586
 * libusb_get_interface_association_descriptors() or
1587
 * libusb_get_active_interface_association_descriptors().
1588
 * It is safe to call this function with a NULL iad_array parameter, in which
1589
 * case the function simply returns.
1590
 *
1591
 * \param iad_array the IAD array to free
1592
 */
1593
void API_EXPORTED libusb_free_interface_association_descriptors(
1594
  struct libusb_interface_association_descriptor_array *iad_array)
1595
0
{
1596
0
  if (!iad_array)
1597
0
    return;
1598
1599
0
  if (iad_array->iad)
1600
0
    free((void*)iad_array->iad);
1601
0
  free(iad_array);
1602
0
}
1603
1604
/*
1605
 * \brief Copy a UTF-8 string with proper truncation if needed.
1606
 *
1607
 * \param tgt The target utf-8 string.  If NULL, then tgt is ignored,
1608
 *            tgt_size is forced to 0, and this function returns the
1609
 *            required tgt_size for a subsequent call to this function.
1610
 * \param src The source utf-8 string.  If NULL, then
1611
 *            the source string is empty, the return length is 1,
1612
 *            and, if tgt is not NULL, this function
1613
 *            sets tgt[0] to the null terminator.
1614
 * \param tgt_size The size of target in bytes.
1615
 * \return the length of src in bytes, including the null terminator.
1616
 *
1617
 * utf8_copy(NULL, src, 0) is equivalent to strlen(src) + 1.
1618
 */
1619
0
static int usbi_utf8_copy(char *tgt, char const *src, int tgt_size) {
1620
0
  uint8_t* t = (uint8_t*)tgt;
1621
0
  uint8_t const* s = (uint8_t const*)src;
1622
1623
0
  if (NULL == src) {
1624
0
    if ((NULL != tgt) && (tgt_size > 0)) {
1625
0
      tgt[0] = 0;
1626
0
    }
1627
0
    return 1;
1628
0
  }
1629
1630
0
  if ((NULL == tgt) || (tgt_size <= 0)) {
1631
0
    return (int)(strlen(src) + 1);
1632
0
  }
1633
1634
  // copy UTF-8 string and compute length
1635
0
  int k = 0;
1636
0
  for (k = 0; s[k]; ++k) {
1637
0
    if (k < tgt_size) {
1638
0
      t[k] = s[k];
1639
0
    } else {
1640
0
      break;
1641
0
    }
1642
0
  }
1643
1644
0
  if (k >= tgt_size) {
1645
    // truncate respecting UTF-8 character boundaries
1646
0
    int idx = tgt_size - 1;
1647
0
    while (idx && (0x80 == (t[idx] & 0xC0))) {  // utf-8 continuation byte
1648
0
      --idx;
1649
0
    }
1650
0
    t[idx] = 0;
1651
0
    return (int)(strlen(src) + 1);
1652
0
  } else {
1653
0
    t[k++] = 0;
1654
0
    return k;
1655
0
  }
1656
0
}
1657
1658
/** \ingroup libusb_desc
1659
 * Retrieve a device string without needing to open the device.
1660
 *
1661
 * Since version v1.0.30 \ref LIBUSB_API_VERSION >= 0x0100010C
1662
 *
1663
 * \param dev the target device
1664
 * \param string_type the string type to retrieve
1665
 * \param data the data buffer for the UTF-8 encoded string.
1666
 * \param length the size of the data buffer in bytes.
1667
 *      USB string descriptors cannot be longer than
1668
 *      LIBUSB_DEVICE_STRING_BYTES_MAX.
1669
 * \returns a negative error code or
1670
 *      the actual string length in bytes including the null terminator.
1671
 * \see libusb_get_string_descriptor()
1672
 * \see libusb_get_string_descriptor_ascii()
1673
 *
1674
 * This function works when the device is still closed since it relies
1675
 * on the operating system to provide the string.  The operating system
1676
 * normally reads and caches the common string descriptors during
1677
 * USB enumeration.
1678
 *
1679
 * Since the USB string descriptor could be processed by the OS,
1680
 * this function returns a UTF-8 encoded string.
1681
 *
1682
 * The string will be returned untranslated or in the default OS language
1683
 * when supported by the OS and USB device.
1684
 *
1685
 * One way to call this function is using a buffer on the stack:
1686
 *
1687
 *     char buffer[LIBUSB_DEVICE_STRING_BYTES_MAX];
1688
 *     int ret = libusb_get_device_string(dev, LIBUSB_DEVICE_STRING_SERIAL_NUMBER, buffer, sizeof(buffer));
1689
 *     if (ret < 0) {
1690
 *         // handle error
1691
 *     }
1692
 *
1693
 * This function is commonly used to get the serial number to allow
1694
 * for device selection before opening the selected device.
1695
 */
1696
int API_EXPORTED libusb_get_device_string(libusb_device *dev,
1697
0
  enum libusb_device_string_type string_type, char *data, int length) {
1698
0
  char * s;
1699
0
  if (NULL == dev) {
1700
0
    return LIBUSB_ERROR_INVALID_PARAM;
1701
0
  }
1702
0
  if ((string_type < 0) || (string_type >= LIBUSB_DEVICE_STRING_COUNT)) {
1703
0
    return LIBUSB_ERROR_INVALID_PARAM;
1704
0
  }
1705
0
  if (length <= 0) {
1706
0
    return LIBUSB_ERROR_INVALID_PARAM;
1707
0
  }
1708
0
  if (NULL == data) {
1709
0
    length = 0;
1710
0
    data = NULL;
1711
0
  } else if (length > 0) {
1712
0
    *data = 0;  // return an empty string on errors when possible
1713
0
  }
1714
1715
0
  if (NULL == dev->device_strings_utf8[string_type]) {
1716
0
    if (usbi_backend.get_device_string) {
1717
0
      s = (char *)malloc(LIBUSB_DEVICE_STRING_BYTES_MAX);
1718
0
      int rv = usbi_backend.get_device_string(dev, string_type, s, LIBUSB_DEVICE_STRING_BYTES_MAX);
1719
0
      if (rv < 0) {
1720
0
        free(s);
1721
0
        return rv;
1722
0
      } else {
1723
0
        dev->device_strings_utf8[string_type] = s;
1724
0
      }
1725
0
    } else {
1726
0
      return LIBUSB_ERROR_NOT_SUPPORTED;
1727
0
    }
1728
0
  }
1729
1730
0
  s = dev->device_strings_utf8[string_type];
1731
0
  if (NULL == s) {
1732
0
    return LIBUSB_ERROR_NOT_SUPPORTED;
1733
0
  }
1734
1735
0
  return usbi_utf8_copy(data, s, length);
1736
0
}
1737
1738
/* Get the configuration descriptor for config_value, or the active
1739
 * configuration when config_value is 0. */
1740
static int get_config_descriptor_for_value(libusb_device *dev,
1741
  uint8_t config_value, struct libusb_config_descriptor **config)
1742
0
{
1743
0
  if (config_value == 0)
1744
0
    return libusb_get_active_config_descriptor(dev, config);
1745
0
  return libusb_get_config_descriptor_by_value(dev, config_value, config);
1746
0
}
1747
1748
/* Resolve iConfiguration for config_value (0 = active config); *index_out is
1749
 * set to 0 when the configuration has no string descriptor. */
1750
int usbi_get_config_string_index(libusb_device *dev,
1751
  uint8_t config_value, uint8_t *index_out)
1752
0
{
1753
0
  struct libusb_config_descriptor *config = NULL;
1754
0
  int r;
1755
1756
0
  r = get_config_descriptor_for_value(dev, config_value, &config);
1757
0
  if (r < 0)
1758
0
    return r;
1759
1760
0
  *index_out = config->iConfiguration;
1761
0
  libusb_free_config_descriptor(config);
1762
0
  return LIBUSB_SUCCESS;
1763
0
}
1764
1765
/* Resolve iInterface for the given interface/alt setting (config_value 0 =
1766
 * active config); *index_out is 0 when it has no string descriptor.  Returns
1767
 * LIBUSB_ERROR_NOT_FOUND if the interface/alt setting does not exist. */
1768
int usbi_get_interface_string_index(libusb_device *dev,
1769
  uint8_t config_value, uint8_t interface_number, uint8_t alt_setting,
1770
  uint8_t *index_out)
1771
0
{
1772
0
  struct libusb_config_descriptor *config = NULL;
1773
0
  int r, i, j;
1774
1775
0
  r = get_config_descriptor_for_value(dev, config_value, &config);
1776
0
  if (r < 0)
1777
0
    return r;
1778
1779
0
  r = LIBUSB_ERROR_NOT_FOUND;
1780
0
  for (i = 0; i < config->bNumInterfaces; i++) {
1781
0
    const struct libusb_interface *intf = &config->interface[i];
1782
0
    for (j = 0; j < intf->num_altsetting; j++) {
1783
0
      const struct libusb_interface_descriptor *as = &intf->altsetting[j];
1784
0
      if (as->bInterfaceNumber == interface_number &&
1785
0
          as->bAlternateSetting == alt_setting) {
1786
0
        *index_out = as->iInterface;
1787
0
        r = LIBUSB_SUCCESS;
1788
0
        break;
1789
0
      }
1790
0
    }
1791
0
    if (r == LIBUSB_SUCCESS)
1792
0
      break;
1793
0
  }
1794
1795
0
  libusb_free_config_descriptor(config);
1796
0
  return r;
1797
0
}
1798
1799
/** \ingroup libusb_desc
1800
 * Retrieve the string descriptor describing a configuration (iConfiguration)
1801
 * without needing to open the device.
1802
 *
1803
 * Since version 1.0.31, \ref LIBUSB_API_VERSION >= 0x0100010D
1804
 *
1805
 * \param dev the target device
1806
 * \param config_value the bConfigurationValue of the configuration, or 0 to
1807
 *      select the device's currently active configuration.
1808
 * \param data the data buffer for the UTF-8 encoded string, or NULL to only
1809
 *      determine the required buffer size (length must still be non-zero).
1810
 * \param length the size of the data buffer in bytes.
1811
 *      USB string descriptors cannot be longer than
1812
 *      LIBUSB_DEVICE_STRING_BYTES_MAX.
1813
 * \returns a negative error code or
1814
 *      the actual string length in bytes including the null terminator.
1815
 * \see libusb_get_device_string()
1816
 * \see libusb_get_interface_string()
1817
 *
1818
 * Like \ref libusb_get_device_string() this function works while the device is
1819
 * still closed, relying on the operating system's cached descriptors.  Unlike
1820
 * \ref libusb_get_device_string() the result is not cached by libusb, so each
1821
 * call may perform I/O; cache the string if it is needed repeatedly.
1822
 *
1823
 * Platform notes:
1824
 * - Windows and macOS fetch the string by its descriptor index and can serve
1825
 *   any configuration, active or not.
1826
 * - Linux reads the string from sysfs, which only exposes the string of the
1827
 *   active configuration.  A non-active configuration can only be served
1828
 *   when it shares its string descriptor (iConfiguration index) with the
1829
 *   active one; otherwise \ref LIBUSB_ERROR_NOT_SUPPORTED is returned even
1830
 *   though the requested configuration is valid.  In that case the string
1831
 *   can still be read by opening the device and calling
1832
 *   \ref libusb_get_string_descriptor with the iConfiguration index.
1833
 * - Backends that do not implement this function always return
1834
 *   \ref LIBUSB_ERROR_NOT_SUPPORTED.
1835
 */
1836
int API_EXPORTED libusb_get_config_string(libusb_device *dev,
1837
  uint8_t config_value, char *data, int length)
1838
0
{
1839
0
  char buf[LIBUSB_DEVICE_STRING_BYTES_MAX];
1840
0
  int r;
1841
1842
0
  if (NULL == dev)
1843
0
    return LIBUSB_ERROR_INVALID_PARAM;
1844
0
  if (length <= 0)
1845
0
    return LIBUSB_ERROR_INVALID_PARAM;
1846
1847
  /* as in libusb_get_device_string(), data may be NULL to query the
1848
   * required buffer size */
1849
0
  if (NULL != data)
1850
0
    *data = 0;  /* return an empty string on errors when possible */
1851
1852
0
  if (NULL == usbi_backend.get_config_string)
1853
0
    return LIBUSB_ERROR_NOT_SUPPORTED;
1854
1855
  /* Fetch into a full-size buffer, then copy out via usbi_utf8_copy() for
1856
   * UTF-8-safe truncation, as libusb_get_device_string() does. */
1857
0
  r = usbi_backend.get_config_string(dev, config_value, buf, sizeof(buf));
1858
0
  if (r < 0)
1859
0
    return r;
1860
1861
0
  return usbi_utf8_copy(data, buf, length);
1862
0
}
1863
1864
/** \ingroup libusb_desc
1865
 * Retrieve the string descriptor describing an interface (iInterface)
1866
 * without needing to open the device.
1867
 *
1868
 * Since version 1.0.31, \ref LIBUSB_API_VERSION >= 0x0100010D
1869
 *
1870
 * \param dev the target device
1871
 * \param config_value the bConfigurationValue of the configuration the
1872
 *      interface belongs to, or 0 to select the device's currently active
1873
 *      configuration.
1874
 * \param interface_number the bInterfaceNumber of the interface
1875
 * \param alt_setting the bAlternateSetting of the interface
1876
 * \param data the data buffer for the UTF-8 encoded string, or NULL to only
1877
 *      determine the required buffer size (length must still be non-zero).
1878
 * \param length the size of the data buffer in bytes.
1879
 *      USB string descriptors cannot be longer than
1880
 *      LIBUSB_DEVICE_STRING_BYTES_MAX.
1881
 * \returns a negative error code or
1882
 *      the actual string length in bytes including the null terminator.
1883
 * \see libusb_get_device_string()
1884
 * \see libusb_get_config_string()
1885
 *
1886
 * Like \ref libusb_get_device_string() this function works while the device is
1887
 * still closed, relying on the operating system's cached descriptors.  Unlike
1888
 * \ref libusb_get_device_string() the result is not cached by libusb, so each
1889
 * call may perform I/O; cache the string if it is needed repeatedly.
1890
 *
1891
 * A return of \ref LIBUSB_ERROR_NOT_FOUND means the interface has no string
1892
 * descriptor (its iInterface is 0) or the requested interface/alternate
1893
 * setting does not exist.
1894
 *
1895
 * Platform notes:
1896
 * - Windows and macOS fetch the string by its descriptor index and can serve
1897
 *   any configuration and alternate setting, current or not.
1898
 * - Linux reads the string from sysfs, which only exposes the string of the
1899
 *   currently selected alternate setting in the active configuration.  A
1900
 *   valid but non-current alternate setting (or non-active configuration)
1901
 *   can only be served when it shares its string descriptor (iInterface
1902
 *   index) with the current one; otherwise \ref LIBUSB_ERROR_NOT_SUPPORTED
1903
 *   is returned even though the requested combination is valid.  In that
1904
 *   case the string can still be read by opening the device and calling
1905
 *   \ref libusb_get_string_descriptor with the iInterface index.
1906
 * - Backends that do not implement this function always return
1907
 *   \ref LIBUSB_ERROR_NOT_SUPPORTED.
1908
 */
1909
int API_EXPORTED libusb_get_interface_string(libusb_device *dev,
1910
  uint8_t config_value, uint8_t interface_number, uint8_t alt_setting,
1911
  char *data, int length)
1912
0
{
1913
0
  char buf[LIBUSB_DEVICE_STRING_BYTES_MAX];
1914
0
  int r;
1915
1916
0
  if (NULL == dev)
1917
0
    return LIBUSB_ERROR_INVALID_PARAM;
1918
0
  if (length <= 0)
1919
0
    return LIBUSB_ERROR_INVALID_PARAM;
1920
1921
  /* as in libusb_get_device_string(), data may be NULL to query the
1922
   * required buffer size */
1923
0
  if (NULL != data)
1924
0
    *data = 0;  /* return an empty string on errors when possible */
1925
1926
0
  if (NULL == usbi_backend.get_interface_string)
1927
0
    return LIBUSB_ERROR_NOT_SUPPORTED;
1928
1929
  /* Fetch into a full-size buffer, then copy out via usbi_utf8_copy() for
1930
   * UTF-8-safe truncation, as libusb_get_device_string() does. */
1931
0
  r = usbi_backend.get_interface_string(dev, config_value,
1932
0
    interface_number, alt_setting, buf, sizeof(buf));
1933
0
  if (r < 0)
1934
0
    return r;
1935
1936
0
  return usbi_utf8_copy(data, buf, length);
1937
0
}