usb 2.1.2 → 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 (288) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +20 -2
  3. package/dist/index.d.ts +2 -1
  4. package/dist/index.js +3 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/usb/bindings.d.ts +4 -0
  7. package/dist/usb/device.js +5 -0
  8. package/dist/usb/device.js.map +1 -1
  9. package/dist/usb/index.js +7 -16
  10. package/dist/usb/index.js.map +1 -1
  11. package/dist/webusb/webusb-device.d.ts +2 -1
  12. package/dist/webusb/webusb-device.js +21 -14
  13. package/dist/webusb/webusb-device.js.map +1 -1
  14. package/libusb/.gitattributes +2 -6
  15. package/libusb/.private/appveyor_build.sh +22 -0
  16. package/libusb/.private/bm.sh +1 -1
  17. package/libusb/.private/ci-build.sh +67 -0
  18. package/libusb/.private/ci-container-build.sh +70 -0
  19. package/libusb/.private/post-rewrite.sh +5 -1
  20. package/libusb/.private/pre-commit.sh +5 -1
  21. package/libusb/.private/wbs.txt +4 -19
  22. package/libusb/.travis.yml +32 -23
  23. package/libusb/AUTHORS +86 -3
  24. package/libusb/ChangeLog +54 -3
  25. package/libusb/INSTALL_WIN.txt +22 -44
  26. package/libusb/Makefile.am +32 -10
  27. package/libusb/{README.md → README} +2 -2
  28. package/libusb/README.git +3 -3
  29. package/libusb/Xcode/common.xcconfig +23 -19
  30. package/libusb/Xcode/config.h +25 -13
  31. package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +511 -109
  32. package/libusb/android/README +90 -54
  33. package/libusb/android/config.h +23 -43
  34. package/libusb/android/examples/unrooted_android.c +300 -0
  35. package/libusb/android/examples/unrooted_android.h +36 -0
  36. package/libusb/android/jni/Android.mk +1 -1
  37. package/libusb/android/jni/Application.mk +16 -0
  38. package/libusb/android/jni/examples.mk +63 -29
  39. package/libusb/android/jni/libusb.mk +14 -8
  40. package/libusb/android/jni/tests.mk +13 -24
  41. package/libusb/appveyor.yml +73 -30
  42. package/libusb/autogen.sh +5 -3
  43. package/libusb/bootstrap.sh +6 -2
  44. package/libusb/configure.ac +314 -227
  45. package/libusb/doc/Makefile.in +22 -0
  46. package/libusb/doc/doxygen.cfg.in +460 -223
  47. package/libusb/examples/Makefile.am +6 -13
  48. package/libusb/examples/dpfp.c +276 -73
  49. package/libusb/examples/ezusb.c +18 -8
  50. package/libusb/examples/ezusb.h +6 -17
  51. package/libusb/examples/fxload.c +4 -5
  52. package/libusb/examples/hotplugtest.c +1 -1
  53. package/libusb/examples/sam3u_benchmark.c +59 -24
  54. package/libusb/examples/testlibusb.c +138 -104
  55. package/libusb/examples/xusb.c +26 -22
  56. package/libusb/libusb/Makefile.am +57 -70
  57. package/libusb/libusb/Makefile.am.extra +26 -0
  58. package/libusb/libusb/core.c +432 -423
  59. package/libusb/libusb/descriptor.c +365 -419
  60. package/libusb/libusb/hotplug.c +200 -104
  61. package/libusb/libusb/io.c +522 -535
  62. package/libusb/libusb/libusb-1.0.def +7 -3
  63. package/libusb/libusb/libusb-1.0.rc +1 -9
  64. package/libusb/libusb/libusb.h +302 -226
  65. package/libusb/libusb/libusbi.h +607 -316
  66. package/libusb/libusb/os/darwin_usb.c +703 -329
  67. package/libusb/libusb/os/darwin_usb.h +39 -15
  68. package/libusb/libusb/os/events_posix.c +300 -0
  69. package/libusb/libusb/os/events_posix.h +59 -0
  70. package/libusb/libusb/os/events_windows.c +214 -0
  71. package/libusb/{msvc/missing.h → libusb/os/events_windows.h} +25 -11
  72. package/libusb/libusb/os/haiku_pollfs.cpp +14 -9
  73. package/libusb/libusb/os/haiku_usb.h +12 -12
  74. package/libusb/libusb/os/haiku_usb_backend.cpp +36 -37
  75. package/libusb/libusb/os/haiku_usb_raw.cpp +80 -116
  76. package/libusb/libusb/os/linux_netlink.c +55 -63
  77. package/libusb/libusb/os/linux_udev.c +61 -69
  78. package/libusb/libusb/os/linux_usbfs.c +926 -1015
  79. package/libusb/libusb/os/linux_usbfs.h +74 -57
  80. package/libusb/libusb/os/netbsd_usb.c +103 -168
  81. package/libusb/libusb/os/null_usb.c +111 -0
  82. package/libusb/libusb/os/openbsd_usb.c +71 -120
  83. package/libusb/libusb/os/sunos_usb.c +289 -375
  84. package/libusb/libusb/os/sunos_usb.h +0 -1
  85. package/libusb/libusb/os/threads_posix.c +81 -32
  86. package/libusb/libusb/os/threads_posix.h +19 -23
  87. package/libusb/libusb/os/threads_windows.c +9 -95
  88. package/libusb/libusb/os/threads_windows.h +33 -31
  89. package/libusb/libusb/os/windows_common.c +915 -0
  90. package/libusb/libusb/os/windows_common.h +330 -42
  91. package/libusb/libusb/os/windows_usbdk.c +161 -267
  92. package/libusb/libusb/os/windows_usbdk.h +5 -2
  93. package/libusb/libusb/os/windows_winusb.c +1355 -1192
  94. package/libusb/libusb/os/windows_winusb.h +167 -167
  95. package/libusb/libusb/strerror.c +20 -30
  96. package/libusb/libusb/sync.c +20 -21
  97. package/libusb/libusb/version.h +1 -1
  98. package/libusb/libusb/version_nano.h +1 -1
  99. package/libusb/msvc/.gitattributes +3 -0
  100. package/libusb/msvc/config.h +27 -20
  101. package/libusb/msvc/{hotplugtest_2012.vcxproj → dpfp_2013.vcxproj} +14 -10
  102. package/libusb/msvc/dpfp_2013.vcxproj.filters +26 -0
  103. package/libusb/msvc/{listdevs_2010.vcxproj → dpfp_2015.vcxproj} +14 -9
  104. package/libusb/msvc/dpfp_2015.vcxproj.filters +26 -0
  105. package/libusb/msvc/dpfp_2017.vcxproj +106 -0
  106. package/libusb/msvc/dpfp_2017.vcxproj.filters +26 -0
  107. package/libusb/msvc/dpfp_2019.vcxproj +106 -0
  108. package/libusb/msvc/dpfp_2019.vcxproj.filters +26 -0
  109. package/libusb/msvc/dpfp_threaded_2013.vcxproj +87 -0
  110. package/libusb/msvc/dpfp_threaded_2013.vcxproj.filters +26 -0
  111. package/libusb/msvc/dpfp_threaded_2015.vcxproj +87 -0
  112. package/libusb/msvc/dpfp_threaded_2015.vcxproj.filters +26 -0
  113. package/libusb/msvc/dpfp_threaded_2017.vcxproj +106 -0
  114. package/libusb/msvc/dpfp_threaded_2017.vcxproj.filters +26 -0
  115. package/libusb/msvc/{fxload_2012.vcxproj → dpfp_threaded_2019.vcxproj} +32 -17
  116. package/libusb/msvc/dpfp_threaded_2019.vcxproj.filters +26 -0
  117. package/libusb/msvc/fxload_2013.vcxproj +6 -3
  118. package/libusb/msvc/fxload_2013.vcxproj.filters +35 -0
  119. package/libusb/msvc/fxload_2015.vcxproj +6 -3
  120. package/libusb/msvc/fxload_2015.vcxproj.filters +35 -0
  121. package/libusb/msvc/fxload_2017.vcxproj +6 -7
  122. package/libusb/msvc/fxload_2017.vcxproj.filters +35 -0
  123. package/libusb/msvc/{fxload_2010.vcxproj → fxload_2019.vcxproj} +29 -6
  124. package/libusb/msvc/fxload_2019.vcxproj.filters +35 -0
  125. package/libusb/{examples → msvc}/getopt/getopt.c +0 -0
  126. package/libusb/{examples → msvc}/getopt/getopt.h +0 -0
  127. package/libusb/{examples → msvc}/getopt/getopt1.c +0 -0
  128. package/libusb/msvc/getopt_2013.vcxproj +4 -5
  129. package/libusb/msvc/getopt_2013.vcxproj.filters +26 -0
  130. package/libusb/msvc/getopt_2015.vcxproj +4 -4
  131. package/libusb/msvc/getopt_2015.vcxproj.filters +26 -0
  132. package/libusb/msvc/getopt_2017.vcxproj +4 -10
  133. package/libusb/msvc/getopt_2017.vcxproj.filters +26 -0
  134. package/libusb/msvc/{getopt_2012.vcxproj → getopt_2019.vcxproj} +25 -6
  135. package/libusb/msvc/getopt_2019.vcxproj.filters +26 -0
  136. package/libusb/msvc/hotplugtest_2013.vcxproj +6 -3
  137. package/libusb/msvc/hotplugtest_2013.vcxproj.filters +23 -0
  138. package/libusb/msvc/hotplugtest_2015.vcxproj +6 -3
  139. package/libusb/msvc/hotplugtest_2015.vcxproj.filters +23 -0
  140. package/libusb/msvc/hotplugtest_2017.vcxproj +6 -7
  141. package/libusb/msvc/hotplugtest_2017.vcxproj.filters +23 -0
  142. package/libusb/msvc/hotplugtest_2019.vcxproj +105 -0
  143. package/libusb/msvc/hotplugtest_2019.vcxproj.filters +23 -0
  144. package/libusb/msvc/libusb_2013.sln +50 -20
  145. package/libusb/msvc/libusb_2015.sln +51 -21
  146. package/libusb/msvc/libusb_2017.sln +90 -36
  147. package/libusb/msvc/libusb_2019.sln +240 -0
  148. package/libusb/msvc/libusb_dll_2013.vcxproj +6 -9
  149. package/libusb/msvc/libusb_dll_2013.vcxproj.filters +94 -0
  150. package/libusb/msvc/libusb_dll_2015.vcxproj +6 -8
  151. package/libusb/msvc/libusb_dll_2015.vcxproj.filters +94 -0
  152. package/libusb/msvc/libusb_dll_2017.vcxproj +6 -16
  153. package/libusb/msvc/libusb_dll_2017.vcxproj.filters +94 -0
  154. package/libusb/msvc/{libusb_dll_2010.vcxproj → libusb_dll_2019.vcxproj} +27 -9
  155. package/libusb/msvc/libusb_dll_2019.vcxproj.filters +94 -0
  156. package/libusb/msvc/libusb_static_2013.vcxproj +5 -9
  157. package/libusb/msvc/libusb_static_2013.vcxproj.filters +80 -0
  158. package/libusb/msvc/libusb_static_2015.vcxproj +5 -8
  159. package/libusb/msvc/libusb_static_2015.vcxproj.filters +80 -0
  160. package/libusb/msvc/libusb_static_2017.vcxproj +5 -8
  161. package/libusb/msvc/libusb_static_2017.vcxproj.filters +80 -0
  162. package/libusb/msvc/{libusb_static_2010.vcxproj → libusb_static_2019.vcxproj} +26 -9
  163. package/libusb/msvc/libusb_static_2019.vcxproj.filters +80 -0
  164. package/libusb/msvc/listdevs_2013.vcxproj +6 -3
  165. package/libusb/msvc/listdevs_2013.vcxproj.filters +23 -0
  166. package/libusb/msvc/listdevs_2015.vcxproj +6 -3
  167. package/libusb/msvc/listdevs_2015.vcxproj.filters +23 -0
  168. package/libusb/msvc/listdevs_2017.vcxproj +6 -7
  169. package/libusb/msvc/listdevs_2017.vcxproj.filters +23 -0
  170. package/libusb/msvc/listdevs_2019.vcxproj +105 -0
  171. package/libusb/msvc/listdevs_2019.vcxproj.filters +23 -0
  172. package/libusb/msvc/{listdevs_2012.vcxproj → sam3u_benchmark_2013.vcxproj} +13 -9
  173. package/libusb/msvc/sam3u_benchmark_2013.vcxproj.filters +26 -0
  174. package/libusb/msvc/{hotplugtest_2010.vcxproj → sam3u_benchmark_2015.vcxproj} +13 -8
  175. package/libusb/msvc/sam3u_benchmark_2015.vcxproj.filters +26 -0
  176. package/libusb/msvc/sam3u_benchmark_2017.vcxproj +106 -0
  177. package/libusb/msvc/sam3u_benchmark_2017.vcxproj.filters +26 -0
  178. package/libusb/msvc/sam3u_benchmark_2019.vcxproj +106 -0
  179. package/libusb/msvc/sam3u_benchmark_2019.vcxproj.filters +26 -0
  180. package/libusb/msvc/stress_2013.vcxproj +4 -2
  181. package/libusb/msvc/stress_2013.vcxproj.filters +32 -0
  182. package/libusb/msvc/stress_2015.vcxproj +4 -2
  183. package/libusb/msvc/stress_2015.vcxproj.filters +32 -0
  184. package/libusb/msvc/stress_2017.vcxproj +4 -6
  185. package/libusb/msvc/stress_2017.vcxproj.filters +32 -0
  186. package/libusb/msvc/{stress_2010.vcxproj → stress_2019.vcxproj} +26 -4
  187. package/libusb/msvc/stress_2019.vcxproj.filters +32 -0
  188. package/libusb/msvc/testlibusb_2013.vcxproj +6 -3
  189. package/libusb/msvc/testlibusb_2013.vcxproj.filters +23 -0
  190. package/libusb/msvc/testlibusb_2015.vcxproj +6 -3
  191. package/libusb/msvc/testlibusb_2015.vcxproj.filters +23 -0
  192. package/libusb/msvc/testlibusb_2017.vcxproj +6 -7
  193. package/libusb/msvc/testlibusb_2017.vcxproj.filters +23 -0
  194. package/libusb/msvc/{testlibusb_2010.vcxproj → testlibusb_2019.vcxproj} +28 -5
  195. package/libusb/msvc/testlibusb_2019.vcxproj.filters +23 -0
  196. package/libusb/msvc/xusb_2013.vcxproj +6 -3
  197. package/libusb/msvc/xusb_2013.vcxproj.filters +23 -0
  198. package/libusb/msvc/xusb_2015.vcxproj +6 -3
  199. package/libusb/msvc/xusb_2015.vcxproj.filters +23 -0
  200. package/libusb/msvc/xusb_2017.vcxproj +6 -7
  201. package/libusb/msvc/xusb_2017.vcxproj.filters +23 -0
  202. package/libusb/msvc/{xusb_2010.vcxproj → xusb_2019.vcxproj} +28 -5
  203. package/libusb/msvc/xusb_2019.vcxproj.filters +23 -0
  204. package/libusb/tests/Makefile.am +13 -1
  205. package/libusb/tests/libusb_testlib.h +12 -43
  206. package/libusb/tests/stress.c +59 -50
  207. package/libusb/tests/testlib.c +78 -171
  208. package/libusb/tests/umockdev.c +1175 -0
  209. package/libusb.gypi +10 -11
  210. package/package.json +2 -2
  211. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  212. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  213. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  214. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  215. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  216. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  217. package/prebuilds/linux-ia32/node.napi.node +0 -0
  218. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  219. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  220. package/prebuilds/win32-ia32/node.napi.node +0 -0
  221. package/prebuilds/win32-x64/node.napi.node +0 -0
  222. package/src/device.cc +12 -7
  223. package/src/node_usb.cc +10 -0
  224. package/test/usb.coffee +6 -0
  225. package/tsc/index.ts +2 -0
  226. package/tsc/usb/bindings.ts +5 -0
  227. package/tsc/usb/device.ts +6 -0
  228. package/tsc/usb/index.ts +5 -8
  229. package/tsc/webusb/webusb-device.ts +12 -8
  230. package/libusb/.private/bd.cmd +0 -89
  231. package/libusb/.private/bwince.cmd +0 -57
  232. package/libusb/.private/wbs_wince.txt +0 -42
  233. package/libusb/Brewfile +0 -4
  234. package/libusb/appveyor_cygwin.bat +0 -11
  235. package/libusb/appveyor_minGW.bat +0 -19
  236. package/libusb/doc/Makefile.am +0 -9
  237. package/libusb/examples/dpfp_threaded.c +0 -557
  238. package/libusb/libusb/hotplug.h +0 -99
  239. package/libusb/libusb/os/poll_posix.c +0 -84
  240. package/libusb/libusb/os/poll_posix.h +0 -14
  241. package/libusb/libusb/os/poll_windows.c +0 -447
  242. package/libusb/libusb/os/poll_windows.h +0 -98
  243. package/libusb/libusb/os/wince_usb.c +0 -888
  244. package/libusb/libusb/os/wince_usb.h +0 -126
  245. package/libusb/libusb/os/windows_nt_common.c +0 -1010
  246. package/libusb/libusb/os/windows_nt_common.h +0 -110
  247. package/libusb/libusb/os/windows_nt_shared_types.h +0 -147
  248. package/libusb/msvc/appveyor.bat +0 -27
  249. package/libusb/msvc/ddk_build.cmd +0 -219
  250. package/libusb/msvc/errno.h +0 -102
  251. package/libusb/msvc/fxload_sources +0 -23
  252. package/libusb/msvc/getopt_2005.vcproj +0 -288
  253. package/libusb/msvc/getopt_2010.vcxproj +0 -72
  254. package/libusb/msvc/getopt_sources +0 -24
  255. package/libusb/msvc/hotplugtest_sources +0 -20
  256. package/libusb/msvc/inttypes.h +0 -295
  257. package/libusb/msvc/libusb.dsw +0 -71
  258. package/libusb/msvc/libusb_2005.sln +0 -95
  259. package/libusb/msvc/libusb_2010.sln +0 -105
  260. package/libusb/msvc/libusb_2012.sln +0 -105
  261. package/libusb/msvc/libusb_dll.dsp +0 -194
  262. package/libusb/msvc/libusb_dll_2005.vcproj +0 -464
  263. package/libusb/msvc/libusb_dll_2012.vcxproj +0 -107
  264. package/libusb/msvc/libusb_dll_wince.vcproj +0 -1251
  265. package/libusb/msvc/libusb_sources +0 -43
  266. package/libusb/msvc/libusb_static.dsp +0 -174
  267. package/libusb/msvc/libusb_static_2005.vcproj +0 -390
  268. package/libusb/msvc/libusb_static_2012.vcxproj +0 -98
  269. package/libusb/msvc/libusb_static_wince.vcproj +0 -1179
  270. package/libusb/msvc/libusb_wince.sln +0 -246
  271. package/libusb/msvc/listdevs.dsp +0 -103
  272. package/libusb/msvc/listdevs_2005.vcproj +0 -360
  273. package/libusb/msvc/listdevs_sources +0 -20
  274. package/libusb/msvc/listdevs_wince.vcproj +0 -1120
  275. package/libusb/msvc/missing.c +0 -80
  276. package/libusb/msvc/stdint.h +0 -256
  277. package/libusb/msvc/stress_2005.vcproj +0 -390
  278. package/libusb/msvc/stress_2012.vcxproj +0 -87
  279. package/libusb/msvc/stress_sources +0 -21
  280. package/libusb/msvc/stress_wince.vcproj +0 -1128
  281. package/libusb/msvc/testlibusb_2012.vcxproj +0 -83
  282. package/libusb/msvc/testlibusb_sources +0 -20
  283. package/libusb/msvc/xusb.dsp +0 -102
  284. package/libusb/msvc/xusb_2005.vcproj +0 -344
  285. package/libusb/msvc/xusb_2012.vcxproj +0 -83
  286. package/libusb/msvc/xusb_sources +0 -20
  287. package/libusb/msvc/xusb_wince.vcproj +0 -1120
  288. package/libusb/travis-autogen.sh +0 -39
