usb 2.0.0-alpha.1 → 2.0.3
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/.gitattributes +1 -0
- package/.gitmodules +1 -1
- package/CHANGELOG.md +91 -0
- package/README.md +570 -0
- package/binding.gyp +2 -2
- package/dist/index.d.ts +16 -5
- package/dist/index.js +135 -5
- package/dist/index.js.map +1 -1
- package/dist/usb/bindings.d.ts +13 -0
- package/dist/usb/bindings.js +2 -1
- package/dist/usb/bindings.js.map +1 -1
- package/dist/usb/index.d.ts +0 -2
- package/dist/usb/index.js +75 -112
- package/dist/usb/index.js.map +1 -1
- package/dist/usb/interface.js.map +1 -1
- package/dist/webusb/index.d.ts +28 -19
- package/dist/webusb/index.js +152 -66
- package/dist/webusb/index.js.map +1 -1
- package/dist/webusb/webusb-device.d.ts +1 -1
- package/dist/webusb/webusb-device.js +15 -6
- package/dist/webusb/webusb-device.js.map +1 -1
- 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 +0 -3
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +959 -1
- package/libusb/android/README +4 -2
- package/libusb/android/config.h +0 -6
- 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 +23 -13
- 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 +7 -7
- package/src/node_usb.cc +43 -1
- package/src/node_usb.h +1 -0
- package/src/uv_async_queue.h +33 -25
- package/test/usb.coffee +12 -4
- package/tsc/index.ts +68 -8
- package/tsc/usb/bindings.ts +19 -1
- package/tsc/usb/index.ts +66 -68
- package/tsc/usb/interface.ts +2 -2
- package/tsc/webusb/index.ts +187 -75
- package/tsc/webusb/webusb-device.ts +28 -17
- package/.github/workflows/prebuild.yml +0 -48
- package/Readme.md +0 -339
- package/dist/webusb/typed-event-target.d.ts +0 -11
- package/dist/webusb/typed-event-target.js +0 -21
- package/dist/webusb/typed-event-target.js.map +0 -1
- package/docs/assets/css/main.css +0 -2660
- package/docs/assets/images/icons.png +0 -0
- package/docs/assets/images/icons@2x.png +0 -0
- package/docs/assets/images/widgets.png +0 -0
- package/docs/assets/images/widgets@2x.png +0 -0
- package/docs/assets/js/main.js +0 -248
- package/docs/assets/js/search.js +0 -1
- package/docs/classes/usb_bindings.device.html +0 -1338
- package/docs/classes/usb_bindings.libusbexception.html +0 -234
- package/docs/classes/usb_bindings.transfer.html +0 -344
- package/docs/classes/usb_capability.capability.html +0 -297
- package/docs/classes/usb_device.extendeddevice.html +0 -766
- package/docs/classes/usb_endpoint.endpoint.html +0 -472
- package/docs/classes/usb_endpoint.inendpoint.html +0 -766
- package/docs/classes/usb_endpoint.outendpoint.html +0 -582
- package/docs/classes/usb_interface.interface.html +0 -648
- package/docs/classes/webusb.webusb-1.html +0 -615
- package/docs/classes/webusb_mutex.mutex.html +0 -270
- package/docs/classes/webusb_typed_event_target.typedeventtarget.html +0 -443
- package/docs/classes/webusb_webusb_device.webusbdevice.html +0 -904
- package/docs/index.html +0 -500
- package/docs/interfaces/usb.deviceevents.html +0 -242
- package/docs/interfaces/usb_descriptors.bosdescriptor.html +0 -293
- package/docs/interfaces/usb_descriptors.capabilitydescriptor.html +0 -274
- package/docs/interfaces/usb_descriptors.configdescriptor.html +0 -388
- package/docs/interfaces/usb_descriptors.devicedescriptor.html +0 -464
- package/docs/interfaces/usb_descriptors.endpointdescriptor.html +0 -370
- package/docs/interfaces/usb_descriptors.interfacedescriptor.html +0 -407
- package/docs/interfaces/webusb.usboptions.html +0 -226
- package/docs/modules/index.html +0 -173
- package/docs/modules/usb.html +0 -173
- package/docs/modules/usb_bindings.html +0 -2319
- package/docs/modules/usb_capability.html +0 -156
- package/docs/modules/usb_descriptors.html +0 -176
- package/docs/modules/usb_device.html +0 -156
- package/docs/modules/usb_endpoint.html +0 -164
- package/docs/modules/usb_interface.html +0 -156
- package/docs/modules/webusb.html +0 -165
- package/docs/modules/webusb_mutex.html +0 -156
- package/docs/modules/webusb_typed_event_target.html +0 -156
- package/docs/modules/webusb_webusb_device.html +0 -156
- package/docs/modules.html +0 -156
- 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/tsc/webusb/typed-event-target.ts +0 -23
package/tsc/webusb/index.ts
CHANGED
|
@@ -1,54 +1,148 @@
|
|
|
1
1
|
import * as usb from '../usb';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
2
3
|
import { WebUSBDevice } from './webusb-device';
|
|
3
|
-
import { TypedEventTarget } from './typed-event-target';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* USB Options
|
|
7
7
|
*/
|
|
8
8
|
export interface USBOptions {
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Optional `device found` callback function to allow the user to select a device
|
|
11
11
|
*/
|
|
12
|
-
devicesFound?: (devices:
|
|
13
|
-
}
|
|
12
|
+
devicesFound?: (devices: USBDevice[]) => Promise<USBDevice | void>;
|
|
14
13
|
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
vendorId?: number;
|
|
20
|
-
productId?: number;
|
|
21
|
-
serialNumber?: string;
|
|
22
|
-
}
|
|
14
|
+
/**
|
|
15
|
+
* Optional array of preconfigured allowed devices
|
|
16
|
+
*/
|
|
17
|
+
allowedDevices?: USBDeviceFilter[];
|
|
23
18
|
|
|
24
|
-
/**
|
|
25
|
-
* @hidden
|
|
26
|
-
*/
|
|
27
|
-
export type USBEvents = {
|
|
28
19
|
/**
|
|
29
|
-
*
|
|
20
|
+
* Optional flag to automatically allow all devices
|
|
30
21
|
*/
|
|
31
|
-
|
|
22
|
+
allowAllDevices?: boolean;
|
|
23
|
+
|
|
32
24
|
/**
|
|
33
|
-
*
|
|
25
|
+
* Optional timeout (in milliseconds) to use for the device control transfers
|
|
34
26
|
*/
|
|
35
|
-
|
|
36
|
-
}
|
|
27
|
+
deviceTimeout?: number;
|
|
28
|
+
}
|
|
37
29
|
|
|
38
|
-
export class WebUSB
|
|
30
|
+
export class WebUSB implements USB {
|
|
39
31
|
|
|
40
|
-
|
|
32
|
+
protected emitter = new EventEmitter();
|
|
33
|
+
protected knownDevices: Map<string, USBDevice> = new Map();
|
|
34
|
+
protected allowedDevices: USBDeviceFilter[];
|
|
41
35
|
|
|
42
36
|
constructor(private options: USBOptions = {}) {
|
|
43
|
-
|
|
37
|
+
this.allowedDevices = options.allowedDevices || [];
|
|
38
|
+
|
|
39
|
+
const deviceConnectCallback = async (device: usb.Device) => {
|
|
40
|
+
const webDevice = await WebUSBDevice.createInstance(device);
|
|
41
|
+
|
|
42
|
+
// When connected, emit an event if it is an allowed device
|
|
43
|
+
if (webDevice && this.isAllowedDevice(webDevice)) {
|
|
44
|
+
const deviceId = this.getDeviceId(device);
|
|
45
|
+
if (deviceId) {
|
|
46
|
+
this.knownDevices.set(deviceId, webDevice);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const event = {
|
|
50
|
+
type: 'connect',
|
|
51
|
+
device: webDevice
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
this.emitter.emit('connect', event);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const deviceDisconnectCallback = async (device: usb.Device) => {
|
|
59
|
+
const deviceId = this.getDeviceId(device);
|
|
60
|
+
|
|
61
|
+
// When disconnected, emit an event if the device was a known allowed device
|
|
62
|
+
if (deviceId !== undefined && this.knownDevices.has(deviceId)) {
|
|
63
|
+
const webDevice = this.knownDevices.get(deviceId);
|
|
64
|
+
|
|
65
|
+
if (webDevice && this.isAllowedDevice(webDevice)) {
|
|
66
|
+
const event = {
|
|
67
|
+
type: 'disconnect',
|
|
68
|
+
device: webDevice
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
this.emitter.emit('disconnect', event);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
this.emitter.on('newListener', event => {
|
|
77
|
+
const listenerCount = this.emitter.listenerCount(event);
|
|
78
|
+
|
|
79
|
+
if (listenerCount !== 0) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (event === 'connect') {
|
|
84
|
+
usb.addListener('attach', deviceConnectCallback);
|
|
85
|
+
} else if (event === 'disconnect') {
|
|
86
|
+
usb.addListener('detach', deviceDisconnectCallback);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
this.emitter.on('removeListener', event => {
|
|
91
|
+
const listenerCount = this.emitter.listenerCount(event);
|
|
92
|
+
|
|
93
|
+
if (listenerCount !== 0) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (event === 'connect') {
|
|
98
|
+
usb.removeListener('attach', deviceConnectCallback);
|
|
99
|
+
} else if (event === 'disconnect') {
|
|
100
|
+
usb.removeListener('detach', deviceDisconnectCallback);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private _onconnect: ((ev: USBConnectionEvent) => void) | undefined;
|
|
106
|
+
public set onconnect(fn: (ev: USBConnectionEvent) => void) {
|
|
107
|
+
if (this._onconnect) {
|
|
108
|
+
this.removeEventListener('connect', this._onconnect);
|
|
109
|
+
this._onconnect = undefined;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (fn) {
|
|
113
|
+
this._onconnect = fn;
|
|
114
|
+
this.addEventListener('connect', this._onconnect);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private _ondisconnect: ((ev: USBConnectionEvent) => void) | undefined;
|
|
119
|
+
public set ondisconnect(fn: (ev: USBConnectionEvent) => void) {
|
|
120
|
+
if (this._ondisconnect) {
|
|
121
|
+
this.removeEventListener('disconnect', this._ondisconnect);
|
|
122
|
+
this._ondisconnect = undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (fn) {
|
|
126
|
+
this._ondisconnect = fn;
|
|
127
|
+
this.addEventListener('disconnect', this._ondisconnect);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public addEventListener(type: 'connect' | 'disconnect', listener: (this: this, ev: USBConnectionEvent) => void): void;
|
|
132
|
+
public addEventListener(type: 'connect' | 'disconnect', listener: EventListener): void;
|
|
133
|
+
public addEventListener(type: string, listener: (ev: USBConnectionEvent) => void): void {
|
|
134
|
+
this.emitter.addListener(type, listener);
|
|
44
135
|
}
|
|
45
136
|
|
|
46
|
-
public
|
|
47
|
-
|
|
137
|
+
public removeEventListener(type: 'connect' | 'disconnect', callback: (this: this, ev: USBConnectionEvent) => void): void;
|
|
138
|
+
public removeEventListener(type: 'connect' | 'disconnect', callback: EventListener): void;
|
|
139
|
+
public removeEventListener(type: string, callback: (this: this, ev: USBConnectionEvent) => void): void {
|
|
140
|
+
this.emitter.removeListener(type, callback);
|
|
48
141
|
}
|
|
49
142
|
|
|
50
|
-
public
|
|
51
|
-
|
|
143
|
+
public dispatchEvent(_event: Event): boolean {
|
|
144
|
+
// Don't dispatch from here
|
|
145
|
+
return false;
|
|
52
146
|
}
|
|
53
147
|
|
|
54
148
|
/**
|
|
@@ -105,7 +199,7 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
105
199
|
throw new Error('selected device not found');
|
|
106
200
|
}
|
|
107
201
|
|
|
108
|
-
if (!this.
|
|
202
|
+
if (!this.isAllowedDevice(device)) {
|
|
109
203
|
this.allowedDevices.push({
|
|
110
204
|
vendorId: device.vendorId,
|
|
111
205
|
productId: device.productId,
|
|
@@ -114,7 +208,7 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
114
208
|
}
|
|
115
209
|
|
|
116
210
|
return device;
|
|
117
|
-
} catch(error) {
|
|
211
|
+
} catch (error) {
|
|
118
212
|
throw new Error(`requestDevice error: ${error}`);
|
|
119
213
|
}
|
|
120
214
|
}
|
|
@@ -124,47 +218,54 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
124
218
|
* @returns Promise containing an array of devices
|
|
125
219
|
*/
|
|
126
220
|
public async getDevices(): Promise<USBDevice[]> {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
221
|
+
let preFilters: USBDeviceFilter[] | undefined;
|
|
222
|
+
|
|
223
|
+
if (!this.options.allowAllDevices) {
|
|
224
|
+
// Create pre-filters
|
|
225
|
+
preFilters = this.allowedDevices.map(device => ({
|
|
226
|
+
vendorId: device.vendorId || undefined,
|
|
227
|
+
productId: device.productId || undefined,
|
|
228
|
+
serialNumber: device.serialNumber || undefined
|
|
229
|
+
}));
|
|
230
|
+
}
|
|
133
231
|
|
|
134
232
|
// Refresh devices and filter for allowed ones
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
for (const i in this.allowedDevices) {
|
|
138
|
-
if (this.isSameDevice(device, this.allowedDevices[i])) {
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return false;
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
return devices;
|
|
233
|
+
const devices = await this.loadDevices(preFilters);
|
|
234
|
+
return devices.filter(device => this.isAllowedDevice(device));
|
|
147
235
|
}
|
|
148
236
|
|
|
149
|
-
private async loadDevices(preFilters?:
|
|
237
|
+
private async loadDevices(preFilters?: USBDeviceFilter[]): Promise<USBDevice[]> {
|
|
150
238
|
let devices = usb.getDeviceList();
|
|
151
239
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
devices = this.preFilterDevices(devices, preFilters);
|
|
155
|
-
}
|
|
240
|
+
// Pre-filter devices
|
|
241
|
+
devices = this.preFilterDevices(devices, preFilters);
|
|
156
242
|
|
|
157
243
|
const webDevices: USBDevice[] = [];
|
|
158
244
|
|
|
159
245
|
for (const device of devices) {
|
|
246
|
+
if (this.options.deviceTimeout) {
|
|
247
|
+
device.timeout = this.options.deviceTimeout;
|
|
248
|
+
}
|
|
249
|
+
|
|
160
250
|
const webDevice = await WebUSBDevice.createInstance(device);
|
|
161
|
-
|
|
251
|
+
if (webDevice) {
|
|
252
|
+
webDevices.push(webDevice);
|
|
253
|
+
|
|
254
|
+
const deviceId = this.getDeviceId(device);
|
|
255
|
+
if (deviceId) {
|
|
256
|
+
this.knownDevices.set(deviceId, webDevice);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
162
259
|
}
|
|
163
260
|
|
|
164
261
|
return webDevices;
|
|
165
262
|
}
|
|
166
263
|
|
|
167
|
-
private preFilterDevices(devices:
|
|
264
|
+
private preFilterDevices(devices: usb.Device[], preFilters?: USBDeviceFilter[]): usb.Device[] {
|
|
265
|
+
if (!preFilters || !preFilters.length) {
|
|
266
|
+
return devices;
|
|
267
|
+
}
|
|
268
|
+
|
|
168
269
|
// Just pre-filter on vid/pid
|
|
169
270
|
return devices.filter(device => preFilters.some(filter => {
|
|
170
271
|
// Vendor
|
|
@@ -178,28 +279,11 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
178
279
|
}));
|
|
179
280
|
}
|
|
180
281
|
|
|
181
|
-
private
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
&& device1.serialNumber === device2.serialNumber);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private replaceAllowedDevice(device: USBDevice): boolean {
|
|
188
|
-
for (const i in this.allowedDevices) {
|
|
189
|
-
if (this.isSameDevice(device, this.allowedDevices[i])) {
|
|
190
|
-
this.allowedDevices[i] = {
|
|
191
|
-
vendorId: device.vendorId,
|
|
192
|
-
productId: device.productId,
|
|
193
|
-
serialNumber: device.serialNumber
|
|
194
|
-
};
|
|
195
|
-
return true;
|
|
196
|
-
}
|
|
282
|
+
private filterDevice(options: USBDeviceRequestOptions, device: USBDevice): boolean {
|
|
283
|
+
if (!options.filters || !options.filters.length) {
|
|
284
|
+
return true;
|
|
197
285
|
}
|
|
198
286
|
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
private filterDevice(options: USBDeviceRequestOptions, device: USBDevice): boolean {
|
|
203
287
|
return options.filters.some(filter => {
|
|
204
288
|
// Vendor
|
|
205
289
|
if (filter.vendorId && filter.vendorId !== device.vendorId) return false;
|
|
@@ -248,4 +332,32 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
248
332
|
return true;
|
|
249
333
|
});
|
|
250
334
|
}
|
|
335
|
+
|
|
336
|
+
private getDeviceId(device: usb.Device): string | undefined {
|
|
337
|
+
if (device.busNumber === undefined || device.deviceAddress === undefined) {
|
|
338
|
+
return undefined;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return `${device.busNumber}.${device.deviceAddress}`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
private isAllowedDevice(device: USBDeviceFilter): boolean {
|
|
345
|
+
if (this.options.allowAllDevices) {
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const isSameDevice = (device1: USBDeviceFilter, device2: USBDeviceFilter): boolean => {
|
|
350
|
+
return (device1.productId === device2.productId
|
|
351
|
+
&& device1.vendorId === device2.vendorId
|
|
352
|
+
&& device1.serialNumber === device2.serialNumber);
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
for (const i in this.allowedDevices) {
|
|
356
|
+
if (isSameDevice(device, this.allowedDevices[i])) {
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
251
363
|
}
|
|
@@ -12,10 +12,14 @@ const ENDPOINT_HALT = 0x00;
|
|
|
12
12
|
* Wrapper to make a node-usb device look like a webusb device
|
|
13
13
|
*/
|
|
14
14
|
export class WebUSBDevice implements USBDevice {
|
|
15
|
-
public static async createInstance(device: usb.Device): Promise<WebUSBDevice> {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
public static async createInstance(device: usb.Device): Promise<WebUSBDevice | undefined> {
|
|
16
|
+
try {
|
|
17
|
+
const instance = new WebUSBDevice(device);
|
|
18
|
+
await instance.initialize();
|
|
19
|
+
return instance;
|
|
20
|
+
} catch {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
public readonly usbVersionMajor: number;
|
|
@@ -98,9 +102,9 @@ export class WebUSBDevice implements USBDevice {
|
|
|
98
102
|
// Re-create the USBInterface to set the claimed attribute
|
|
99
103
|
this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
|
|
100
104
|
interfaceNumber: iface.interfaceNumber,
|
|
101
|
-
alternate
|
|
102
|
-
alternates
|
|
103
|
-
claimed
|
|
105
|
+
alternate: iface.alternate,
|
|
106
|
+
alternates: iface.alternates,
|
|
107
|
+
claimed: false
|
|
104
108
|
};
|
|
105
109
|
}
|
|
106
110
|
}
|
|
@@ -128,7 +132,7 @@ export class WebUSBDevice implements USBDevice {
|
|
|
128
132
|
return;
|
|
129
133
|
}
|
|
130
134
|
|
|
131
|
-
const config =
|
|
135
|
+
const config = this.configurations.find(configuration => configuration.configurationValue === configurationValue);
|
|
132
136
|
if (!config) {
|
|
133
137
|
throw new Error('selectConfiguration error: configuration not found');
|
|
134
138
|
}
|
|
@@ -171,9 +175,9 @@ export class WebUSBDevice implements USBDevice {
|
|
|
171
175
|
// Re-create the USBInterface to set the claimed attribute
|
|
172
176
|
this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
|
|
173
177
|
interfaceNumber,
|
|
174
|
-
alternate
|
|
175
|
-
alternates
|
|
176
|
-
claimed
|
|
178
|
+
alternate: iface.alternate,
|
|
179
|
+
alternates: iface.alternates,
|
|
180
|
+
claimed: true
|
|
177
181
|
};
|
|
178
182
|
} catch (error) {
|
|
179
183
|
throw new Error(`claimInterface error: ${error}`);
|
|
@@ -194,9 +198,9 @@ export class WebUSBDevice implements USBDevice {
|
|
|
194
198
|
// Re-create the USBInterface to set the claimed attribute
|
|
195
199
|
this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
|
|
196
200
|
interfaceNumber,
|
|
197
|
-
alternate
|
|
198
|
-
alternates
|
|
199
|
-
claimed
|
|
201
|
+
alternate: iface.alternate,
|
|
202
|
+
alternates: iface.alternates,
|
|
203
|
+
claimed: false
|
|
200
204
|
};
|
|
201
205
|
}
|
|
202
206
|
}
|
|
@@ -275,7 +279,7 @@ export class WebUSBDevice implements USBDevice {
|
|
|
275
279
|
const type = this.controlTransferParamsToType(setup, usb.LIBUSB_ENDPOINT_OUT);
|
|
276
280
|
const controlTransfer = promisify(this.device.controlTransfer).bind(this.device);
|
|
277
281
|
const buffer = data ? Buffer.from(data) : Buffer.alloc(0);
|
|
278
|
-
const bytesWritten = <number>
|
|
282
|
+
const bytesWritten = <number>await controlTransfer(type, setup.request, setup.value, setup.index, buffer);
|
|
279
283
|
|
|
280
284
|
return {
|
|
281
285
|
bytesWritten,
|
|
@@ -387,13 +391,20 @@ export class WebUSBDevice implements USBDevice {
|
|
|
387
391
|
private async initialize(): Promise<void> {
|
|
388
392
|
try {
|
|
389
393
|
await this.deviceMutex.lock();
|
|
390
|
-
|
|
394
|
+
|
|
395
|
+
if (!this.opened) {
|
|
396
|
+
this.device.open();
|
|
397
|
+
}
|
|
398
|
+
|
|
391
399
|
this.manufacturerName = await this.getStringDescriptor(this.device.deviceDescriptor.iManufacturer);
|
|
392
400
|
this.productName = await this.getStringDescriptor(this.device.deviceDescriptor.iProduct);
|
|
393
401
|
this.serialNumber = await this.getStringDescriptor(this.device.deviceDescriptor.iSerialNumber);
|
|
394
402
|
this.configurations = await this.getConfigurations();
|
|
395
403
|
} finally {
|
|
396
|
-
this.
|
|
404
|
+
if (this.opened) {
|
|
405
|
+
this.device.close();
|
|
406
|
+
}
|
|
407
|
+
|
|
397
408
|
this.deviceMutex.unlock();
|
|
398
409
|
}
|
|
399
410
|
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
name: prebuild
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- master
|
|
7
|
-
tags:
|
|
8
|
-
- '*'
|
|
9
|
-
pull_request:
|
|
10
|
-
branches:
|
|
11
|
-
- master
|
|
12
|
-
workflow_dispatch:
|
|
13
|
-
|
|
14
|
-
jobs:
|
|
15
|
-
prebuild:
|
|
16
|
-
strategy:
|
|
17
|
-
matrix:
|
|
18
|
-
config:
|
|
19
|
-
- { os: macos-latest, arch: x64 }
|
|
20
|
-
- { os: ubuntu-18.04, arch: x64 }
|
|
21
|
-
- { os: windows-latest, arch: x64 }
|
|
22
|
-
- { os: windows-latest, arch: ia32 }
|
|
23
|
-
runs-on: ${{ matrix.config.os }}
|
|
24
|
-
steps:
|
|
25
|
-
- if: matrix.config.os == 'ubuntu-18.04'
|
|
26
|
-
run: |
|
|
27
|
-
sudo apt-get update
|
|
28
|
-
sudo apt-get install libudev-dev
|
|
29
|
-
- uses: actions/setup-node@v2
|
|
30
|
-
with:
|
|
31
|
-
node-version: 14.x
|
|
32
|
-
- uses: actions/checkout@v2
|
|
33
|
-
with:
|
|
34
|
-
submodules: recursive
|
|
35
|
-
- run: yarn
|
|
36
|
-
- run: yarn run prebuild -- -a ${{ matrix.config.arch }}
|
|
37
|
-
- if: startsWith(github.ref, 'refs/tags/')
|
|
38
|
-
shell: bash
|
|
39
|
-
env:
|
|
40
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
41
|
-
run: |
|
|
42
|
-
assets=()
|
|
43
|
-
for asset in ./prebuilds/*; do
|
|
44
|
-
assets+=("-a" "$asset")
|
|
45
|
-
done
|
|
46
|
-
tag_name="${GITHUB_REF##*/}"
|
|
47
|
-
hub release create -m "$tag_name" "$tag_name" || true
|
|
48
|
-
hub release edit "${assets[@]}" -m "" "$tag_name"
|