usb 1.7.2 → 1.8.1-libusb.4
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/.gitmodules +1 -1
- package/Readme.md +2 -2
- package/binding.gyp +2 -2
- package/libusb/.private/pre-commit.sh +7 -1
- package/libusb/.travis.yml +49 -0
- package/libusb/AUTHORS +44 -3
- package/libusb/Brewfile +4 -0
- package/libusb/ChangeLog +74 -2
- package/libusb/README.md +32 -0
- package/libusb/TODO +1 -1
- package/libusb/Xcode/common.xcconfig +12 -0
- package/libusb/Xcode/config.h +25 -0
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +959 -1
- package/libusb/android/README +4 -2
- package/libusb/android/config.h +75 -0
- package/libusb/appveyor.yml +41 -0
- package/libusb/appveyor_cygwin.bat +11 -0
- package/libusb/appveyor_minGW.bat +19 -0
- package/libusb/autogen.sh +1 -1
- package/libusb/bootstrap.sh +3 -16
- package/libusb/configure.ac +108 -80
- package/libusb/doc/doxygen.cfg.in +1785 -739
- package/libusb/examples/Makefile.am +1 -1
- package/libusb/examples/dpfp.c +3 -1
- package/libusb/examples/dpfp_threaded.c +23 -10
- package/libusb/examples/ezusb.c +3 -3
- package/libusb/examples/ezusb.h +2 -2
- package/libusb/examples/fxload.c +31 -9
- package/libusb/examples/hotplugtest.c +35 -7
- package/libusb/examples/listdevs.c +3 -1
- package/libusb/examples/sam3u_benchmark.c +3 -3
- package/libusb/examples/testlibusb.c +277 -0
- package/libusb/examples/xusb.c +40 -34
- package/libusb/libusb/Makefile.am +49 -23
- package/libusb/libusb/core.c +855 -457
- package/libusb/libusb/descriptor.c +72 -78
- package/libusb/libusb/hotplug.c +122 -76
- package/libusb/libusb/hotplug.h +42 -25
- package/libusb/libusb/io.c +625 -390
- package/libusb/libusb/libusb-1.0.def +12 -0
- package/libusb/libusb/libusb.h +218 -150
- package/libusb/libusb/libusbi.h +346 -176
- package/libusb/libusb/os/darwin_usb.c +604 -319
- package/libusb/libusb/os/darwin_usb.h +61 -20
- package/libusb/libusb/os/haiku_pollfs.cpp +367 -0
- package/libusb/libusb/os/haiku_usb.h +113 -0
- package/libusb/libusb/os/haiku_usb_backend.cpp +533 -0
- package/libusb/libusb/os/haiku_usb_raw.cpp +267 -0
- package/libusb/libusb/os/haiku_usb_raw.h +188 -0
- package/libusb/libusb/os/linux_netlink.c +186 -146
- package/libusb/libusb/os/linux_udev.c +36 -14
- package/libusb/libusb/os/linux_usbfs.c +426 -225
- package/libusb/libusb/os/linux_usbfs.h +5 -3
- package/libusb/libusb/os/netbsd_usb.c +21 -77
- package/libusb/libusb/os/openbsd_usb.c +32 -115
- package/libusb/libusb/os/poll_posix.c +38 -5
- package/libusb/libusb/os/poll_posix.h +3 -0
- package/libusb/libusb/os/poll_windows.c +277 -626
- package/libusb/libusb/os/poll_windows.h +11 -44
- package/libusb/libusb/os/sunos_usb.c +1695 -0
- package/libusb/libusb/os/sunos_usb.h +80 -0
- package/libusb/libusb/os/threads_posix.c +24 -26
- package/libusb/libusb/os/threads_posix.h +73 -21
- package/libusb/libusb/os/threads_windows.c +71 -157
- package/libusb/libusb/os/threads_windows.h +68 -44
- package/libusb/libusb/os/wince_usb.c +276 -420
- package/libusb/libusb/os/wince_usb.h +23 -28
- package/libusb/libusb/os/windows_common.h +78 -58
- package/libusb/libusb/os/windows_nt_common.c +1010 -0
- package/libusb/libusb/os/windows_nt_common.h +110 -0
- package/libusb/libusb/os/windows_nt_shared_types.h +147 -0
- package/libusb/libusb/os/windows_usbdk.c +830 -0
- package/libusb/libusb/os/windows_usbdk.h +103 -0
- package/libusb/libusb/os/windows_winusb.c +4391 -0
- package/libusb/libusb/os/windows_winusb.h +783 -0
- package/libusb/libusb/strerror.c +41 -7
- package/libusb/libusb/sync.c +41 -13
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/libusb-1.0.pc.in +1 -1
- package/libusb/msvc/appveyor.bat +27 -0
- package/libusb/msvc/config.h +5 -4
- package/libusb/msvc/ddk_build.cmd +87 -43
- package/libusb/msvc/fxload_2010.vcxproj +24 -104
- package/libusb/msvc/fxload_2012.vcxproj +24 -107
- package/libusb/msvc/fxload_2013.vcxproj +24 -107
- package/libusb/msvc/fxload_2015.vcxproj +91 -0
- package/libusb/msvc/fxload_2017.vcxproj +114 -0
- package/libusb/msvc/fxload_sources +1 -1
- package/libusb/msvc/getopt_2010.vcxproj +16 -75
- package/libusb/msvc/getopt_2012.vcxproj +16 -79
- package/libusb/msvc/getopt_2013.vcxproj +16 -79
- package/libusb/msvc/getopt_2015.vcxproj +73 -0
- package/libusb/msvc/getopt_2017.vcxproj +98 -0
- package/libusb/msvc/getopt_sources +6 -2
- package/libusb/msvc/hotplugtest_2010.vcxproj +18 -99
- package/libusb/msvc/hotplugtest_2012.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2013.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2015.vcxproj +83 -0
- package/libusb/msvc/hotplugtest_2017.vcxproj +106 -0
- package/libusb/msvc/hotplugtest_sources +1 -1
- package/libusb/msvc/libusb_2005.sln +20 -20
- package/libusb/msvc/libusb_2010.sln +57 -46
- package/libusb/msvc/libusb_2012.sln +57 -46
- package/libusb/msvc/libusb_2013.sln +57 -50
- package/libusb/msvc/libusb_2015.sln +59 -52
- package/libusb/msvc/libusb_2017.sln +186 -0
- package/libusb/msvc/libusb_dll.dsp +2 -2
- package/libusb/msvc/libusb_dll_2005.vcproj +30 -2
- package/libusb/msvc/libusb_dll_2010.vcxproj +26 -90
- package/libusb/msvc/libusb_dll_2012.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2013.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2015.vcxproj +107 -0
- package/libusb/msvc/libusb_dll_2017.vcxproj +134 -0
- package/libusb/msvc/libusb_dll_wince.vcproj +9 -1
- package/libusb/msvc/libusb_sources +10 -5
- package/libusb/msvc/libusb_static.dsp +2 -2
- package/libusb/msvc/libusb_static_2005.vcproj +32 -4
- package/libusb/msvc/libusb_static_2010.vcxproj +24 -83
- package/libusb/msvc/libusb_static_2012.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2013.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2015.vcxproj +98 -0
- package/libusb/msvc/libusb_static_2017.vcxproj +117 -0
- package/libusb/msvc/libusb_static_wince.vcproj +20 -26
- package/libusb/msvc/libusb_wince.sln +88 -88
- package/libusb/msvc/listdevs_2010.vcxproj +16 -99
- package/libusb/msvc/listdevs_2012.vcxproj +16 -102
- package/libusb/msvc/listdevs_2013.vcxproj +16 -102
- package/libusb/msvc/listdevs_2015.vcxproj +83 -0
- package/libusb/msvc/listdevs_2017.vcxproj +106 -0
- package/libusb/msvc/listdevs_sources +2 -1
- package/libusb/msvc/stress_2010.vcxproj +20 -101
- package/libusb/msvc/stress_2012.vcxproj +20 -104
- package/libusb/msvc/stress_2013.vcxproj +20 -104
- package/libusb/msvc/stress_2015.vcxproj +87 -0
- package/libusb/msvc/stress_2017.vcxproj +110 -0
- package/libusb/msvc/stress_sources +21 -0
- package/libusb/msvc/testlibusb_2010.vcxproj +82 -0
- package/libusb/msvc/testlibusb_2012.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2013.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2015.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2017.vcxproj +106 -0
- package/libusb/msvc/testlibusb_sources +20 -0
- package/libusb/msvc/xusb_2010.vcxproj +17 -98
- package/libusb/msvc/xusb_2012.vcxproj +17 -101
- package/libusb/msvc/xusb_2013.vcxproj +17 -101
- package/libusb/msvc/xusb_2015.vcxproj +83 -0
- package/libusb/msvc/xusb_2017.vcxproj +106 -0
- package/libusb/msvc/xusb_sources +1 -1
- package/libusb/tests/stress.c +2 -2
- package/libusb/tests/testlib.c +0 -4
- package/libusb/travis-autogen.sh +39 -0
- package/libusb.gypi +13 -2
- package/package.json +20 -11
- 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-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/device.cc +1 -1
- package/usb.js +51 -5
- package/.github/workflows/prebuild.yml +0 -49
- package/libusb/INSTALL +0 -234
- package/libusb/README +0 -28
- package/libusb/libusb/os/windows_usb.c +0 -5347
- package/libusb/libusb/os/windows_usb.h +0 -971
- package/libusb/msvc/fxload_2010.vcxproj.filters +0 -25
- package/libusb/msvc/fxload_2012.vcxproj.filters +0 -25
- package/libusb/msvc/getopt_2010.vcxproj.filters +0 -26
- package/libusb/msvc/getopt_2012.vcxproj.filters +0 -26
- package/libusb/msvc/hotplugtest_2010.vcxproj.filters +0 -14
- package/libusb/msvc/hotplugtest_2012.vcxproj.filters +0 -14
- package/libusb/msvc/libusb_dll_2010.vcxproj.filters +0 -81
- package/libusb/msvc/libusb_dll_2012.vcxproj.filters +0 -84
- package/libusb/msvc/libusb_static_2010.vcxproj.filters +0 -74
- package/libusb/msvc/libusb_static_2012.vcxproj.filters +0 -74
- package/libusb/msvc/listdevs_2010.vcxproj.filters +0 -14
- package/libusb/msvc/listdevs_2012.vcxproj.filters +0 -14
- package/libusb/msvc/stress_2010.vcxproj.filters +0 -25
- package/libusb/msvc/stress_2012.vcxproj.filters +0 -25
- package/libusb/msvc/xusb_2010.vcxproj.filters +0 -14
- package/libusb/msvc/xusb_2012.vcxproj.filters +0 -14
package/libusb/libusb/hotplug.c
CHANGED
|
@@ -34,16 +34,16 @@
|
|
|
34
34
|
#include "hotplug.h"
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* @defgroup
|
|
37
|
+
* @defgroup libusb_hotplug Device hotplug event notification
|
|
38
38
|
* This page details how to use the libusb hotplug interface, where available.
|
|
39
39
|
*
|
|
40
40
|
* Be mindful that not all platforms currently implement hotplug notification and
|
|
41
41
|
* that you should first call on \ref libusb_has_capability() with parameter
|
|
42
42
|
* \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available.
|
|
43
43
|
*
|
|
44
|
-
* \page
|
|
44
|
+
* \page libusb_hotplug Device hotplug event notification
|
|
45
45
|
*
|
|
46
|
-
* \section
|
|
46
|
+
* \section hotplug_intro Introduction
|
|
47
47
|
*
|
|
48
48
|
* Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support
|
|
49
49
|
* for hotplug events on <b>some</b> platforms (you should test if your platform
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
*
|
|
56
56
|
* To receive hotplug notification you register a callback by calling
|
|
57
57
|
* \ref libusb_hotplug_register_callback(). This function will optionally return
|
|
58
|
-
* a handle that can be passed to \ref libusb_hotplug_deregister_callback().
|
|
58
|
+
* a callback handle that can be passed to \ref libusb_hotplug_deregister_callback().
|
|
59
59
|
*
|
|
60
60
|
* A callback function must return an int (0 or 1) indicating whether the callback is
|
|
61
61
|
* expecting additional events. Returning 0 will rearm the callback and 1 will cause
|
|
@@ -75,40 +75,47 @@
|
|
|
75
75
|
*
|
|
76
76
|
* Note: If you receive notification that a device has left and you have any
|
|
77
77
|
* a libusb_device_handles for the device it is up to you to call libusb_close()
|
|
78
|
-
* on each handle to free up any remaining resources associated with the device.
|
|
78
|
+
* on each device handle to free up any remaining resources associated with the device.
|
|
79
79
|
* Once a device has left any libusb_device_handle associated with the device
|
|
80
80
|
* are invalid and will remain so even if the device comes back.
|
|
81
81
|
*
|
|
82
82
|
* When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered
|
|
83
|
-
* safe to call any libusb function that takes a libusb_device.
|
|
84
|
-
*
|
|
83
|
+
* safe to call any libusb function that takes a libusb_device. It also safe to
|
|
84
|
+
* open a device and submit asynchronous transfers. However, most other functions
|
|
85
|
+
* that take a libusb_device_handle are <b>not</b> safe to call. Examples of such
|
|
86
|
+
* functions are any of the \ref libusb_syncio "synchronous API" functions or the blocking
|
|
87
|
+
* functions that retrieve various \ref libusb_desc "USB descriptors". These functions must
|
|
88
|
+
* be used outside of the context of the hotplug callback.
|
|
89
|
+
*
|
|
90
|
+
* When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function
|
|
85
91
|
* is libusb_get_device_descriptor().
|
|
86
92
|
*
|
|
87
93
|
* The following code provides an example of the usage of the hotplug interface:
|
|
88
94
|
\code
|
|
89
95
|
#include <stdio.h>
|
|
90
96
|
#include <stdlib.h>
|
|
97
|
+
#include <time.h>
|
|
91
98
|
#include <libusb.h>
|
|
92
99
|
|
|
93
100
|
static int count = 0;
|
|
94
101
|
|
|
95
102
|
int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
|
|
96
103
|
libusb_hotplug_event event, void *user_data) {
|
|
97
|
-
static libusb_device_handle *
|
|
104
|
+
static libusb_device_handle *dev_handle = NULL;
|
|
98
105
|
struct libusb_device_descriptor desc;
|
|
99
106
|
int rc;
|
|
100
107
|
|
|
101
108
|
(void)libusb_get_device_descriptor(dev, &desc);
|
|
102
109
|
|
|
103
110
|
if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
|
|
104
|
-
rc = libusb_open(dev, &
|
|
111
|
+
rc = libusb_open(dev, &dev_handle);
|
|
105
112
|
if (LIBUSB_SUCCESS != rc) {
|
|
106
113
|
printf("Could not open USB device\n");
|
|
107
114
|
}
|
|
108
115
|
} else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
|
|
109
|
-
if (
|
|
110
|
-
libusb_close(
|
|
111
|
-
|
|
116
|
+
if (dev_handle) {
|
|
117
|
+
libusb_close(dev_handle);
|
|
118
|
+
dev_handle = NULL;
|
|
112
119
|
}
|
|
113
120
|
} else {
|
|
114
121
|
printf("Unhandled event %d\n", event);
|
|
@@ -119,7 +126,7 @@ int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
|
|
|
119
126
|
}
|
|
120
127
|
|
|
121
128
|
int main (void) {
|
|
122
|
-
libusb_hotplug_callback_handle
|
|
129
|
+
libusb_hotplug_callback_handle callback_handle;
|
|
123
130
|
int rc;
|
|
124
131
|
|
|
125
132
|
libusb_init(NULL);
|
|
@@ -127,7 +134,7 @@ int main (void) {
|
|
|
127
134
|
rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
|
|
128
135
|
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005,
|
|
129
136
|
LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
|
|
130
|
-
&
|
|
137
|
+
&callback_handle);
|
|
131
138
|
if (LIBUSB_SUCCESS != rc) {
|
|
132
139
|
printf("Error creating a hotplug callback\n");
|
|
133
140
|
libusb_exit(NULL);
|
|
@@ -136,10 +143,10 @@ int main (void) {
|
|
|
136
143
|
|
|
137
144
|
while (count < 2) {
|
|
138
145
|
libusb_handle_events_completed(NULL, NULL);
|
|
139
|
-
|
|
146
|
+
nanosleep(&(struct timespec){0, 10000000UL}, NULL);
|
|
140
147
|
}
|
|
141
148
|
|
|
142
|
-
libusb_hotplug_deregister_callback(NULL,
|
|
149
|
+
libusb_hotplug_deregister_callback(NULL, callback_handle);
|
|
143
150
|
libusb_exit(NULL);
|
|
144
151
|
|
|
145
152
|
return 0;
|
|
@@ -147,36 +154,30 @@ int main (void) {
|
|
|
147
154
|
\endcode
|
|
148
155
|
*/
|
|
149
156
|
|
|
150
|
-
static int usbi_hotplug_match_cb
|
|
157
|
+
static int usbi_hotplug_match_cb(struct libusb_context *ctx,
|
|
151
158
|
struct libusb_device *dev, libusb_hotplug_event event,
|
|
152
159
|
struct libusb_hotplug_callback *hotplug_cb)
|
|
153
160
|
{
|
|
154
|
-
|
|
155
|
-
if (hotplug_cb->needs_free) {
|
|
156
|
-
/* Free callback */
|
|
157
|
-
return 1;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (!(hotplug_cb->events & event)) {
|
|
161
|
+
if (!(hotplug_cb->flags & event)) {
|
|
161
162
|
return 0;
|
|
162
163
|
}
|
|
163
164
|
|
|
164
|
-
if (
|
|
165
|
+
if ((hotplug_cb->flags & USBI_HOTPLUG_VENDOR_ID_VALID) &&
|
|
165
166
|
hotplug_cb->vendor_id != dev->device_descriptor.idVendor) {
|
|
166
167
|
return 0;
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
if (
|
|
170
|
+
if ((hotplug_cb->flags & USBI_HOTPLUG_PRODUCT_ID_VALID) &&
|
|
170
171
|
hotplug_cb->product_id != dev->device_descriptor.idProduct) {
|
|
171
172
|
return 0;
|
|
172
173
|
}
|
|
173
174
|
|
|
174
|
-
if (
|
|
175
|
+
if ((hotplug_cb->flags & USBI_HOTPLUG_DEV_CLASS_VALID) &&
|
|
175
176
|
hotplug_cb->dev_class != dev->device_descriptor.bDeviceClass) {
|
|
176
177
|
return 0;
|
|
177
178
|
}
|
|
178
179
|
|
|
179
|
-
return hotplug_cb->cb
|
|
180
|
+
return hotplug_cb->cb(ctx, dev, event, hotplug_cb->user_data);
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
|
|
@@ -188,8 +189,13 @@ void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
|
|
|
188
189
|
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
|
|
189
190
|
|
|
190
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;
|
|
195
|
+
}
|
|
196
|
+
|
|
191
197
|
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
|
192
|
-
ret = usbi_hotplug_match_cb
|
|
198
|
+
ret = usbi_hotplug_match_cb(ctx, dev, event, hotplug_cb);
|
|
193
199
|
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
|
|
194
200
|
|
|
195
201
|
if (ret) {
|
|
@@ -199,69 +205,102 @@ void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
|
|
|
199
205
|
}
|
|
200
206
|
|
|
201
207
|
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
|
208
|
+
}
|
|
209
|
+
|
|
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));
|
|
202
215
|
|
|
203
|
-
|
|
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);
|
|
204
232
|
}
|
|
205
233
|
|
|
206
234
|
int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
|
|
207
235
|
libusb_hotplug_event events, libusb_hotplug_flag flags,
|
|
208
236
|
int vendor_id, int product_id, int dev_class,
|
|
209
237
|
libusb_hotplug_callback_fn cb_fn, void *user_data,
|
|
210
|
-
libusb_hotplug_callback_handle *
|
|
238
|
+
libusb_hotplug_callback_handle *callback_handle)
|
|
211
239
|
{
|
|
212
|
-
libusb_hotplug_callback *new_callback;
|
|
213
|
-
static int handle_id = 1;
|
|
214
|
-
|
|
215
|
-
/* check for hotplug support */
|
|
216
|
-
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
|
217
|
-
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
218
|
-
}
|
|
240
|
+
struct libusb_hotplug_callback *new_callback;
|
|
219
241
|
|
|
220
242
|
/* check for sane values */
|
|
221
|
-
if ((
|
|
243
|
+
if ((!events || (~(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) & events)) ||
|
|
244
|
+
(flags && (~LIBUSB_HOTPLUG_ENUMERATE & flags)) ||
|
|
245
|
+
(LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) ||
|
|
222
246
|
(LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) ||
|
|
223
247
|
(LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) ||
|
|
224
248
|
!cb_fn) {
|
|
225
249
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
226
250
|
}
|
|
227
251
|
|
|
252
|
+
/* check for hotplug support */
|
|
253
|
+
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
|
254
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
255
|
+
}
|
|
256
|
+
|
|
228
257
|
USBI_GET_CONTEXT(ctx);
|
|
229
258
|
|
|
230
|
-
new_callback =
|
|
259
|
+
new_callback = calloc(1, sizeof(*new_callback));
|
|
231
260
|
if (!new_callback) {
|
|
232
261
|
return LIBUSB_ERROR_NO_MEM;
|
|
233
262
|
}
|
|
234
263
|
|
|
235
|
-
new_callback->
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
264
|
+
new_callback->flags = (uint8_t)events;
|
|
265
|
+
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;
|
|
268
|
+
}
|
|
269
|
+
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;
|
|
272
|
+
}
|
|
273
|
+
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;
|
|
276
|
+
}
|
|
241
277
|
new_callback->cb = cb_fn;
|
|
242
278
|
new_callback->user_data = user_data;
|
|
243
|
-
new_callback->needs_free = 0;
|
|
244
279
|
|
|
245
280
|
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
|
|
246
281
|
|
|
247
|
-
/* protect the handle by the context hotplug lock
|
|
248
|
-
|
|
249
|
-
|
|
282
|
+
/* protect the handle by the context hotplug lock */
|
|
283
|
+
new_callback->handle = ctx->next_hotplug_cb_handle++;
|
|
284
|
+
|
|
285
|
+
/* handle the unlikely case of overflow */
|
|
286
|
+
if (ctx->next_hotplug_cb_handle < 0)
|
|
287
|
+
ctx->next_hotplug_cb_handle = 1;
|
|
250
288
|
|
|
251
289
|
list_add(&new_callback->list, &ctx->hotplug_cbs);
|
|
252
290
|
|
|
253
291
|
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
|
254
292
|
|
|
293
|
+
usbi_dbg("new hotplug cb %p with handle %d", new_callback, new_callback->handle);
|
|
255
294
|
|
|
256
|
-
if (flags & LIBUSB_HOTPLUG_ENUMERATE) {
|
|
257
|
-
|
|
295
|
+
if ((flags & LIBUSB_HOTPLUG_ENUMERATE) && (events & LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)) {
|
|
296
|
+
ssize_t i, len;
|
|
258
297
|
struct libusb_device **devs;
|
|
259
298
|
|
|
260
|
-
len =
|
|
299
|
+
len = libusb_get_device_list(ctx, &devs);
|
|
261
300
|
if (len < 0) {
|
|
262
301
|
libusb_hotplug_deregister_callback(ctx,
|
|
263
302
|
new_callback->handle);
|
|
264
|
-
return len;
|
|
303
|
+
return (int)len;
|
|
265
304
|
}
|
|
266
305
|
|
|
267
306
|
for (i = 0; i < len; i++) {
|
|
@@ -274,19 +313,17 @@ int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
|
|
|
274
313
|
}
|
|
275
314
|
|
|
276
315
|
|
|
277
|
-
if (
|
|
278
|
-
*
|
|
279
|
-
}
|
|
316
|
+
if (callback_handle)
|
|
317
|
+
*callback_handle = new_callback->handle;
|
|
280
318
|
|
|
281
319
|
return LIBUSB_SUCCESS;
|
|
282
320
|
}
|
|
283
321
|
|
|
284
|
-
void API_EXPORTED libusb_hotplug_deregister_callback
|
|
285
|
-
libusb_hotplug_callback_handle
|
|
322
|
+
void API_EXPORTED libusb_hotplug_deregister_callback(struct libusb_context *ctx,
|
|
323
|
+
libusb_hotplug_callback_handle callback_handle)
|
|
286
324
|
{
|
|
287
325
|
struct libusb_hotplug_callback *hotplug_cb;
|
|
288
|
-
|
|
289
|
-
ssize_t ret;
|
|
326
|
+
int deregistered = 0;
|
|
290
327
|
|
|
291
328
|
/* check for hotplug support */
|
|
292
329
|
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
|
@@ -295,33 +332,42 @@ void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx
|
|
|
295
332
|
|
|
296
333
|
USBI_GET_CONTEXT(ctx);
|
|
297
334
|
|
|
335
|
+
usbi_dbg("deregister hotplug cb %d", callback_handle);
|
|
336
|
+
|
|
298
337
|
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
|
|
299
|
-
list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list,
|
|
300
|
-
|
|
301
|
-
if (handle == hotplug_cb->handle) {
|
|
338
|
+
list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
|
|
339
|
+
if (callback_handle == hotplug_cb->handle) {
|
|
302
340
|
/* Mark this callback for deregistration */
|
|
303
|
-
hotplug_cb->
|
|
341
|
+
hotplug_cb->flags |= USBI_HOTPLUG_NEEDS_FREE;
|
|
342
|
+
deregistered = 1;
|
|
304
343
|
}
|
|
305
344
|
}
|
|
306
345
|
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
|
307
346
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
347
|
+
if (deregistered) {
|
|
348
|
+
int pending_events;
|
|
349
|
+
|
|
350
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
351
|
+
pending_events = usbi_pending_events(ctx);
|
|
352
|
+
ctx->event_flags |= USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
|
|
353
|
+
if (!pending_events)
|
|
354
|
+
usbi_signal_event(ctx);
|
|
355
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
313
356
|
}
|
|
314
357
|
}
|
|
315
358
|
|
|
316
|
-
void
|
|
359
|
+
void usbi_hotplug_deregister(struct libusb_context *ctx, int forced)
|
|
360
|
+
{
|
|
317
361
|
struct libusb_hotplug_callback *hotplug_cb, *next;
|
|
318
362
|
|
|
319
363
|
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
|
|
320
|
-
list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list,
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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);
|
|
370
|
+
}
|
|
324
371
|
}
|
|
325
|
-
|
|
326
372
|
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
|
|
327
373
|
}
|
package/libusb/libusb/hotplug.h
CHANGED
|
@@ -19,12 +19,34 @@
|
|
|
19
19
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
#
|
|
22
|
+
#ifndef USBI_HOTPLUG_H
|
|
23
23
|
#define USBI_HOTPLUG_H
|
|
24
24
|
|
|
25
|
-
#ifndef LIBUSBI_H
|
|
26
25
|
#include "libusbi.h"
|
|
27
|
-
|
|
26
|
+
|
|
27
|
+
enum usbi_hotplug_flags {
|
|
28
|
+
/* This callback is interested in device arrivals */
|
|
29
|
+
USBI_HOTPLUG_DEVICE_ARRIVED = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
|
|
30
|
+
|
|
31
|
+
/* This callback is interested in device removals */
|
|
32
|
+
USBI_HOTPLUG_DEVICE_LEFT = LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
|
|
33
|
+
|
|
34
|
+
/* IMPORTANT: The values for the below entries must start *after*
|
|
35
|
+
* the highest value of the above entries!!!
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/* The vendor_id field is valid for matching */
|
|
39
|
+
USBI_HOTPLUG_VENDOR_ID_VALID = (1U << 3),
|
|
40
|
+
|
|
41
|
+
/* The product_id field is valid for matching */
|
|
42
|
+
USBI_HOTPLUG_PRODUCT_ID_VALID = (1U << 4),
|
|
43
|
+
|
|
44
|
+
/* The dev_class field is valid for matching */
|
|
45
|
+
USBI_HOTPLUG_DEV_CLASS_VALID = (1U << 5),
|
|
46
|
+
|
|
47
|
+
/* This callback has been unregistered and needs to be freed */
|
|
48
|
+
USBI_HOTPLUG_NEEDS_FREE = (1U << 6),
|
|
49
|
+
};
|
|
28
50
|
|
|
29
51
|
/** \ingroup hotplug
|
|
30
52
|
* The hotplug callback structure. The user populates this structure with
|
|
@@ -32,23 +54,17 @@
|
|
|
32
54
|
* to receive notification of hotplug events.
|
|
33
55
|
*/
|
|
34
56
|
struct libusb_hotplug_callback {
|
|
35
|
-
/**
|
|
36
|
-
|
|
57
|
+
/** Flags that control how this callback behaves */
|
|
58
|
+
uint8_t flags;
|
|
37
59
|
|
|
38
|
-
/** Vendor ID to match
|
|
39
|
-
|
|
60
|
+
/** Vendor ID to match (if flags says this is valid) */
|
|
61
|
+
uint16_t vendor_id;
|
|
40
62
|
|
|
41
|
-
/** Product ID to match
|
|
42
|
-
|
|
63
|
+
/** Product ID to match (if flags says this is valid) */
|
|
64
|
+
uint16_t product_id;
|
|
43
65
|
|
|
44
|
-
/** Device class to match
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/** Hotplug callback flags */
|
|
48
|
-
libusb_hotplug_flag flags;
|
|
49
|
-
|
|
50
|
-
/** Event(s) that will trigger this callback */
|
|
51
|
-
libusb_hotplug_event events;
|
|
66
|
+
/** Device class to match (if flags says this is valid) */
|
|
67
|
+
uint8_t dev_class;
|
|
52
68
|
|
|
53
69
|
/** Callback function to invoke for matching event/device */
|
|
54
70
|
libusb_hotplug_callback_fn cb;
|
|
@@ -59,24 +75,25 @@ struct libusb_hotplug_callback {
|
|
|
59
75
|
/** User data that will be passed to the callback function */
|
|
60
76
|
void *user_data;
|
|
61
77
|
|
|
62
|
-
/** Callback is marked for deletion */
|
|
63
|
-
int needs_free;
|
|
64
|
-
|
|
65
78
|
/** List this callback is registered in (ctx->hotplug_cbs) */
|
|
66
79
|
struct list_head list;
|
|
67
80
|
};
|
|
68
81
|
|
|
69
|
-
typedef struct libusb_hotplug_callback libusb_hotplug_callback;
|
|
70
|
-
|
|
71
82
|
struct libusb_hotplug_message {
|
|
83
|
+
/** The hotplug event that occurred */
|
|
72
84
|
libusb_hotplug_event event;
|
|
85
|
+
|
|
86
|
+
/** The device for which this hotplug event occurred */
|
|
73
87
|
struct libusb_device *device;
|
|
74
|
-
};
|
|
75
88
|
|
|
76
|
-
|
|
89
|
+
/** List this message is contained in (ctx->hotplug_msgs) */
|
|
90
|
+
struct list_head list;
|
|
91
|
+
};
|
|
77
92
|
|
|
78
|
-
void
|
|
93
|
+
void usbi_hotplug_deregister(struct libusb_context *ctx, int forced);
|
|
79
94
|
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
|
|
80
95
|
libusb_hotplug_event event);
|
|
96
|
+
void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
|
|
97
|
+
libusb_hotplug_event event);
|
|
81
98
|
|
|
82
99
|
#endif
|