@@ -1,7 +1,7 @@
1
1
  /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
2
2
  /*
3
3
  * Hotplug functions for libusb
4
- * Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
4
+ * Copyright © 2012-2021 Nathan Hjelm <hjelmn@mac.com>
5
5
  * Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
6
6
  *
7
7
  * This library is free software; you can redistribute it and/or
@@ -19,19 +19,7 @@
19
19
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
20
  */
21
21
 
22
- #include <config.h>
23
-
24
- #include <errno.h>
25
- #include <stdio.h>
26
- #include <stdlib.h>
27
- #include <string.h>
28
- #ifdef HAVE_SYS_TYPES_H
29
- #include <sys/types.h>
30
- #endif
31
- #include <assert.h>
32
-
33
22
  #include "libusbi.h"
34
- #include "hotplug.h"
35
23
 
36
24
  /**
37
25
  * @defgroup libusb_hotplug Device hotplug event notification
@@ -48,7 +36,7 @@
48
36
  * Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support
49
37
  * for hotplug events on <b>some</b> platforms (you should test if your platform
50
38
  * supports hotplug notification by calling \ref libusb_has_capability() with
51
- * parameter \ref LIBUSB_CAP_HAS_HOTPLUG).
39
+ * parameter \ref LIBUSB_CAP_HAS_HOTPLUG).
52
40
  *
53
41
  * This interface allows you to request notification for the arrival and departure
54
42
  * of matching USB devices.
@@ -61,8 +49,8 @@
61
49
  * expecting additional events. Returning 0 will rearm the callback and 1 will cause
62
50
  * the callback to be deregistered. Note that when callbacks are called from
63
51
  * libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE
64
- * flag, the callback return value is ignored, iow you cannot cause a callback
65
- * to be deregistered by returning 1 when it is called from
52
+ * flag, the callback return value is ignored. In other words, you cannot cause a
53
+ * callback to be deregistered by returning 1 when it is called from
66
54
  * libusb_hotplug_register_callback().
67
55
  *
68
56
  * Callbacks for a particular context are automatically deregistered by libusb_exit().
@@ -74,7 +62,7 @@
74
62
  * A hotplug event can listen for either or both of these events.
75
63
  *
76
64
  * Note: If you receive notification that a device has left and you have any
77
- * a libusb_device_handles for the device it is up to you to call libusb_close()
65
+ * libusb_device_handles for the device it is up to you to call libusb_close()
78
66
  * on each device handle to free up any remaining resources associated with the device.
79
67
  * Once a device has left any libusb_device_handle associated with the device
80
68
  * are invalid and will remain so even if the device comes back.
@@ -154,9 +142,80 @@ int main (void) {
154
142
  \endcode
155
143
  */
