usb 2.17.0 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +14 -0
- package/binding.gyp +2 -9
- package/dist/usb/bindings.d.ts +27 -2
- package/dist/usb/bindings.js.map +1 -1
- package/dist/usb/index.d.ts +0 -29
- package/dist/usb/index.js +4 -18
- package/dist/usb/index.js.map +1 -1
- package/libusb/.clang-tidy +5 -3
- package/libusb/.private/ci-build.sh +5 -1
- package/libusb/AUTHORS +14 -0
- package/libusb/ChangeLog +15 -2
- package/libusb/README +8 -5
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +4 -0
- package/libusb/configure.ac +12 -2
- package/libusb/examples/hotplugtest.c +19 -11
- package/libusb/examples/listdevs.c +41 -3
- package/libusb/examples/xusb.c +6 -1
- package/libusb/libusb/Makefile.am +4 -0
- package/libusb/libusb/core.c +175 -14
- package/libusb/libusb/descriptor.c +163 -14
- package/libusb/libusb/io.c +7 -3
- package/libusb/libusb/libusb-1.0.def +10 -0
- package/libusb/libusb/libusb.h +59 -9
- package/libusb/libusb/libusbi.h +89 -25
- package/libusb/libusb/os/darwin_usb.c +126 -46
- package/libusb/libusb/os/darwin_usb.h +10 -8
- package/libusb/libusb/os/emscripten_webusb.cpp +31 -10
- package/libusb/libusb/os/haiku_usb_raw.cpp +4 -0
- package/libusb/libusb/os/linux_usbfs.c +73 -25
- package/libusb/libusb/os/netbsd_usb.c +2 -0
- package/libusb/libusb/os/openbsd_usb.c +2 -0
- package/libusb/libusb/os/sunos_usb.c +2 -0
- package/libusb/libusb/os/threads_posix.c +3 -3
- package/libusb/libusb/os/threads_posix.h +8 -2
- package/libusb/libusb/os/threads_windows.h +2 -1
- package/libusb/libusb/os/windows_common.c +86 -1
- package/libusb/libusb/os/windows_common.h +20 -1
- package/libusb/libusb/os/windows_hotplug.c +321 -0
- package/libusb/libusb/os/windows_hotplug.h +28 -0
- package/libusb/libusb/os/windows_usbdk.c +16 -8
- package/libusb/libusb/os/windows_winusb.c +753 -41
- package/libusb/libusb/os/windows_winusb.h +11 -6
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/msvc/Base.props +1 -1
- package/libusb/msvc/Configuration.Base.props +2 -1
- package/libusb/msvc/Configuration.DynamicLibrary.props +12 -0
- package/libusb/msvc/ProjectConfigurations.Base.props +69 -16
- package/libusb/msvc/build_all.ps1 +2 -2
- package/libusb/msvc/config.h +4 -0
- package/libusb/msvc/getopt/bits/getopt_core.h +96 -0
- package/libusb/msvc/getopt/bits/getopt_ext.h +77 -0
- package/libusb/msvc/getopt/features.h +21 -0
- package/libusb/msvc/getopt/getopt.c +456 -705
- package/libusb/msvc/getopt/getopt.h +16 -158
- package/libusb/msvc/getopt/getopt1.c +40 -69
- package/libusb/msvc/getopt/getopt_int.h +118 -0
- package/libusb/msvc/getopt/gettext.h +7 -0
- package/libusb/msvc/getopt/unistd.h +5 -0
- package/libusb/msvc/getopt.vcxproj +11 -4
- package/libusb/msvc/libusb.sln +515 -268
- package/libusb/msvc/libusb_dll.vcxproj +2 -0
- package/libusb/msvc/libusb_static.vcxproj +2 -0
- package/libusb/msvc/xusb.vcxproj +1 -1
- package/libusb/tests/Makefile.am +10 -1
- package/libusb/tests/fuzz/corpus/bos/min.bos +0 -0
- package/libusb/tests/fuzz/corpus/descriptor_parsers/min_valid_config.bin +0 -0
- package/libusb/tests/fuzz/corpus/descriptor_parsers/regression_bug_a_endpoint_null.bin +0 -0
- package/libusb/tests/fuzz/corpus/descriptor_parsers/regression_bug_b_iad_oob.bin +0 -0
- package/libusb/tests/fuzz/fuzz_bos_descriptor.c +49 -0
- package/libusb/tests/fuzz/fuzz_descriptor_parsers.c +83 -0
- package/libusb/tests/stress_mt.c +2 -1
- package/libusb/tests/webusb-test-shim/index.js +6 -5
- package/libusb.gypi +5 -0
- package/package.json +1 -1
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-arm64/node.napi.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/{hotplug/libusb.cc → hotplug.cc} +2 -3
- package/src/{hotplug/hotplug.h → hotplug.h} +2 -6
- package/src/node_usb.cc +3 -3
- package/test/usb.coffee +4 -4
- package/test/webusb.coffee +22 -12
- package/src/hotplug/windows.cc +0 -168
package/libusb/libusb/core.c
CHANGED
|
@@ -382,6 +382,8 @@ if (cfg != desired)
|
|
|
382
382
|
* - libusb_detach_kernel_driver()
|
|
383
383
|
* - libusb_dev_mem_alloc()
|
|
384
384
|
* - libusb_dev_mem_free()
|
|
385
|
+
* - libusb_endpoint_set_raw_io()
|
|
386
|
+
* - libusb_endpoint_supports_raw_io()
|
|
385
387
|
* - libusb_error_name()
|
|
386
388
|
* - libusb_event_handler_active()
|
|
387
389
|
* - libusb_event_handling_ok()
|
|
@@ -404,6 +406,7 @@ if (cfg != desired)
|
|
|
404
406
|
* - libusb_free_usb_2_0_extension_descriptor()
|
|
405
407
|
* - libusb_get_active_config_descriptor()
|
|
406
408
|
* - libusb_get_bos_descriptor()
|
|
409
|
+
* - libusb_get_session_data()
|
|
407
410
|
* - libusb_get_bus_number()
|
|
408
411
|
* - libusb_get_config_descriptor()
|
|
409
412
|
* - libusb_get_config_descriptor_by_value()
|
|
@@ -415,10 +418,12 @@ if (cfg != desired)
|
|
|
415
418
|
* - libusb_get_device_descriptor()
|
|
416
419
|
* - libusb_get_device_list()
|
|
417
420
|
* - libusb_get_device_speed()
|
|
421
|
+
* - libusb_get_device_string()
|
|
418
422
|
* - libusb_get_iso_packet_buffer()
|
|
419
423
|
* - libusb_get_iso_packet_buffer_simple()
|
|
420
424
|
* - libusb_get_max_alt_packet_size()
|
|
421
425
|
* - libusb_get_max_iso_packet_size()
|
|
426
|
+
* - libusb_get_max_raw_io_transfer_size()
|
|
422
427
|
* - libusb_get_max_packet_size()
|
|
423
428
|
* - libusb_get_next_timeout()
|
|
424
429
|
* - libusb_get_parent()
|
|
@@ -499,6 +504,7 @@ if (cfg != desired)
|
|
|
499
504
|
* - \ref libusb_capability
|
|
500
505
|
* - \ref libusb_class_code
|
|
501
506
|
* - \ref libusb_descriptor_type
|
|
507
|
+
* - \ref libusb_device_string_type
|
|
502
508
|
* - \ref libusb_endpoint_direction
|
|
503
509
|
* - \ref libusb_endpoint_transfer_type
|
|
504
510
|
* - \ref libusb_error
|
|
@@ -722,26 +728,33 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
|
|
|
722
728
|
dev->session_data = session_id;
|
|
723
729
|
dev->speed = LIBUSB_SPEED_UNKNOWN;
|
|
724
730
|
|
|
725
|
-
|
|
726
|
-
|
|
731
|
+
/* Note: the device is NOT added to ctx->usb_devs here. The caller
|
|
732
|
+
* (backend) must call usbi_connect_device() after fully initializing
|
|
733
|
+
* the device's private data. This prevents a concurrent
|
|
734
|
+
* usbi_get_device_by_session_id() from finding a half-initialized
|
|
735
|
+
* device. */
|
|
727
736
|
|
|
728
737
|
return dev;
|
|
729
738
|
}
|
|
730
739
|
|
|
731
|
-
void
|
|
740
|
+
void usbi_attach_device(struct libusb_device *dev)
|
|
732
741
|
{
|
|
733
742
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
734
743
|
|
|
735
744
|
usbi_atomic_store(&dev->attached, 1);
|
|
736
745
|
|
|
737
|
-
usbi_mutex_lock(&
|
|
738
|
-
list_add(&dev->list, &
|
|
739
|
-
usbi_mutex_unlock(&
|
|
746
|
+
usbi_mutex_lock(&ctx->usb_devs_lock);
|
|
747
|
+
list_add(&dev->list, &ctx->usb_devs);
|
|
748
|
+
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
|
749
|
+
}
|
|
740
750
|
|
|
741
|
-
|
|
751
|
+
void usbi_connect_device(struct libusb_device *dev)
|
|
752
|
+
{
|
|
753
|
+
usbi_attach_device(dev);
|
|
754
|
+
usbi_hotplug_notification(DEVICE_CTX(dev), dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED);
|
|
742
755
|
}
|
|
743
756
|
|
|
744
|
-
void
|
|
757
|
+
void usbi_detach_device(struct libusb_device *dev)
|
|
745
758
|
{
|
|
746
759
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
747
760
|
|
|
@@ -750,8 +763,12 @@ void usbi_disconnect_device(struct libusb_device *dev)
|
|
|
750
763
|
usbi_mutex_lock(&ctx->usb_devs_lock);
|
|
751
764
|
list_del(&dev->list);
|
|
752
765
|
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
|
766
|
+
}
|
|
753
767
|
|
|
754
|
-
|
|
768
|
+
void usbi_disconnect_device(struct libusb_device *dev)
|
|
769
|
+
{
|
|
770
|
+
usbi_detach_device(dev);
|
|
771
|
+
usbi_hotplug_notification(DEVICE_CTX(dev), dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT);
|
|
755
772
|
}
|
|
756
773
|
|
|
757
774
|
/* Perform some final sanity checks on a newly discovered device. If this
|
|
@@ -905,6 +922,26 @@ void API_EXPORTED libusb_free_device_list(libusb_device **list,
|
|
|
905
922
|
free(list);
|
|
906
923
|
}
|
|
907
924
|
|
|
925
|
+
/** \ingroup libusb_dev
|
|
926
|
+
* Returns the backend-specific identifier of the underlying system device tree
|
|
927
|
+
* node. Can be used to find the corresponding system device and directly query
|
|
928
|
+
* it (or access it otherwise) when and if necessary.
|
|
929
|
+
*
|
|
930
|
+
* Relevant backends:
|
|
931
|
+
* - Darwin: IOKit `sessionID`
|
|
932
|
+
* - Windows WinUSB: `DEVINST`
|
|
933
|
+
* - Linux, BSD: `busnum << 8 | devnum`
|
|
934
|
+
*
|
|
935
|
+
* Since version 1.0.30, \ref LIBUSB_API_VERSION >= 0x0100010C
|
|
936
|
+
*
|
|
937
|
+
* \param dev a device (must not be null)
|
|
938
|
+
* \returns the backend-specific device identifier
|
|
939
|
+
*/
|
|
940
|
+
unsigned long API_EXPORTED libusb_get_session_data(libusb_device *dev)
|
|
941
|
+
{
|
|
942
|
+
return dev->session_data;
|
|
943
|
+
}
|
|
944
|
+
|
|
908
945
|
/** \ingroup libusb_dev
|
|
909
946
|
* Get the number of the bus that a device is connected to.
|
|
910
947
|
* \param dev a device
|
|
@@ -1276,6 +1313,7 @@ libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev)
|
|
|
1276
1313
|
|
|
1277
1314
|
refcnt = usbi_atomic_inc(&dev->refcnt);
|
|
1278
1315
|
assert(refcnt >= 2);
|
|
1316
|
+
UNUSED(refcnt);
|
|
1279
1317
|
|
|
1280
1318
|
return dev;
|
|
1281
1319
|
}
|
|
@@ -1292,8 +1330,27 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev)
|
|
|
1292
1330
|
if (!dev)
|
|
1293
1331
|
return;
|
|
1294
1332
|
|
|
1295
|
-
|
|
1296
|
-
|
|
1333
|
+
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
|
1334
|
+
/* Non-hotplug path: the decrement and conditional list removal
|
|
1335
|
+
* must be atomic with respect to usbi_get_device_by_session_id(),
|
|
1336
|
+
* which searches the list and refs the device under the same lock.
|
|
1337
|
+
* Without this, a concurrent search could find a device whose
|
|
1338
|
+
* refcnt has already reached zero and hit the assert in
|
|
1339
|
+
* libusb_ref_device(). */
|
|
1340
|
+
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
1341
|
+
|
|
1342
|
+
usbi_mutex_lock(&ctx->usb_devs_lock);
|
|
1343
|
+
refcnt = usbi_atomic_dec(&dev->refcnt);
|
|
1344
|
+
assert(refcnt >= 0);
|
|
1345
|
+
if (refcnt == 0 && usbi_atomic_load(&dev->attached)) {
|
|
1346
|
+
list_del(&dev->list);
|
|
1347
|
+
usbi_atomic_store(&dev->attached, 0);
|
|
1348
|
+
}
|
|
1349
|
+
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
|
1350
|
+
} else {
|
|
1351
|
+
refcnt = usbi_atomic_dec(&dev->refcnt);
|
|
1352
|
+
assert(refcnt >= 0);
|
|
1353
|
+
}
|
|
1297
1354
|
|
|
1298
1355
|
if (refcnt == 0) {
|
|
1299
1356
|
usbi_dbg(DEVICE_CTX(dev), "destroy device %d.%d", dev->bus_number, dev->device_address);
|
|
@@ -1303,9 +1360,8 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev)
|
|
|
1303
1360
|
if (usbi_backend.destroy_device)
|
|
1304
1361
|
usbi_backend.destroy_device(dev);
|
|
1305
1362
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
usbi_disconnect_device(dev);
|
|
1363
|
+
for (int idx = 0; idx < LIBUSB_DEVICE_STRING_COUNT; ++idx) {
|
|
1364
|
+
free(dev->device_strings_utf8[idx]);
|
|
1309
1365
|
}
|
|
1310
1366
|
|
|
1311
1367
|
free(dev);
|
|
@@ -2204,6 +2260,111 @@ int API_EXPORTED libusb_set_auto_detach_kernel_driver(
|
|
|
2204
2260
|
return LIBUSB_SUCCESS;
|
|
2205
2261
|
}
|
|
2206
2262
|
|
|
2263
|
+
/** \ingroup libusb_dev
|
|
2264
|
+
* Check if the endpoint supports RAW_IO.
|
|
2265
|
+
* \param dev_handle a device handle
|
|
2266
|
+
* \param endpoint the endpoint to check
|
|
2267
|
+
*
|
|
2268
|
+
* \returns 1 if the endpoint supports RAW_IO
|
|
2269
|
+
* \returns 0 if the endpoint does not support RAW_IO
|
|
2270
|
+
* \returns a LIBUSB_ERROR code on failure
|
|
2271
|
+
*
|
|
2272
|
+
* Only endpoints using the WinUSB driver support RAW_IO,
|
|
2273
|
+
* for all other backends/drivers this function will return 0.
|
|
2274
|
+
*
|
|
2275
|
+
* Fails if the interface the endpoint belongs to isn't claimed,
|
|
2276
|
+
* \see libusb_claim_interface().
|
|
2277
|
+
*
|
|
2278
|
+
* \see libusb_endpoint_set_raw_io()
|
|
2279
|
+
*
|
|
2280
|
+
* Since version 1.0.30, \ref LIBUSB_API_VERSION >= 0x0100010C
|
|
2281
|
+
*/
|
|
2282
|
+
int API_EXPORTED libusb_endpoint_supports_raw_io(libusb_device_handle* dev_handle,
|
|
2283
|
+
uint8_t endpoint)
|
|
2284
|
+
{
|
|
2285
|
+
if (usbi_backend.endpoint_supports_raw_io == NULL)
|
|
2286
|
+
{
|
|
2287
|
+
return 0;
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
// If the `endpoint_supports_raw_io` function is present, these two should be too:
|
|
2291
|
+
assert(usbi_backend.endpoint_set_raw_io != NULL);
|
|
2292
|
+
assert(usbi_backend.get_max_raw_io_transfer_size != NULL);
|
|
2293
|
+
|
|
2294
|
+
return usbi_backend.endpoint_supports_raw_io(dev_handle, endpoint);
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
/** \ingroup libusb_dev
|
|
2298
|
+
* Enable/disable RAW_IO for an endpoint on an open device.
|
|
2299
|
+
*
|
|
2300
|
+
* Only endpoints using the WinUSB driver support RAW_IO,
|
|
2301
|
+
* for all other backends/drivers this function will return an error code.
|
|
2302
|
+
*
|
|
2303
|
+
* Using RAW_IO can greatly improve USB throughput by directly passing
|
|
2304
|
+
* transfer requests to the underlying USB driver instead of queuing them
|
|
2305
|
+
* in WinUSB. This can be particularly useful for high-throughput devices
|
|
2306
|
+
* like cameras or oscilloscopes.
|
|
2307
|
+
*
|
|
2308
|
+
* Transfers submitted to the endpoint while RAW_IO is enabled will fail unless
|
|
2309
|
+
* they adhere to the following rules :
|
|
2310
|
+
* - The buffer length must be a multiple of the maximum endpoint packet size
|
|
2311
|
+
* \see libusb_get_max_packet_size.
|
|
2312
|
+
* - The buffer length must be less than or equal to the value returned by
|
|
2313
|
+
* \ref libusb_get_max_raw_io_transfer_size.
|
|
2314
|
+
*
|
|
2315
|
+
* This option should not be changed when any transfer is in progress on
|
|
2316
|
+
* the specified endpoint.
|
|
2317
|
+
*
|
|
2318
|
+
* Fails if the interface the endpoint belongs to isn't claimed,
|
|
2319
|
+
* \see libusb_claim_interface().
|
|
2320
|
+
*
|
|
2321
|
+
* \param dev_handle a device handle
|
|
2322
|
+
* \param endpoint the endpoint to set RAW_IO for
|
|
2323
|
+
* \param enable 1 to enable RAW_IO, 0 to disable it
|
|
2324
|
+
*
|
|
2325
|
+
* \returns \ref LIBUSB_SUCCESS on success
|
|
2326
|
+
* \returns \ref LIBUSB_ERROR_NOT_SUPPORTED if the backend does not support RAW_IO.
|
|
2327
|
+
* \returns another LIBUSB_ERROR code on other failure
|
|
2328
|
+
*
|
|
2329
|
+
* \see libusb_endpoint_supports_raw_io()
|
|
2330
|
+
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-functions-for-pipe-policy-modification
|
|
2331
|
+
*
|
|
2332
|
+
* Since version 1.0.30, \ref LIBUSB_API_VERSION >= 0x0100010C
|
|
2333
|
+
*/
|
|
2334
|
+
int API_EXPORTED libusb_endpoint_set_raw_io(libusb_device_handle* dev_handle,
|
|
2335
|
+
uint8_t endpoint, int enable)
|
|
2336
|
+
{
|
|
2337
|
+
if (!usbi_backend.endpoint_set_raw_io)
|
|
2338
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
2339
|
+
|
|
2340
|
+
return usbi_backend.endpoint_set_raw_io(dev_handle, endpoint, enable);
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
/** \ingroup libusb_dev
|
|
2344
|
+
* Retrieve the maximum transfer size in bytes supported for WinUSB RAW_IO
|
|
2345
|
+
* for an inbound bulk or interrupt endpoint on an open device.
|
|
2346
|
+
*
|
|
2347
|
+
* Returns a maximum transfer size in bytes, or a negative error code.
|
|
2348
|
+
* If the backend does not support WinUSB RAW_IO, returns
|
|
2349
|
+
* \ref LIBUSB_ERROR_NOT_SUPPORTED.
|
|
2350
|
+
*
|
|
2351
|
+
* Fails if the interface the endpoint belongs to isn't claimed,
|
|
2352
|
+
* \see libusb_claim_interface().
|
|
2353
|
+
*
|
|
2354
|
+
* \see libusb_endpoint_set_raw_io()
|
|
2355
|
+
*
|
|
2356
|
+
* Since version 1.0.30, \ref LIBUSB_API_VERSION >= 0x0100010C
|
|
2357
|
+
*/
|
|
2358
|
+
int API_EXPORTED libusb_get_max_raw_io_transfer_size(
|
|
2359
|
+
libusb_device_handle *dev_handle, uint8_t endpoint)
|
|
2360
|
+
{
|
|
2361
|
+
if (!usbi_backend.get_max_raw_io_transfer_size)
|
|
2362
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
2363
|
+
|
|
2364
|
+
return usbi_backend.get_max_raw_io_transfer_size(
|
|
2365
|
+
dev_handle, endpoint);
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2207
2368
|
/** \ingroup libusb_lib
|
|
2208
2369
|
* Deprecated. Use libusb_set_option() or libusb_init_context() instead,
|
|
2209
2370
|
* with the \ref LIBUSB_OPTION_LOG_LEVEL option.
|
|
@@ -38,10 +38,10 @@ static inline uint16_t ReadLittleEndian16(const uint8_t p[2])
|
|
|
38
38
|
|
|
39
39
|
static inline uint32_t ReadLittleEndian32(const uint8_t p[4])
|
|
40
40
|
{
|
|
41
|
-
return (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
return ((uint32_t)p[3] << 24 |
|
|
42
|
+
(uint32_t)p[2] << 16 |
|
|
43
|
+
(uint32_t)p[1] << 8 |
|
|
44
|
+
(uint32_t)p[0]);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
|
|
@@ -148,6 +148,8 @@ static void clear_interface(struct libusb_interface *usb_interface)
|
|
|
148
148
|
usb_interface->altsetting + i;
|
|
149
149
|
|
|
150
150
|
free((void *)ifp->extra);
|
|
151
|
+
ifp->extra = NULL;
|
|
152
|
+
ifp->extra_length = 0;
|
|
151
153
|
if (ifp->endpoint) {
|
|
152
154
|
uint8_t j;
|
|
153
155
|
|
|
@@ -156,10 +158,13 @@ static void clear_interface(struct libusb_interface *usb_interface)
|
|
|
156
158
|
ifp->endpoint + j);
|
|
157
159
|
}
|
|
158
160
|
free((void *)ifp->endpoint);
|
|
161
|
+
ifp->endpoint = NULL;
|
|
162
|
+
ifp->bNumEndpoints = 0;
|
|
159
163
|
}
|
|
160
164
|
}
|
|
161
165
|
free((void *)usb_interface->altsetting);
|
|
162
166
|
usb_interface->altsetting = NULL;
|
|
167
|
+
usb_interface->num_altsetting = 0;
|
|
163
168
|
}
|
|
164
169
|
|
|
165
170
|
static int parse_interface(libusb_context *ctx,
|
|
@@ -241,6 +246,10 @@ static int parse_interface(libusb_context *ctx,
|
|
|
241
246
|
usbi_warn(ctx,
|
|
242
247
|
"short extra intf desc read %d/%u",
|
|
243
248
|
size, header->bLength);
|
|
249
|
+
/* Keep the invariant: bNumEndpoints > 0 implies
|
|
250
|
+
* endpoint != NULL. The endpoint array isn't
|
|
251
|
+
* allocated yet on this early return. */
|
|
252
|
+
ifp->bNumEndpoints = 0;
|
|
244
253
|
return parsed;
|
|
245
254
|
}
|
|
246
255
|
|
|
@@ -322,7 +331,11 @@ static void clear_configuration(struct libusb_config_descriptor *config)
|
|
|
322
331
|
config->interface + i);
|
|
323
332
|
}
|
|
324
333
|
free((void *)config->interface);
|
|
334
|
+
config->interface = NULL;
|
|
335
|
+
config->bNumInterfaces = 0;
|
|
325
336
|
free((void *)config->extra);
|
|
337
|
+
config->extra = NULL;
|
|
338
|
+
config->extra_length = 0;
|
|
326
339
|
}
|
|
327
340
|
|
|
328
341
|
static int parse_configuration(struct libusb_context *ctx,
|
|
@@ -423,7 +436,7 @@ static int parse_configuration(struct libusb_context *ctx,
|
|
|
423
436
|
config->extra_length += (int)len;
|
|
424
437
|
}
|
|
425
438
|
|
|
426
|
-
r = parse_interface(ctx, usb_interface + i, buffer,
|
|
439
|
+
r = parse_interface(ctx, usb_interface + i, buffer, size);
|
|
427
440
|
if (r < 0)
|
|
428
441
|
goto err;
|
|
429
442
|
if (r == 0) {
|
|
@@ -777,7 +790,7 @@ static int parse_bos(struct libusb_context *ctx,
|
|
|
777
790
|
return LIBUSB_ERROR_IO;
|
|
778
791
|
}
|
|
779
792
|
|
|
780
|
-
_bos = calloc(1, sizeof(*_bos) + bos_desc->bNumDeviceCaps * sizeof(void *));
|
|
793
|
+
_bos = calloc(1, sizeof(*_bos) + (bos_desc->bNumDeviceCaps * sizeof(void *)));
|
|
781
794
|
if (!_bos)
|
|
782
795
|
return LIBUSB_ERROR_NO_MEM;
|
|
783
796
|
|
|
@@ -1082,7 +1095,7 @@ int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
|
|
|
1082
1095
|
parsedDescriptor.wReserved = ReadLittleEndian16(&dev_capability_data[7]);
|
|
1083
1096
|
|
|
1084
1097
|
uint8_t numSublikSpeedAttributes = (parsedDescriptor.bmAttributes & 0xF) + 1;
|
|
1085
|
-
_ssplus_cap = malloc(sizeof(struct libusb_ssplus_usb_device_capability_descriptor) + numSublikSpeedAttributes * sizeof(struct libusb_ssplus_sublink_attribute));
|
|
1098
|
+
_ssplus_cap = malloc(sizeof(struct libusb_ssplus_usb_device_capability_descriptor) + (numSublikSpeedAttributes * sizeof(struct libusb_ssplus_sublink_attribute)));
|
|
1086
1099
|
if (!_ssplus_cap)
|
|
1087
1100
|
return LIBUSB_ERROR_NO_MEM;
|
|
1088
1101
|
|
|
@@ -1096,7 +1109,8 @@ int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
|
|
|
1096
1109
|
_ssplus_cap->minTxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0xF000) >> 12;
|
|
1097
1110
|
|
|
1098
1111
|
/* Check that we have enough to read all the sublink attributes */
|
|
1099
|
-
if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE + _ssplus_cap->numSublinkSpeedAttributes * sizeof(uint32_t)) {
|
|
1112
|
+
if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE + (_ssplus_cap->numSublinkSpeedAttributes * sizeof(uint32_t))) {
|
|
1113
|
+
free(_ssplus_cap);
|
|
1100
1114
|
usbi_err(ctx, "short ssplus capability descriptor, unable to read sublinks: Not enough data");
|
|
1101
1115
|
return LIBUSB_ERROR_IO;
|
|
1102
1116
|
}
|
|
@@ -1104,7 +1118,7 @@ int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
|
|
|
1104
1118
|
/* Read the attributes */
|
|
1105
1119
|
uint8_t* base = ((uint8_t*)dev_cap) + LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE;
|
|
1106
1120
|
for(uint8_t i = 0 ; i < _ssplus_cap->numSublinkSpeedAttributes ; i++) {
|
|
1107
|
-
uint32_t attr = ReadLittleEndian32(base + i * sizeof(uint32_t));
|
|
1121
|
+
uint32_t attr = ReadLittleEndian32(base + (i * sizeof(uint32_t)));
|
|
1108
1122
|
_ssplus_cap->sublinkSpeedAttributes[i].ssid = attr & 0x0f;
|
|
1109
1123
|
_ssplus_cap->sublinkSpeedAttributes[i].mantissa = attr >> 16;
|
|
1110
1124
|
_ssplus_cap->sublinkSpeedAttributes[i].exponent = (attr >> 4) & 0x3 ;
|
|
@@ -1311,9 +1325,10 @@ int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_ha
|
|
|
1311
1325
|
r = libusb_get_string_descriptor(dev_handle, 0, 0, str.buf, 4);
|
|
1312
1326
|
if (r < 0)
|
|
1313
1327
|
return r;
|
|
1314
|
-
else if (r != 4 || str.desc.bLength < 4 || str.desc.bDescriptorType != LIBUSB_DT_STRING)
|
|
1328
|
+
else if (r != 4 || str.desc.bLength < 4 || str.desc.bDescriptorType != LIBUSB_DT_STRING) {
|
|
1329
|
+
usbi_warn(HANDLE_CTX(dev_handle), "invalid language ID string descriptor");
|
|
1315
1330
|
return LIBUSB_ERROR_IO;
|
|
1316
|
-
else if (str.desc.bLength & 1)
|
|
1331
|
+
} else if (str.desc.bLength & 1)
|
|
1317
1332
|
usbi_warn(HANDLE_CTX(dev_handle), "suspicious bLength %u for language ID string descriptor", str.desc.bLength);
|
|
1318
1333
|
|
|
1319
1334
|
langid = libusb_le16_to_cpu(str.desc.wData[0]);
|
|
@@ -1365,7 +1380,7 @@ static int parse_iad_array(struct libusb_context *ctx,
|
|
|
1365
1380
|
|
|
1366
1381
|
/* First pass: Iterate through desc list, count number of IADs */
|
|
1367
1382
|
iad_array->length = 0;
|
|
1368
|
-
while (consumed
|
|
1383
|
+
while (size - consumed >= DESC_HEADER_LENGTH) {
|
|
1369
1384
|
header.bLength = buf[0];
|
|
1370
1385
|
header.bDescriptorType = buf[1];
|
|
1371
1386
|
if (header.bLength < DESC_HEADER_LENGTH) {
|
|
@@ -1373,9 +1388,9 @@ static int parse_iad_array(struct libusb_context *ctx,
|
|
|
1373
1388
|
header.bLength);
|
|
1374
1389
|
return LIBUSB_ERROR_IO;
|
|
1375
1390
|
}
|
|
1376
|
-
else if (header.bLength > size) {
|
|
1391
|
+
else if (header.bLength > size - consumed) {
|
|
1377
1392
|
usbi_warn(ctx, "short config descriptor read %d/%u",
|
|
1378
|
-
size, header.bLength);
|
|
1393
|
+
size - consumed, header.bLength);
|
|
1379
1394
|
return LIBUSB_ERROR_IO;
|
|
1380
1395
|
}
|
|
1381
1396
|
if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION)
|
|
@@ -1556,3 +1571,137 @@ void API_EXPORTED libusb_free_interface_association_descriptors(
|
|
|
1556
1571
|
free((void*)iad_array->iad);
|
|
1557
1572
|
free(iad_array);
|
|
1558
1573
|
}
|
|
1574
|
+
|
|
1575
|
+
/*
|
|
1576
|
+
* \brief Copy a UTF-8 string with proper truncation if needed.
|
|
1577
|
+
*
|
|
1578
|
+
* \param tgt The target utf-8 string. If NULL, then tgt is ignored,
|
|
1579
|
+
* tgt_size is forced to 0, and this function returns the
|
|
1580
|
+
* required tgt_size for a subsequent call to this function.
|
|
1581
|
+
* \param src The source utf-8 string. If NULL, then
|
|
1582
|
+
* the source string is empty, the return length is 1,
|
|
1583
|
+
* and, if tgt is not NULL, this function
|
|
1584
|
+
* sets tgt[0] to the null terminator.
|
|
1585
|
+
* \param tgt_size The size of target in bytes.
|
|
1586
|
+
* \return the length of src in bytes, including the null terminator.
|
|
1587
|
+
*
|
|
1588
|
+
* utf8_copy(NULL, src, 0) is equivalent to strlen(src) + 1.
|
|
1589
|
+
*/
|
|
1590
|
+
static int usbi_utf8_copy(char *tgt, char const *src, int tgt_size) {
|
|
1591
|
+
uint8_t* t = (uint8_t*)tgt;
|
|
1592
|
+
uint8_t const* s = (uint8_t const*)src;
|
|
1593
|
+
|
|
1594
|
+
if (NULL == src) {
|
|
1595
|
+
if ((NULL != tgt) && (tgt_size > 0)) {
|
|
1596
|
+
tgt[0] = 0;
|
|
1597
|
+
}
|
|
1598
|
+
return 1;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
if ((NULL == tgt) || (tgt_size <= 0)) {
|
|
1602
|
+
return (int)(strlen(src) + 1);
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
// copy UTF-8 string and compute length
|
|
1606
|
+
int k = 0;
|
|
1607
|
+
for (k = 0; s[k]; ++k) {
|
|
1608
|
+
if (k < tgt_size) {
|
|
1609
|
+
t[k] = s[k];
|
|
1610
|
+
} else {
|
|
1611
|
+
break;
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
if (k >= tgt_size) {
|
|
1616
|
+
// truncate respecting UTF-8 character boundaries
|
|
1617
|
+
int idx = tgt_size - 1;
|
|
1618
|
+
while (idx && (0x80 == (t[idx] & 0xC0))) { // utf-8 continuation byte
|
|
1619
|
+
--idx;
|
|
1620
|
+
}
|
|
1621
|
+
t[idx] = 0;
|
|
1622
|
+
return (int)(strlen(src) + 1);
|
|
1623
|
+
} else {
|
|
1624
|
+
t[k++] = 0;
|
|
1625
|
+
return k;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
/** \ingroup libusb_desc
|
|
1630
|
+
* Retrieve a device string without needing to open the device.
|
|
1631
|
+
*
|
|
1632
|
+
* Since version v1.0.30 \ref LIBUSB_API_VERSION >= 0x0100010C
|
|
1633
|
+
*
|
|
1634
|
+
* \param dev the target device
|
|
1635
|
+
* \param string_type the string type to retrieve
|
|
1636
|
+
* \param data the data buffer for the UTF-8 encoded string.
|
|
1637
|
+
* \param length the size of the data buffer in bytes.
|
|
1638
|
+
* USB string descriptors cannot be longer than
|
|
1639
|
+
* LIBUSB_DEVICE_STRING_BYTES_MAX.
|
|
1640
|
+
* \returns a negative error code or
|
|
1641
|
+
* the actual string length in bytes including the null terminator.
|
|
1642
|
+
* \see libusb_get_string_descriptor()
|
|
1643
|
+
* \see libusb_get_string_descriptor_ascii()
|
|
1644
|
+
*
|
|
1645
|
+
* This function works when the device is still closed since it relies
|
|
1646
|
+
* on the operating system to provide the string. The operating system
|
|
1647
|
+
* normally reads and caches the common string descriptors during
|
|
1648
|
+
* USB enumeration.
|
|
1649
|
+
*
|
|
1650
|
+
* Since the USB string descriptor could be processed by the OS,
|
|
1651
|
+
* this function returns a UTF-8 encoded string.
|
|
1652
|
+
*
|
|
1653
|
+
* The string will be returned untranslated or in the default OS language
|
|
1654
|
+
* when supported by the OS and USB device.
|
|
1655
|
+
*
|
|
1656
|
+
* One way to call this function is using a buffer on the stack:
|
|
1657
|
+
*
|
|
1658
|
+
* char buffer[LIBUSB_DEVICE_STRING_BYTES_MAX];
|
|
1659
|
+
* int ret = libusb_get_device_string(dev, LIBUSB_DEVICE_STRING_SERIAL_NUMBER, buffer, sizeof(buffer));
|
|
1660
|
+
* if (ret < 0) {
|
|
1661
|
+
* // handle error
|
|
1662
|
+
* }
|
|
1663
|
+
*
|
|
1664
|
+
* This function is commonly used to get the serial number to allow
|
|
1665
|
+
* for device selection before opening the selected device.
|
|
1666
|
+
*/
|
|
1667
|
+
int API_EXPORTED libusb_get_device_string(libusb_device *dev,
|
|
1668
|
+
enum libusb_device_string_type string_type, char *data, int length) {
|
|
1669
|
+
char * s;
|
|
1670
|
+
if (NULL == dev) {
|
|
1671
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1672
|
+
}
|
|
1673
|
+
if ((string_type < 0) || (string_type >= LIBUSB_DEVICE_STRING_COUNT)) {
|
|
1674
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1675
|
+
}
|
|
1676
|
+
if (length <= 0) {
|
|
1677
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1678
|
+
}
|
|
1679
|
+
if (NULL == data) {
|
|
1680
|
+
length = 0;
|
|
1681
|
+
data = NULL;
|
|
1682
|
+
} else if (length > 0) {
|
|
1683
|
+
*data = 0; // return an empty string on errors when possible
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
if (NULL == dev->device_strings_utf8[string_type]) {
|
|
1687
|
+
if (usbi_backend.get_device_string) {
|
|
1688
|
+
s = malloc(LIBUSB_DEVICE_STRING_BYTES_MAX);
|
|
1689
|
+
int rv = usbi_backend.get_device_string(dev, string_type, s, LIBUSB_DEVICE_STRING_BYTES_MAX);
|
|
1690
|
+
if (rv < 0) {
|
|
1691
|
+
free(s);
|
|
1692
|
+
return rv;
|
|
1693
|
+
} else {
|
|
1694
|
+
dev->device_strings_utf8[string_type] = s;
|
|
1695
|
+
}
|
|
1696
|
+
} else {
|
|
1697
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
s = dev->device_strings_utf8[string_type];
|
|
1702
|
+
if (NULL == s) {
|
|
1703
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
return usbi_utf8_copy(data, s, length);
|
|
1707
|
+
}
|
package/libusb/libusb/io.c
CHANGED
|
@@ -1303,7 +1303,6 @@ struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
|
|
|
1303
1303
|
return NULL;
|
|
1304
1304
|
|
|
1305
1305
|
struct usbi_transfer *itransfer = (struct usbi_transfer *)(ptr + priv_size);
|
|
1306
|
-
itransfer->num_iso_packets = iso_packets;
|
|
1307
1306
|
itransfer->priv = ptr;
|
|
1308
1307
|
usbi_mutex_init(&itransfer->lock);
|
|
1309
1308
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
@@ -1370,8 +1369,10 @@ static int arm_timer_for_next_timeout(struct libusb_context *ctx)
|
|
|
1370
1369
|
|
|
1371
1370
|
/* act on first transfer that has not already been handled */
|
|
1372
1371
|
if (!(itransfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) {
|
|
1372
|
+
#ifdef ENABLE_LOGGING
|
|
1373
1373
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1374
1374
|
usbi_dbg(ctx, "next timeout originally %ums", transfer->timeout);
|
|
1375
|
+
#endif
|
|
1375
1376
|
return usbi_arm_timer(&ctx->timer, cur_ts);
|
|
1376
1377
|
}
|
|
1377
1378
|
}
|
|
@@ -1434,9 +1435,11 @@ out:
|
|
|
1434
1435
|
if (first && usbi_using_timer(ctx) && TIMESPEC_IS_SET(timeout)) {
|
|
1435
1436
|
/* if this transfer has the lowest timeout of all active transfers,
|
|
1436
1437
|
* rearm the timer with this transfer's timeout */
|
|
1438
|
+
#ifdef ENABLE_LOGGING
|
|
1437
1439
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1438
1440
|
usbi_dbg(ctx, "arm timer for timeout in %ums (first in line)",
|
|
1439
1441
|
transfer->timeout);
|
|
1442
|
+
#endif
|
|
1440
1443
|
r = usbi_arm_timer(&ctx->timer, timeout);
|
|
1441
1444
|
}
|
|
1442
1445
|
#else
|
|
@@ -2811,9 +2814,8 @@ void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds)
|
|
|
2811
2814
|
* device. This function ensures transfers get cancelled appropriately.
|
|
2812
2815
|
* Callers of this function must hold the events_lock.
|
|
2813
2816
|
*/
|
|
2814
|
-
void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
|
|
2817
|
+
void usbi_handle_disconnect(struct libusb_context *ctx, struct libusb_device_handle *dev_handle)
|
|
2815
2818
|
{
|
|
2816
|
-
struct libusb_context *ctx = HANDLE_CTX(dev_handle);
|
|
2817
2819
|
struct usbi_transfer *cur;
|
|
2818
2820
|
struct usbi_transfer *to_cancel;
|
|
2819
2821
|
|
|
@@ -2853,9 +2855,11 @@ void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
|
|
|
2853
2855
|
if (!to_cancel)
|
|
2854
2856
|
break;
|
|
2855
2857
|
|
|
2858
|
+
#ifdef ENABLE_LOGGING
|
|
2856
2859
|
struct libusb_transfer *transfer_to_cancel = USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel);
|
|
2857
2860
|
usbi_dbg(ctx, "cancelling transfer %p from disconnect",
|
|
2858
2861
|
(void *) transfer_to_cancel);
|
|
2862
|
+
#endif
|
|
2859
2863
|
|
|
2860
2864
|
usbi_mutex_lock(&to_cancel->lock);
|
|
2861
2865
|
usbi_backend.clear_transfer_priv(to_cancel);
|
|
@@ -24,6 +24,10 @@ EXPORTS
|
|
|
24
24
|
libusb_dev_mem_alloc@8 = libusb_dev_mem_alloc
|
|
25
25
|
libusb_dev_mem_free
|
|
26
26
|
libusb_dev_mem_free@12 = libusb_dev_mem_free
|
|
27
|
+
libusb_endpoint_set_raw_io
|
|
28
|
+
libusb_endpoint_set_raw_io@12 = libusb_endpoint_set_raw_io
|
|
29
|
+
libusb_endpoint_supports_raw_io
|
|
30
|
+
libusb_endpoint_supports_raw_io@8 = libusb_endpoint_supports_raw_io
|
|
27
31
|
libusb_error_name
|
|
28
32
|
libusb_error_name@4 = libusb_error_name
|
|
29
33
|
libusb_event_handler_active
|
|
@@ -84,6 +88,8 @@ EXPORTS
|
|
|
84
88
|
libusb_get_device_list@8 = libusb_get_device_list
|
|
85
89
|
libusb_get_device_speed
|
|
86
90
|
libusb_get_device_speed@4 = libusb_get_device_speed
|
|
91
|
+
libusb_get_device_string
|
|
92
|
+
libusb_get_device_string@16 = libusb_get_device_string
|
|
87
93
|
libusb_get_interface_association_descriptors
|
|
88
94
|
libusb_get_interface_association_descriptors@12 = libusb_get_interface_association_descriptors
|
|
89
95
|
libusb_get_max_alt_packet_size
|
|
@@ -92,6 +98,8 @@ EXPORTS
|
|
|
92
98
|
libusb_get_max_iso_packet_size@8 = libusb_get_max_iso_packet_size
|
|
93
99
|
libusb_get_max_packet_size
|
|
94
100
|
libusb_get_max_packet_size@8 = libusb_get_max_packet_size
|
|
101
|
+
libusb_get_max_raw_io_transfer_size
|
|
102
|
+
libusb_get_max_raw_io_transfer_size@8 = libusb_get_max_raw_io_transfer_size
|
|
95
103
|
libusb_get_next_timeout
|
|
96
104
|
libusb_get_next_timeout@8 = libusb_get_next_timeout
|
|
97
105
|
libusb_get_parent
|
|
@@ -106,6 +114,8 @@ EXPORTS
|
|
|
106
114
|
libusb_get_port_numbers@12 = libusb_get_port_numbers
|
|
107
115
|
libusb_get_port_path
|
|
108
116
|
libusb_get_port_path@16 = libusb_get_port_path
|
|
117
|
+
libusb_get_session_data
|
|
118
|
+
libusb_get_session_data@4 = libusb_get_session_data
|
|
109
119
|
libusb_get_ss_endpoint_companion_descriptor
|
|
110
120
|
libusb_get_ss_endpoint_companion_descriptor@12 = libusb_get_ss_endpoint_companion_descriptor
|
|
111
121
|
libusb_get_ss_usb_device_capability_descriptor
|