usb 2.2.0 → 2.3.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +16 -2
  3. package/dist/usb/index.js +7 -16
  4. package/dist/usb/index.js.map +1 -1
  5. package/libusb/.private/ci-container-build.sh +70 -0
  6. package/libusb/AUTHORS +10 -0
  7. package/libusb/ChangeLog +13 -0
  8. package/libusb/android/examples/unrooted_android.c +3 -4
  9. package/libusb/appveyor.yml +4 -0
  10. package/libusb/configure.ac +14 -1
  11. package/libusb/libusb/Makefile.am +1 -1
  12. package/libusb/libusb/core.c +17 -5
  13. package/libusb/libusb/hotplug.c +3 -0
  14. package/libusb/libusb/io.c +32 -8
  15. package/libusb/libusb/libusb.h +7 -0
  16. package/libusb/libusb/libusbi.h +22 -4
  17. package/libusb/libusb/os/darwin_usb.c +77 -20
  18. package/libusb/libusb/os/linux_usbfs.c +1 -1
  19. package/libusb/libusb/os/windows_common.c +14 -3
  20. package/libusb/libusb/os/windows_common.h +2 -1
  21. package/libusb/libusb/os/windows_winusb.c +30 -3
  22. package/libusb/libusb/version.h +1 -1
  23. package/libusb/libusb/version_nano.h +1 -1
  24. package/libusb/tests/Makefile.am +12 -1
  25. package/libusb/tests/umockdev.c +1175 -0
  26. package/package.json +1 -1
  27. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  28. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  29. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  30. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  31. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  32. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  33. package/prebuilds/linux-ia32/node.napi.node +0 -0
  34. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  35. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  36. package/prebuilds/win32-ia32/node.napi.node +0 -0
  37. package/prebuilds/win32-x64/node.napi.node +0 -0
  38. package/tsc/usb/index.ts +5 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.3.0] - 2022-04-11