156
144
 
157
- static int usbi_hotplug_match_cb(struct libusb_context *ctx,
158
- struct libusb_device *dev, libusb_hotplug_event event,
159
- struct libusb_hotplug_callback *hotplug_cb)
145
+ #define VALID_HOTPLUG_EVENTS \
146
+ (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | \
147
+ LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
148
+
149
+ #define VALID_HOTPLUG_FLAGS \
150
+ (LIBUSB_HOTPLUG_ENUMERATE)
151
+
152
+ void usbi_hotplug_init(struct libusb_context *ctx)
153
+ {
154
+ /* check for hotplug support */
155
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
156
+ return;
157
+
158
+ usbi_mutex_init(&ctx->hotplug_cbs_lock);
159
+ list_init(&ctx->hotplug_cbs);
160
+ ctx->next_hotplug_cb_handle = 1;
161
+ usbi_atomic_store(&ctx->hotplug_ready, 1);
162
+ }
163
+
164
+ void usbi_hotplug_exit(struct libusb_context *ctx)
165
+ {
166
+ struct usbi_hotplug_callback *hotplug_cb, *next_cb;
167
+ struct usbi_hotplug_message *msg;
168
+ struct libusb_device *dev, *next_dev;
169
+
170
+ /* check for hotplug support */
171
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
172
+ return;
173
+
174
+ if (!usbi_atomic_load(&ctx->hotplug_ready))
175
+ return;
176
+
177
+ /* free all registered hotplug callbacks */
178
+ for_each_hotplug_cb_safe(ctx, hotplug_cb, next_cb) {
179
+ list_del(&hotplug_cb->list);
180
+ free(hotplug_cb);
181
+ }
182
+
183
+ /* free all pending hotplug messages */
184
+ while (!list_empty(&ctx->hotplug_msgs)) {
185
+ msg = list_first_entry(&ctx->hotplug_msgs, struct usbi_hotplug_message, list);
186
+
187
+ /* if the device left, the message holds a reference
188
+ * and we must drop it */
189
+ if (msg->event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
190
+ libusb_unref_device(msg->device);
191
+
192
+ list_del(&msg->list);
193
+ free(msg);
194
+ }
195
+
196
+ /* free all discovered devices. due to parent references loop until no devices are freed. */
197
+ for_each_device_safe(ctx, dev, next_dev) {
198
+ /* remove the device from the usb_devs list only if there are no
199
+ * references held, otherwise leave it on the list so that a
200
+ * warning message will be shown */
201
+ if (usbi_atomic_load(&dev->refcnt) == 1) {
202
+ list_del(&dev->list);
203
+ }
204
+ if (dev->parent_dev && usbi_atomic_load(&dev->parent_dev->refcnt) == 1) {
205
+ /* the parent was before this device in the list and will be released.
206
+ remove it from the list. this is safe as parent_dev can not be
207
+ equal to next_dev. */
208
+ assert (dev->parent_dev != next_dev);
209
+ list_del(&dev->parent_dev->list);
210
+ }
211
+ libusb_unref_device(dev);
212
+ }
213
+
214
+ usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
215
+ }
216
+
217
+ static int usbi_hotplug_match_cb(struct libusb_device *dev,
218
+ libusb_hotplug_event event, struct usbi_hotplug_callback *hotplug_cb)
160
219
  {
161
220
  if (!(hotplug_cb->flags & event)) {
162
221
  return 0;
@@ -177,28 +236,82 @@ static int usbi_hotplug_match_cb(struct libusb_context *ctx,
177
236
  return 0;
178
237
  }
179
238
 
180
- return hotplug_cb->cb(ctx, dev, event, hotplug_cb->user_data);
239
+ return hotplug_cb->cb(DEVICE_CTX(dev), dev, event, hotplug_cb->user_data);
181
240
  }
182
241
 
183
- void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
242
+ void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
184
243
  libusb_hotplug_event event)
185
244
  {
186
- struct libusb_hotplug_callback *hotplug_cb, *next;
187
- int ret;
245
+ struct usbi_hotplug_message *msg;
246
+ unsigned int event_flags;
247
+
248
+ /* Only generate a notification if hotplug is ready. This prevents hotplug
249
+ * notifications from being generated during initial enumeration or if the
250
+ * backend does not support hotplug. */
251
+ if (!usbi_atomic_load(&ctx->hotplug_ready))
252
+ return;
253
+
254
+ msg = calloc(1, sizeof(*msg));
255
+ if (!msg) {
256
+ usbi_err(ctx, "error allocating hotplug message");
257
+ return;
258
+ }
259
+
260
+ msg->event = event;
261
+ msg->device = dev;
262
+
263
+ /* Take the event data lock and add this message to the list.
264
+ * Only signal an event if there are no prior pending events. */
265
+ usbi_mutex_lock(&ctx->event_data_lock);
266
+ event_flags = ctx->event_flags;
267
+ ctx->event_flags |= USBI_EVENT_HOTPLUG_MSG_PENDING;
268
+ list_add_tail(&msg->list, &ctx->hotplug_msgs);
269
+ if (!event_flags)
270
+ usbi_signal_event(&ctx->event);
271
+ usbi_mutex_unlock(&ctx->event_data_lock);
272
+ }
273
+
274
+ void usbi_hotplug_process(struct libusb_context *ctx, struct list_head *hotplug_msgs)
275
+ {
276
+ struct usbi_hotplug_callback *hotplug_cb, *next_cb;
277
+ struct usbi_hotplug_message *msg;
278
+ int r;
188
279
 
189
280
  usbi_mutex_lock(&ctx->hotplug_cbs_lock);
190
281
 
191
- list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
192
- if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE) {
193
- /* process deregistration in usbi_hotplug_deregister() */
194
- continue;
282
+ /* dispatch all pending hotplug messages */
283
+ while (!list_empty(hotplug_msgs)) {
284
+ msg = list_first_entry(hotplug_msgs, struct usbi_hotplug_message, list);
285
+
286
+ for_each_hotplug_cb_safe(ctx, hotplug_cb, next_cb) {
287
+ /* skip callbacks that have unregistered */
288
+ if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE)
289
+ continue;
290
+
291
+ usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
292
+ r = usbi_hotplug_match_cb(msg->device, msg->event, hotplug_cb);
293
+ usbi_mutex_lock(&ctx->hotplug_cbs_lock);
294
+
295
+ if (r) {
296
+ list_del(&hotplug_cb->list);
297
+ free(hotplug_cb);
298
+ }
195
299
  }
196
300
 
197
- usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
198
- ret = usbi_hotplug_match_cb(ctx, dev, event, hotplug_cb);
199
- usbi_mutex_lock(&ctx->hotplug_cbs_lock);
301
+ /* if the device left, the message holds a reference
302
+ * and we must drop it */
303
+ if (msg->event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
304
+ libusb_unref_device(msg->device);
200
305
 
201
- if (ret) {
306
+ list_del(&msg->list);
307
+ free(msg);
308
+ }
309
+
310
+ /* free any callbacks that have unregistered */
311
+ for_each_hotplug_cb_safe(ctx, hotplug_cb, next_cb) {
312
+ if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE) {
313
+ usbi_dbg(ctx, "freeing hotplug cb %p with handle %d",
314
+ hotplug_cb, hotplug_cb->handle);
202
315
  list_del(&hotplug_cb->list);
203
316
  free(hotplug_cb);
204
317
  }
@@ -207,41 +320,17 @@ void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
207
320
  usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
208
321
  }
209
322
 
210
- void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
211
- libusb_hotplug_event event)
212
- {
213
- int pending_events;
214
- struct libusb_hotplug_message *message = calloc(1, sizeof(*message));
215
-
216
- if (!message) {
217
- usbi_err(ctx, "error allocating hotplug message");
218
- return;
219
- }
220
-
221
- message->event = event;
222
- message->device = dev;
223
-
224
- /* Take the event data lock and add this message to the list.
225
- * Only signal an event if there are no prior pending events. */
226
- usbi_mutex_lock(&ctx->event_data_lock);
227
- pending_events = usbi_pending_events(ctx);
228
- list_add_tail(&message->list, &ctx->hotplug_msgs);
229
- if (!pending_events)
230
- usbi_signal_event(ctx);
231
- usbi_mutex_unlock(&ctx->event_data_lock);
232
- }
233
-
234
323
  int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
235
- libusb_hotplug_event events, libusb_hotplug_flag flags,
324
+ int events, int flags,
236
325
  int vendor_id, int product_id, int dev_class,
237
326
  libusb_hotplug_callback_fn cb_fn, void *user_data,
238
327
  libusb_hotplug_callback_handle *callback_handle)
239
328
  {
240
- struct libusb_hotplug_callback *new_callback;
329
+ struct usbi_hotplug_callback *hotplug_cb;
241
330
 
242
331
  /* check for sane values */
243
- if ((!events || (~(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) & events)) ||
244
- (flags && (~LIBUSB_HOTPLUG_ENUMERATE & flags)) ||
332
+ if (!events || (~VALID_HOTPLUG_EVENTS & events) ||
333
+ (~VALID_HOTPLUG_FLAGS & flags) ||
245
334
  (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) ||
246
335
  (LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) ||
247
336
  (LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) ||
@@ -250,47 +339,45 @@ int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
250
339
  }
251
340
 
252
341
  /* check for hotplug support */
253
- if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
342
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
254
343
  return LIBUSB_ERROR_NOT_SUPPORTED;
255
- }
256
344
 
257
- USBI_GET_CONTEXT(ctx);
345
+ ctx = usbi_get_context(ctx);
258
346
 
259
- new_callback = calloc(1, sizeof(*new_callback));
260
- if (!new_callback) {
347
+ hotplug_cb = calloc(1, sizeof(*hotplug_cb));
348
+ if (!hotplug_cb)
261
349
  return LIBUSB_ERROR_NO_MEM;
262
- }
263
350
 
264
- new_callback->flags = (uint8_t)events;
351
+ hotplug_cb->flags = (uint8_t)events;
265
352
  if (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id) {
266
- new_callback->flags |= USBI_HOTPLUG_VENDOR_ID_VALID;
267
- new_callback->vendor_id = (uint16_t)vendor_id;
353
+ hotplug_cb->flags |= USBI_HOTPLUG_VENDOR_ID_VALID;
354
+ hotplug_cb->vendor_id = (uint16_t)vendor_id;
268
355
  }
269
356
  if (LIBUSB_HOTPLUG_MATCH_ANY != product_id) {
270
- new_callback->flags |= USBI_HOTPLUG_PRODUCT_ID_VALID;
271
- new_callback->product_id = (uint16_t)product_id;
357
+ hotplug_cb->flags |= USBI_HOTPLUG_PRODUCT_ID_VALID;
358
+ hotplug_cb->product_id = (uint16_t)product_id;
272
359
  }
273
360
  if (LIBUSB_HOTPLUG_MATCH_ANY != dev_class) {
274
- new_callback->flags |= USBI_HOTPLUG_DEV_CLASS_VALID;
275
- new_callback->dev_class = (uint8_t)dev_class;
361
+ hotplug_cb->flags |= USBI_HOTPLUG_DEV_CLASS_VALID;
362
+ hotplug_cb->dev_class = (uint8_t)dev_class;
276
363
  }
277
- new_callback->cb = cb_fn;
278
- new_callback->user_data = user_data;
364
+ hotplug_cb->cb = cb_fn;
365
+ hotplug_cb->user_data = user_data;
279
366
 
280
367
  usbi_mutex_lock(&ctx->hotplug_cbs_lock);
281
368
 
282
369
  /* protect the handle by the context hotplug lock */
283
- new_callback->handle = ctx->next_hotplug_cb_handle++;
370
+ hotplug_cb->handle = ctx->next_hotplug_cb_handle++;
284
371
 
285
372
  /* handle the unlikely case of overflow */
286
373
  if (ctx->next_hotplug_cb_handle < 0)
287
374
  ctx->next_hotplug_cb_handle = 1;
288
375
 
289
- list_add(&new_callback->list, &ctx->hotplug_cbs);
376
+ list_add(&hotplug_cb->list, &ctx->hotplug_cbs);
290
377
 
291
378
  usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
292
379
 
293
- usbi_dbg("new hotplug cb %p with handle %d", new_callback, new_callback->handle);
380
+ usbi_dbg(ctx, "new hotplug cb %p with handle %d", hotplug_cb, hotplug_cb->handle);
294
381
 
295
382
  if ((flags & LIBUSB_HOTPLUG_ENUMERATE) && (events & LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)) {
296
383
  ssize_t i, len;
@@ -298,76 +385,85 @@ int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
298
385
 
299
386
  len = libusb_get_device_list(ctx, &devs);
300
387
  if (len < 0) {
301
- libusb_hotplug_deregister_callback(ctx,
302
- new_callback->handle);
388
+ libusb_hotplug_deregister_callback(ctx, hotplug_cb->handle);
303
389
  return (int)len;
304
390
  }
305
391
 
306
392
  for (i = 0; i < len; i++) {
307
- usbi_hotplug_match_cb(ctx, devs[i],
393
+ usbi_hotplug_match_cb(devs[i],
308
394
  LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
309
- new_callback);
395
+ hotplug_cb);
310
396
  }
311
397
 
312
398
  libusb_free_device_list(devs, 1);
313
399
  }
314
400
 
315
-
316
401
  if (callback_handle)
317
- *callback_handle = new_callback->handle;
402
+ *callback_handle = hotplug_cb->handle;
318
403
 
319
404
  return LIBUSB_SUCCESS;
320
405
  }
321
406
 
322
- void API_EXPORTED libusb_hotplug_deregister_callback(struct libusb_context *ctx,
407
+ void API_EXPORTED libusb_hotplug_deregister_callback(libusb_context *ctx,
323
408
  libusb_hotplug_callback_handle callback_handle)
324
409
  {
325
- struct libusb_hotplug_callback *hotplug_cb;
410
+ struct usbi_hotplug_callback *hotplug_cb;
326
411
  int deregistered = 0;
327
412
 
328
413
  /* check for hotplug support */
329
- if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
414
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
330
415
  return;
331
- }
332
416
 
333
- USBI_GET_CONTEXT(ctx);
417
+ usbi_dbg(ctx, "deregister hotplug cb %d", callback_handle);
334
418
 
335
- usbi_dbg("deregister hotplug cb %d", callback_handle);
419
+ ctx = usbi_get_context(ctx);
336
420
 
337
421
  usbi_mutex_lock(&ctx->hotplug_cbs_lock);
338
- list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
422
+ for_each_hotplug_cb(ctx, hotplug_cb) {
339
423
  if (callback_handle == hotplug_cb->handle) {
340
- /* Mark this callback for deregistration */
424
+ /* mark this callback for deregistration */
341
425
  hotplug_cb->flags |= USBI_HOTPLUG_NEEDS_FREE;
342
426
  deregistered = 1;
427
+ break;
343
428
  }
344
429
  }
345
430
  usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
346
431
 
347
432
  if (deregistered) {
348
- int pending_events;
433
+ unsigned int event_flags;
349
434
 
350
435
  usbi_mutex_lock(&ctx->event_data_lock);
351
- pending_events = usbi_pending_events(ctx);
436
+ event_flags = ctx->event_flags;
352
437
  ctx->event_flags |= USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
353
- if (!pending_events)
354
- usbi_signal_event(ctx);
438
+ if (!event_flags)
439
+ usbi_signal_event(&ctx->event);
355
440
  usbi_mutex_unlock(&ctx->event_data_lock);
356
441
  }
357
442
  }
358
443
 
359
- void usbi_hotplug_deregister(struct libusb_context *ctx, int forced)
444
+ DEFAULT_VISIBILITY
445
+ void * LIBUSB_CALL libusb_hotplug_get_user_data(libusb_context *ctx,
446
+ libusb_hotplug_callback_handle callback_handle)
360
447
  {
361
- struct libusb_hotplug_callback *hotplug_cb, *next;
448
+ struct usbi_hotplug_callback *hotplug_cb;
449
+ void *user_data = NULL;
450
+
451
+ /* check for hotplug support */
452
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
453
+ return NULL;
454
+
455
+ usbi_dbg(ctx, "get hotplug cb %d user data", callback_handle);
456
+
457
+ ctx = usbi_get_context(ctx);
362
458
 
363
459
  usbi_mutex_lock(&ctx->hotplug_cbs_lock);
364
- list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
365
- if (forced || (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE)) {
366
- usbi_dbg("freeing hotplug cb %p with handle %d", hotplug_cb,
367
- hotplug_cb->handle);
368
- list_del(&hotplug_cb->list);
369
- free(hotplug_cb);
460
+ for_each_hotplug_cb(ctx, hotplug_cb) {
461
+ if (callback_handle == hotplug_cb->handle) {
462
+ user_data = hotplug_cb->user_data;
463
+ break;
370
464
  }
371
465
  }
372
466
  usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
467
+
468
+ return user_data;
373
469
  }