4
+
5
+ ### Changed
6
+ - Changed libusb dependency to upstream v1.0.26 - [`505`](https://github.com/node-usb/node-usb/pull/505) ([Rob Moran](https://github.com/thegecko))
7
+
8
+ - Cleaned up Windows device polling method - [`496`](https://github.com/node-usb/node-usb/pull/496) ([Alba Mendez](https://github.com/mildsunrise))
9
+
3
10
  ## [2.2.0] - 2022-03-25
4
11
 
5
12
  ### Added
package/README.md CHANGED
@@ -12,7 +12,21 @@ This is a refactoring / rewrite of Christopher Klein's [node-usb](https://github
12
12
 
13
13
  [Node.js >= v10.16.0](https://nodejs.org), which includes `npm`.
14
14
 
15
- On Windows, use [Zadig](http://zadig.akeo.ie/) to install the WinUSB driver for your USB device. Otherwise you will get `LIBUSB_ERROR_NOT_SUPPORTED` when attempting to open devices.
15
+ ## Windows
16
+
17
+ On Windows, if you get `LIBUSB_ERROR_NOT_SUPPORTED` when attempting to open your device, it's possible your device doesn't have a WinUSB driver for libusb to use.
18
+
19
+ You can install one using [Zadig](http://zadig.akeo.ie/) or another approach is to use the [UsbDK Backend](https://github.com/daynix/UsbDk) of libusb by immediately calling `usb.useUsbDkBackend()`.
20
+
21
+ Note that you cannot use multiple drivers on Windows as they get exclusive access to the device. So if you want to switch between drivers (e.g. using a printer with this software or the system), you will need to uninstall/install drivers as required.
22
+
23
+ ## Linux
24
+
25
+ On Linux, you'll need libudev to build libusb if a prebuild is not available. On Ubuntu/Debian:
26
+
27
+ ```bash
28
+ sudo apt-get install build-essential libudev-dev
29
+ ```
16
30
 
17
31
  # Installation
18
32
 
@@ -30,7 +44,7 @@ With `yarn`:
30
44
  yarn add usb
31
45
  ```
32
46
 
33
- __Note:__ the library is now written in `TypeScript`, so a separate types file is not longer required to be installed.
47
+ __Note:__ the library is now written in `TypeScript`, so a separate types file is not longer required to be installed (e.g. don't install `@types/usb`).
34
48
 
35
49
  # License
36
50
  [MIT](LICENSE.md)
package/dist/usb/index.js CHANGED
@@ -26,7 +26,7 @@ Object.getOwnPropertyNames(device_1.ExtendedDevice.prototype).forEach(function (
26
26
  var pollTimeout = 500;
27
27
  var hotplugSupported = usb._getLibusbCapability(usb.LIBUSB_CAP_HAS_HOTPLUG) > 0;
28
28
  var pollingHotplug = false;
29
- var pollDevices = [];
29
+ var pollDevices = new Set();
30
30
  var pollHotplug = function (start) {
31
31
  var e_1, _a, e_2, _b;
32
32
  if (start === void 0) { start = false; }
@@ -36,19 +36,15 @@ var pollHotplug = function (start) {
36
36
  else if (!pollingHotplug) {
37
37
  return;
38
38
  }
39
- var devices = usb.getDeviceList();
39
+ // Collect current devices
40
+ var devices = new Set(usb.getDeviceList());
40
41
  if (!start) {
41
- var _loop_1 = function (device) {
42
- var found = pollDevices.find(function (item) { return item.deviceAddress === device.deviceAddress; });
43
- if (!found) {
44
- usb.emit('attach', device);
45
- }
46
- };
47
42
  try {
48
43
  // Find attached devices
49
44
  for (var devices_1 = __values(devices), devices_1_1 = devices_1.next(); !devices_1_1.done; devices_1_1 = devices_1.next()) {
50
45
  var device = devices_1_1.value;
51
- _loop_1(device);
46
+ if (!pollDevices.has(device))
47
+ usb.emit('attach', device);
52
48
  }
53
49
  }
54
50
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -58,17 +54,12 @@ var pollHotplug = function (start) {
58
54
  }
59
55
  finally { if (e_1) throw e_1.error; }
60
56
  }
61
- var _loop_2 = function (device) {
62
- var found = devices.find(function (item) { return item.deviceAddress === device.deviceAddress; });
63
- if (!found) {
64
- usb.emit('detach', device);
65
- }
66
- };
67
57
  try {
68
58
  // Find detached devices
69
59
  for (var pollDevices_1 = __values(pollDevices), pollDevices_1_1 = pollDevices_1.next(); !pollDevices_1_1.done; pollDevices_1_1 = pollDevices_1.next()) {
70
60
  var device = pollDevices_1_1.value;
71
- _loop_2(device);
61
+ if (!devices.has(device))
62
+ usb.emit('detach', device);
72
63
  }
73
64
  }
74
65
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../tsc/usb/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../tsc/usb/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ #!/bin/bash
2
+
3
+ set -eu
4
+
5
+ # keep container around if $DEBUG is set
6
+ [ -n "${DEBUG:-}" ] || OPTS="--rm"
7
+
8
+ if type podman >/dev/null 2>&1; then
9
+ RUNC=podman
10
+ else
11
+ RUNC="sudo docker"
12
+ fi
13
+
14
+ MOUNT_MODE=":ro"
15
+
16
+ $RUNC run --interactive ${RUNC_OPTIONS:-} ${OPTS:-} --volume `pwd`:/source${MOUNT_MODE:-} ${1:-docker.io/amd64/ubuntu:rolling} /bin/bash << EOF
17
+ set -ex
18
+
19
+ # avoid meson exit code 125; https://github.com/containers/podman/issues/11540
20
+ trap '[ \$? -eq 0 ] || exit 1' EXIT
21
+
22
+ # go-faster apt
23
+ echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/90nolanguages
24
+
25
+ # upgrade
26
+ export DEBIAN_FRONTEND=noninteractive
27
+ apt-get update
28
+ apt-get install -y eatmydata
29
+ eatmydata apt-get -y --purge dist-upgrade
30
+
31
+ # install build and test dependencies
32
+ eatmydata apt-get install -y make libtool libudev-dev pkg-config umockdev libumockdev-dev
33
+
34
+ # run build as user
35
+ useradd build
36
+ su -s /bin/bash - build << EOG
37
+ set -ex
38
+
39
+ mkdir "/tmp/builddir"
40
+ cd "/tmp/builddir"
41
+
42
+ CFLAGS="-O2"
43
+
44
+ # enable extra warnings
45
+ CFLAGS+=" -Winline"
46
+ CFLAGS+=" -Wmissing-include-dirs"
47
+ CFLAGS+=" -Wnested-externs"
48
+ CFLAGS+=" -Wpointer-arith"
49
+ CFLAGS+=" -Wredundant-decls"
50
+ CFLAGS+=" -Wswitch-enum"
51
+ export CFLAGS
52
+
53
+ echo ""
54
+ echo "Configuring ..."
55
+ /source/configure --enable-examples-build --enable-tests-build
56
+
57
+ echo ""
58
+ echo "Building ..."
59
+ make -j4 -k
60
+
61
+ echo ""
62
+ echo "Running umockdev tests ..."
63
+ tests/umockdev
64
+
65
+ echo "Running stress tests ..."
66
+ tests/stress
67
+ EOG
68
+ EOF
69
+
70
+
package/libusb/AUTHORS CHANGED
@@ -41,6 +41,7 @@ Baruch Siach
41
41
  Bastien Nocera
42
42
  Bei Zhang
43
43
  Bence Csokas
44
+ Benjamin Berg
44
45
  Benjamin Dobell
45
46
  Bohdan Tymkiv
46
47
  Brent Rector
@@ -61,6 +62,7 @@ Dmitry Zakablukov
61
62
  Doug Johnston
62
63
  Evan Hunter
63
64
  Evan Miller
65
+ Fabrice Fontaine
64
66
  Federico Manzan
65
67
  Felipe Balbi
66
68
  Florian Albrechtskirchinger
@@ -100,6 +102,7 @@ Juan Cruz Viotti
100
102
  Julian Scheel
101
103
  Justin Bischoff
102
104
  Karsten Koenig
105
+ Keith Ahluwalia
103
106
  Kenjiro Tsuji
104
107
  Kimura Masaru
105
108
  Konrad Rzepecki
@@ -118,7 +121,9 @@ Mark Kuo
118
121
  Markus Heidelberg
119
122
  Martin Ettl
120
123
  Martin Koegler
124
+ Martin Ling
121
125
  Martin Thierer
126
+ Mathias Hjärtström
122
127
  Matthew Stapleton
123
128
  Matthias Bolte
124
129
  Michael Dickens
@@ -144,6 +149,7 @@ Pino Toscano
144
149
  Rob Walker
145
150
  Romain Vimont
146
151
  Roman Kalashnikov
152
+ Ryan Hileman
147
153
  Ryan Schmidt
148
154
  Saleem Rashid
149
155
  Sameeh Jubran
@@ -151,6 +157,7 @@ Sean McBride
151
157
  Sebastian Pipping
152
158
  Sebastian von Ohr
153
159
  Sergey Serb
160
+ Shawn Hoffman
154
161
  Simon Haggett
155
162
  Simon Newton
156
163
  Slash Gordon
@@ -179,6 +186,7 @@ Vladimir Beloborodov
179
186
  William Orr
180
187
  William Skellenger
181
188
  Xiaofan Chen
189
+ Yegor Yefremov
182
190
  Zhiqiang Liu
183
191
  Zoltán Kovács
184
192
  Сергей Валерьевич
@@ -186,7 +194,9 @@ Zoltán Kovács
186
194
  Роман Донченко
187
195
  jonner
188
196
  orbitcowboy
197
+ osy
189
198
  parafin
190
199
  RipleyTom
200
+ Seneral
191
201
  saur0n
192
202
  winterrace
package/libusb/ChangeLog CHANGED
@@ -1,6 +1,19 @@
1
1
  For detailed information about the changes below, please see the git log or
2
2
  visit: http://log.libusb.info
3
3
 
4
+ 2022-04-10: v1.0.26
5
+ * Fix regression with transfer free's after closing device
6
+ * Fix regression with destroyed context if API is misused
7
+ * Workaround for applications using missing default context
8
+ * Fix hotplog enumeration regression
9
+ * Fix Windows isochronous transfer regression since 1.0.24
10
+ * Fix macOS exit crash in some multi-context cases
11
+ * Build fixes for various platforms and configurations
12
+ * Fix Windows HID multi-interface product string retrieval
13
+ * Update isochronous OUT packet actual lengths on Windows
14
+ * Add interface bound checking for broken devices
15
+ * Add umockdev tests on Linux
16
+
4
17
  2022-01-31: v1.0.25
5
18
  * Linux: Fix regression with some particular devices
6
19
  * Linux: Fix regression with libusb_handle_events_timeout_completed()
@@ -24,12 +24,12 @@
24
24
 
25
25
  /*
26
26
  * This example creates a shared object which can be accessed over JNA or JNI from Java or Kotlin in Android.
27
- * Hint: If you are using Android Studio set the "Debug type" to "Java Only" to receive debug messages.
27
+ * Hint: If you are using Android Studio, set the "Debug type" to "Java Only" to receive debug messages.
28
28
  */
29
29
 
30
30
  /*
31
31
  * Usage:
32
- * First you have to connect your USB device from the Java side.
32
+ * First, you have to connect your USB device from the Java side.
33
33
  * Use the android.hardware.usb class to find the USB device, claim the interfaces, and open the usb_device_connection
34
34
  * Obtain the native File Descriptor --> usb_device_connection.getFileDescriptor()
35
35
  * Pass the received int value to the unrooted_usb_description method of this code (over JNA)
@@ -270,7 +270,7 @@ static void print_device(libusb_device *dev, libusb_device_handle *handle)
270
270
  }
271
271
 
272
272
 
273
- // fileDescriptor = is the native File Descriptor obtained in Java and transfered to native over JNA for Example.
273
+ /* fileDescriptor = the native file descriptor obtained in Java and transferred to native over JNA, for example */
274
274
  int unrooted_usb_description(int fileDescriptor)
275
275
  {
276
276
  libusb_context *ctx = NULL;
@@ -298,4 +298,3 @@ int unrooted_usb_description(int fileDescriptor)
298
298
  print_device(libusb_get_device(devh), devh);
299
299
  return r;
300
300
  }
301
-
@@ -42,6 +42,8 @@ for:
42
42
  - cmd: msbuild "%APPVEYOR_BUILD_FOLDER%\msvc\libusb_2015.sln" /m /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
43
43
  - cmd: C:\msys64\usr\bin\bash -l "%APPVEYOR_BUILD_FOLDER%\.private\appveyor_build.sh" MinGW
44
44
  - cmd: C:\cygwin\bin\bash -l "%APPVEYOR_BUILD_FOLDER%\.private\appveyor_build.sh" cygwin
45
+ after_build:
46
+ - cmd: 7z a "libusb-build_%APPVEYOR_BUILD_WORKER_IMAGE%_%PLATFORM%_%CONFIGURATION%.7z" tag_* README-build.txt %PLATFORM%\%CONFIGURATION%\dll\*.* %PLATFORM%\%CONFIGURATION%\lib\*.* %PLATFORM%\%CONFIGURATION%\examples\*.exe %PLATFORM%\%CONFIGURATION%\tests\*.exe C:\msys64\home\appveyor\libusb-MinGW-Win32 C:\cygwin\home\appveyor\libusb-cygwin-Win32
45
47
 
46
48
  -
47
49
  matrix:
@@ -56,6 +58,8 @@ for:
56
58
  - cmd: msbuild "%APPVEYOR_BUILD_FOLDER%\msvc\libusb_2015.sln" /m /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
57
59
  - cmd: C:\msys64\usr\bin\bash -l "%APPVEYOR_BUILD_FOLDER%\.private\appveyor_build.sh" MinGW
58
60
  - cmd: C:\cygwin64\bin\bash -l "%APPVEYOR_BUILD_FOLDER%\.private\appveyor_build.sh" cygwin
61
+ after_build:
62
+ - cmd: 7z a "libusb-build_%APPVEYOR_BUILD_WORKER_IMAGE%_%PLATFORM%_%CONFIGURATION%.7z" tag_* README-build.txt %PLATFORM%\%CONFIGURATION%\dll\*.* %PLATFORM%\%CONFIGURATION%\lib\*.* %PLATFORM%\%CONFIGURATION%\examples\*.exe %PLATFORM%\%CONFIGURATION%\tests\*.exe C:\msys64\home\appveyor\libusb-MinGW-x64 C:\cygwin64\home\appveyor\libusb-cygwin-x64
59
63
 
60
64
  -
61
65
  matrix:
@@ -124,6 +124,7 @@ case $host in
124
124
  platform=windows
125
125
  test "x$enable_shared" = xyes && create_import_lib=yes
126
126
  EXTRA_CFLAGS="-mwin32 -fno-omit-frame-pointer"
127
+ EXTRA_LDFLAGS="-static-libgcc"
127
128
  ;;
128
129
  *)
129
130
  AC_MSG_RESULT([Null])
@@ -152,6 +153,7 @@ if test "x$platform" = xposix; then
152
153
  AC_SEARCH_LIBS([pthread_create], [pthread],
153
154
  [test "x$ac_cv_search_pthread_create" != "xnone required" && AC_SUBST(THREAD_LIBS, [-lpthread])],
154
155
  [], [])
156
+ AC_SEARCH_LIBS([__atomic_fetch_add_4], [atomic])
155
157
  elif test "x$platform" = xwindows; then
156
158
  AC_DEFINE([PLATFORM_WINDOWS], [1], [Define to 1 if compiling for a Windows platform.])
157
159
  else
@@ -177,6 +179,14 @@ linux)
177
179
  dnl system has udev. use it or fail!
178
180
  AC_CHECK_HEADER([libudev.h], [], [AC_MSG_ERROR([udev support requested but libudev header not installed])])
179
181
  AC_CHECK_LIB([udev], [udev_new], [], [AC_MSG_ERROR([udev support requested but libudev not installed])])
182
+
183
+ # We can build umockdev tests (if available)
184
+ PKG_PROG_PKG_CONFIG
185
+ PKG_CHECK_MODULES(UMOCKDEV, umockdev-1.0 >= 0.16.0, ac_have_umockdev=yes, ac_have_umockdev=no)
186
+ PKG_CHECK_MODULES(UMOCKDEV_HOTPLUG, umockdev-1.0 >= 0.17.7, ac_umockdev_hotplug=yes, ac_umockdev_hotplug=no)
187
+ if test "x$ac_umockdev_hotplug" = xyes; then
188
+ AC_DEFINE([UMOCKDEV_HOTPLUG], [1], [UMockdev hotplug code is not racy])
189
+ fi
180
190
  else
181
191
  AC_CHECK_HEADERS([asm/types.h])
182
192
  AC_CHECK_HEADER([linux/netlink.h], [], [AC_MSG_ERROR([Linux netlink header not found])])
@@ -206,7 +216,7 @@ if test "x$platform" = xposix; then
206
216
  AC_MSG_CHECKING([whether OS X target version is 10.12 or later])
207
217
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
208
218
  #include <AvailabilityMacros.h>
209
- #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
219
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < 101200
210
220
  # error "Target OS X version is too old"
211
221
  #endif
212
222
  ], [])],
@@ -356,6 +366,7 @@ AC_ARG_ENABLE([tests-build],
356
366
 
357
367
  AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != xno])
358
368
  AM_CONDITIONAL([BUILD_TESTS], [test "x$build_tests" != xno])
369
+ AM_CONDITIONAL([BUILD_UMOCKDEV_TEST], [test "x$ac_have_umockdev" = xyes -a "x$log_enabled" != xno])
359
370
  AM_CONDITIONAL([CREATE_IMPORT_LIB], [test "x$create_import_lib" = xyes])
360
371
  AM_CONDITIONAL([OS_DARWIN], [test "x$backend" = xdarwin])
361
372
  AM_CONDITIONAL([OS_HAIKU], [test "x$backend" = xhaiku])
@@ -393,6 +404,8 @@ AC_SUBST(AM_CXXFLAGS)
393
404
 
394
405
  AC_SUBST(LT_LDFLAGS)
395
406
 
407
+ AC_SUBST([EXTRA_LDFLAGS])
408
+
396
409
  dnl set name of html output directory for doxygen
397
410
  AC_SUBST(DOXYGEN_HTMLDIR, [api-1.0])
398
411
 
@@ -80,7 +80,7 @@ all-local: .libs/libusb-1.0.dll.a
80
80
  endif
81
81
  endif
82
82
 
83
- libusb_1_0_la_LDFLAGS = $(LT_LDFLAGS)
83
+ libusb_1_0_la_LDFLAGS = $(LT_LDFLAGS) $(EXTRA_LDFLAGS)
84
84
  libusb_1_0_la_SOURCES = libusbi.h version.h version_nano.h \
85
85
  core.c descriptor.c hotplug.c io.c strerror.c sync.c \
86
86
  $(PLATFORM_SRC) $(OS_SRC)
@@ -41,6 +41,7 @@ static libusb_log_cb log_handler;
41
41
  #endif
42
42
 
43
43
  struct libusb_context *usbi_default_context;
44
+ struct libusb_context *usbi_fallback_context;
44
45
  static int default_context_refcnt;
45
46
  static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
46
47
  static struct usbi_option default_context_options[LIBUSB_OPTION_MAX];
@@ -2284,7 +2285,7 @@ int API_EXPORTED libusb_init(libusb_context **ctx)
2284
2285
 
2285
2286
  usbi_mutex_static_lock(&default_context_lock);
2286
2287
 
2287
- if (!ctx && usbi_default_context) {
2288
+ if (!ctx && default_context_refcnt > 0) {
2288
2289
  usbi_dbg(usbi_default_context, "reusing default context");
2289
2290
  default_context_refcnt++;
2290
2291
  usbi_mutex_static_unlock(&default_context_lock);
@@ -2346,17 +2347,24 @@ int API_EXPORTED libusb_init(libusb_context **ctx)
2346
2347
  list_add(&_ctx->list, &active_contexts_list);
2347
2348
  usbi_mutex_static_unlock(&active_contexts_lock);
2348
2349
 
2349
- usbi_hotplug_init(_ctx);
2350
-
2351
2350
  if (usbi_backend.init) {
2352
2351
  r = usbi_backend.init(_ctx);
2353
2352
  if (r)
2354
2353
  goto err_io_exit;
2355
2354
  }
2356
2355
 
2357
- if (ctx)
2356
+ /* Initialize hotplug after the initial enumeration is done. */
2357
+ usbi_hotplug_init(_ctx);
2358
+
2359
+ if (ctx) {
2358
2360
  *ctx = _ctx;
2359
2361
 
2362
+ if (!usbi_fallback_context) {
2363
+ usbi_fallback_context = _ctx;
2364
+ usbi_warn(usbi_fallback_context, "installing new context as implicit default");
2365
+ }
2366
+ }
2367
+
2360
2368
  usbi_mutex_static_unlock(&default_context_lock);
2361
2369
 
2362
2370
  return 0;
@@ -2429,6 +2437,8 @@ void API_EXPORTED libusb_exit(libusb_context *ctx)
2429
2437
 
2430
2438
  if (!ctx)
2431
2439
  usbi_default_context = NULL;
2440
+ if (ctx == usbi_fallback_context)
2441
+ usbi_fallback_context = NULL;
2432
2442
 
2433
2443
  usbi_mutex_static_unlock(&default_context_lock);
2434
2444
 
@@ -2441,6 +2451,7 @@ void API_EXPORTED libusb_exit(libusb_context *ctx)
2441
2451
  for_each_device(_ctx, dev) {
2442
2452
  usbi_warn(_ctx, "device %d.%d still referenced",
2443
2453
  dev->bus_number, dev->device_address);
2454
+ DEVICE_CTX(dev) = NULL;
2444
2455
  }
2445
2456
 
2446
2457
  if (!list_empty(&_ctx->open_devs))
@@ -2574,7 +2585,8 @@ static void log_v(struct libusb_context *ctx, enum libusb_log_level level,
2574
2585
  #else
2575
2586
  enum libusb_log_level ctx_level;
2576
2587
 
2577
- ctx = usbi_get_context(ctx);
2588
+ ctx = ctx ? ctx : usbi_default_context;
2589
+ ctx = ctx ? ctx : usbi_fallback_context;
2578
2590
  if (ctx)
2579
2591
  ctx_level = ctx->debug;
2580
2592
  else
@@ -171,6 +171,9 @@ void usbi_hotplug_exit(struct libusb_context *ctx)
171
171
  if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
172
172
  return;
173
173
 
174
+ if (!usbi_atomic_load(&ctx->hotplug_ready))
175
+ return;
176
+
174
177
  /* free all registered hotplug callbacks */
175
178
  for_each_hotplug_cb_safe(ctx, hotplug_cb, next_cb) {
176
179
  list_del(&hotplug_cb->list);
@@ -1344,6 +1344,8 @@ void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer)
1344
1344
 
1345
1345
  itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
1346
1346
  usbi_mutex_destroy(&itransfer->lock);
1347
+ if (itransfer->dev)
1348
+ libusb_unref_device(itransfer->dev);
1347
1349
 
1348
1350
  priv_size = PTR_ALIGN(usbi_backend.transfer_priv_size);
1349
1351
  ptr = (unsigned char *)itransfer - priv_size;
@@ -1489,9 +1491,15 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
1489
1491
  {
1490
1492
  struct usbi_transfer *itransfer =
1491
1493
  LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
1492
- struct libusb_context *ctx = TRANSFER_CTX(transfer);
1494
+ struct libusb_context *ctx;
1493
1495
  int r;
1494
1496
 
1497
+ assert(transfer->dev_handle);
1498
+ if (itransfer->dev)
1499
+ libusb_unref_device(itransfer->dev);
1500
+ itransfer->dev = libusb_ref_device(transfer->dev_handle->dev);
1501
+
1502
+ ctx = HANDLE_CTX(transfer->dev_handle);
1495
1503
  usbi_dbg(ctx, "transfer %p", transfer);
1496
1504
 
1497
1505
  /*
@@ -1551,8 +1559,6 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
1551
1559
  r = usbi_backend.submit_transfer(itransfer);
1552
1560
  if (r == LIBUSB_SUCCESS) {
1553
1561
  itransfer->state_flags |= USBI_TRANSFER_IN_FLIGHT;
1554
- /* keep a reference to this device */
1555
- libusb_ref_device(transfer->dev_handle->dev);
1556
1562
  }
1557
1563
  usbi_mutex_unlock(&itransfer->lock);
1558
1564
 
@@ -1570,6 +1576,26 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
1570
1576
  * \ref libusb_transfer_status::LIBUSB_TRANSFER_CANCELLED
1571
1577
  * "LIBUSB_TRANSFER_CANCELLED."
1572
1578
  *
1579
+ * This function behaves differently on Darwin-based systems (macOS and iOS):
1580
+ *
1581
+ * - Calling this function for one transfer will cause all transfers on the
1582
+ * same endpoint to be cancelled. Your callback function will be invoked with
1583
+ * a transfer status of
1584
+ * \ref libusb_transfer_status::LIBUSB_TRANSFER_CANCELLED
1585
+ * "LIBUSB_TRANSFER_CANCELLED" for each transfer that was cancelled.
1586
+
1587
+ * - Calling this function also sends a \c ClearFeature(ENDPOINT_HALT) request
1588
+ * for the transfer's endpoint. If the device does not handle this request
1589
+ * correctly, the data toggle bits for the endpoint can be left out of sync
1590
+ * between host and device, which can have unpredictable results when the
1591
+ * next data is sent on the endpoint, including data being silently lost.
1592
+ * A call to \ref libusb_clear_halt will not resolve this situation, since
1593
+ * that function uses the same request. Therefore, if your program runs on
1594
+ * Darwin and uses a device that does not correctly implement
1595
+ * \c ClearFeature(ENDPOINT_HALT) requests, it may only be safe to cancel
1596
+ * transfers when followed by a device reset using
1597
+ * \ref libusb_reset_device.
1598
+ *
1573
1599
  * \param transfer the transfer to cancel
1574
1600
  * \returns 0 on success
1575
1601
  * \returns LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress,
@@ -1659,7 +1685,6 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
1659
1685
  {
1660
1686
  struct libusb_transfer *transfer =
1661
1687
  USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1662
- struct libusb_device_handle *dev_handle = transfer->dev_handle;
1663
1688
  struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
1664
1689
  uint8_t flags;
1665
1690
  int r;
@@ -1693,7 +1718,6 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
1693
1718
  * this point. */
1694
1719
  if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
1695
1720
  libusb_free_transfer(transfer);
1696
- libusb_unref_device(dev_handle->dev);
1697
1721
  return r;
1698
1722
  }
1699
1723
 
@@ -1727,10 +1751,10 @@ int usbi_handle_transfer_cancellation(struct usbi_transfer *itransfer)
1727
1751
  * function will be called the next time an event handler runs. */
1728
1752
  void usbi_signal_transfer_completion(struct usbi_transfer *itransfer)
1729
1753
  {
1730
- libusb_device_handle *dev_handle = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)->dev_handle;
1754
+ struct libusb_device *dev = itransfer->dev;
1731
1755
 
1732
- if (dev_handle) {
1733
- struct libusb_context *ctx = HANDLE_CTX(dev_handle);
1756
+ if (dev) {
1757
+ struct libusb_context *ctx = DEVICE_CTX(dev);
1734
1758
  unsigned int event_flags;
1735
1759
 
1736
1760
  usbi_mutex_lock(&ctx->event_data_lock);
@@ -26,6 +26,9 @@
26
26
  #define LIBUSB_H
27
27
 
28
28
  #if defined(_MSC_VER)
29
+ #pragma warning(push)
30
+ /* Disable: warning C4200: nonstandard extension used : zero-sized array in struct/union */
31
+ #pragma warning(disable:4200)
29
32
  /* on MS environments, the inline keyword is available in C++ only */
30
33
  #if !defined(__cplusplus)
31
34
  #define inline __inline
@@ -2128,6 +2131,10 @@ enum libusb_option {
2128
2131
 
2129
2132
  int LIBUSB_CALL libusb_set_option(libusb_context *ctx, enum libusb_option option, ...);
2130
2133
 
2134
+ #ifdef _MSC_VER
2135
+ #pragma warning(pop)
2136
+ #endif
2137
+
2131
2138
  #if defined(__cplusplus)
2132
2139
  }
2133
2140
  #endif
@@ -329,10 +329,11 @@ void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,
329
329
  #endif /* ENABLE_LOGGING */
330
330
 
331
331
  #define DEVICE_CTX(dev) ((dev)->ctx)
332
- #define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev))
333
- #define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle))
332
+ #define HANDLE_CTX(handle) ((handle) ? DEVICE_CTX((handle)->dev) : NULL)
334
333
  #define ITRANSFER_CTX(itransfer) \
335
- (TRANSFER_CTX(USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)))
334
+ ((itransfer)->dev ? DEVICE_CTX((itransfer)->dev) : NULL)
335
+ #define TRANSFER_CTX(transfer) \
336
+ (ITRANSFER_CTX(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)))
336
337
 
337
338
  #define IS_EPIN(ep) (0 != ((ep) & LIBUSB_ENDPOINT_IN))
338
339
  #define IS_EPOUT(ep) (!IS_EPIN(ep))
@@ -435,13 +436,26 @@ struct libusb_context {
435
436
  };
436
437
 
437
438
  extern struct libusb_context *usbi_default_context;
439
+ extern struct libusb_context *usbi_fallback_context;
438
440
 
439
441
  extern struct list_head active_contexts_list;
440
442
  extern usbi_mutex_static_t active_contexts_lock;
441
443
 
442
444
  static inline struct libusb_context *usbi_get_context(struct libusb_context *ctx)
443
445
  {
444
- return ctx ? ctx : usbi_default_context;
446
+ static int warned = 0;
447
+
448
+ if (!ctx) {
449
+ ctx = usbi_default_context;
450
+ }
451
+ if (!ctx) {
452
+ ctx = usbi_fallback_context;
453
+ if (ctx && warned == 0) {
454
+ usbi_err(ctx, "API misuse! Using non-default context as implicit default.");
455
+ warned = 1;
456
+ }
457
+ }
458
+ return ctx;
445
459
  }
446
460
 
447
461
  enum usbi_event_flags {
@@ -562,6 +576,10 @@ struct usbi_transfer {
562
576
  uint32_t state_flags; /* Protected by usbi_transfer->lock */
563
577
  uint32_t timeout_flags; /* Protected by the flying_stransfers_lock */
564
578
 
579
+ /* The device reference is held until destruction for logging
580
+ * even after dev_handle is set to NULL. */
581
+ struct libusb_device *dev;
582
+
565
583
  /* this lock is held during libusb_submit_transfer() and
566
584
  * libusb_cancel_transfer() (allowing the OS backend to prevent duplicate
567
585
  * cancellation, submission-during-cancellation, etc). the OS backend