usb 2.0.0-alpha.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitmodules +1 -1
- package/CHANGELOG.md +100 -0
- package/README.md +573 -0
- package/binding.gyp +12 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +14 -8
- 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.js +86 -2
- package/dist/usb/index.js.map +1 -1
- package/dist/usb/interface.js.map +1 -1
- package/dist/webusb/index.d.ts +32 -19
- package/dist/webusb/index.js +163 -67
- package/dist/webusb/index.js.map +1 -1
- package/dist/webusb/webusb-device.d.ts +1 -1
- package/dist/webusb/webusb-device.js +27 -15
- 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 +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 +21 -2
- package/package.json +18 -13
- package/prebuilds/android-arm/node.napi.node +0 -0
- package/prebuilds/android-arm64/node.napi.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.node +0 -0
- package/prebuilds/linux-arm64/node.napi.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/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 +6 -0
- package/tsc/index.ts +13 -7
- package/tsc/usb/bindings.ts +19 -1
- package/tsc/usb/index.ts +67 -19
- package/tsc/usb/interface.ts +2 -2
- package/tsc/webusb/index.ts +197 -74
- package/tsc/webusb/webusb-device.ts +30 -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 -304
- package/docs/modules/usb.html +0 -173
- package/docs/modules/usb_bindings.html +0 -2248
- 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,159 @@
|
|
|
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
|
-
|
|
27
|
+
deviceTimeout?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Convenience method to get the WebUSB interface available
|
|
32
|
+
*/
|
|
33
|
+
export const getWebUsb = (): USB => {
|
|
34
|
+
if (navigator && navigator.usb) {
|
|
35
|
+
return navigator.usb;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return new WebUSB();
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
export class WebUSB
|
|
41
|
+
export class WebUSB implements USB {
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
protected emitter = new EventEmitter();
|
|
44
|
+
protected knownDevices: Map<string, USBDevice> = new Map();
|
|
45
|
+
protected allowedDevices: USBDeviceFilter[];
|
|
41
46
|
|
|
42
47
|
constructor(private options: USBOptions = {}) {
|
|
43
|
-
|
|
48
|
+
this.allowedDevices = options.allowedDevices || [];
|
|
49
|
+
|
|
50
|
+
const deviceConnectCallback = async (device: usb.Device) => {
|
|
51
|
+
const webDevice = await WebUSBDevice.createInstance(device);
|
|
52
|
+
|
|
53
|
+
// When connected, emit an event if it is an allowed device
|
|
54
|
+
if (webDevice && this.isAllowedDevice(webDevice)) {
|
|
55
|
+
const deviceId = this.getDeviceId(device);
|
|
56
|
+
if (deviceId) {
|
|
57
|
+
this.knownDevices.set(deviceId, webDevice);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const event = {
|
|
61
|
+
type: 'connect',
|
|
62
|
+
device: webDevice
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
this.emitter.emit('connect', event);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const deviceDisconnectCallback = async (device: usb.Device) => {
|
|
70
|
+
const deviceId = this.getDeviceId(device);
|
|
71
|
+
|
|
72
|
+
// When disconnected, emit an event if the device was a known allowed device
|
|
73
|
+
if (deviceId !== undefined && this.knownDevices.has(deviceId)) {
|
|
74
|
+
const webDevice = this.knownDevices.get(deviceId);
|
|
75
|
+
|
|
76
|
+
if (webDevice && this.isAllowedDevice(webDevice)) {
|
|
77
|
+
const event = {
|
|
78
|
+
type: 'disconnect',
|
|
79
|
+
device: webDevice
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
this.emitter.emit('disconnect', event);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
this.emitter.on('newListener', event => {
|
|
88
|
+
const listenerCount = this.emitter.listenerCount(event);
|
|
89
|
+
|
|
90
|
+
if (listenerCount !== 0) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (event === 'connect') {
|
|
95
|
+
usb.addListener('attach', deviceConnectCallback);
|
|
96
|
+
} else if (event === 'disconnect') {
|
|
97
|
+
usb.addListener('detach', deviceDisconnectCallback);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
this.emitter.on('removeListener', event => {
|
|
102
|
+
const listenerCount = this.emitter.listenerCount(event);
|
|
103
|
+
|
|
104
|
+
if (listenerCount !== 0) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (event === 'connect') {
|
|
109
|
+
usb.removeListener('attach', deviceConnectCallback);
|
|
110
|
+
} else if (event === 'disconnect') {
|
|
111
|
+
usb.removeListener('detach', deviceDisconnectCallback);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private _onconnect: ((ev: USBConnectionEvent) => void) | undefined;
|
|
117
|
+
public set onconnect(fn: (ev: USBConnectionEvent) => void) {
|
|
118
|
+
if (this._onconnect) {
|
|
119
|
+
this.removeEventListener('connect', this._onconnect);
|
|
120
|
+
this._onconnect = undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (fn) {
|
|
124
|
+
this._onconnect = fn;
|
|
125
|
+
this.addEventListener('connect', this._onconnect);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private _ondisconnect: ((ev: USBConnectionEvent) => void) | undefined;
|
|
130
|
+
public set ondisconnect(fn: (ev: USBConnectionEvent) => void) {
|
|
131
|
+
if (this._ondisconnect) {
|
|
132
|
+
this.removeEventListener('disconnect', this._ondisconnect);
|
|
133
|
+
this._ondisconnect = undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (fn) {
|
|
137
|
+
this._ondisconnect = fn;
|
|
138
|
+
this.addEventListener('disconnect', this._ondisconnect);
|
|
139
|
+
}
|
|
44
140
|
}
|
|
45
141
|
|
|
46
|
-
public
|
|
47
|
-
|
|
142
|
+
public addEventListener(type: 'connect' | 'disconnect', listener: (this: this, ev: USBConnectionEvent) => void): void;
|
|
143
|
+
public addEventListener(type: 'connect' | 'disconnect', listener: EventListener): void;
|
|
144
|
+
public addEventListener(type: string, listener: (ev: USBConnectionEvent) => void): void {
|
|
145
|
+
this.emitter.addListener(type, listener);
|
|
48
146
|
}
|
|
49
147
|
|
|
50
|
-
public
|
|
51
|
-
|
|
148
|
+
public removeEventListener(type: 'connect' | 'disconnect', callback: (this: this, ev: USBConnectionEvent) => void): void;
|
|
149
|
+
public removeEventListener(type: 'connect' | 'disconnect', callback: EventListener): void;
|
|
150
|
+
public removeEventListener(type: string, callback: (this: this, ev: USBConnectionEvent) => void): void {
|
|
151
|
+
this.emitter.removeListener(type, callback);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
public dispatchEvent(_event: Event): boolean {
|
|
155
|
+
// Don't dispatch from here
|
|
156
|
+
return false;
|
|
52
157
|
}
|
|
53
158
|
|
|
54
159
|
/**
|
|
@@ -105,7 +210,7 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
105
210
|
throw new Error('selected device not found');
|
|
106
211
|
}
|
|
107
212
|
|
|
108
|
-
if (!this.
|
|
213
|
+
if (!this.isAllowedDevice(device)) {
|
|
109
214
|
this.allowedDevices.push({
|
|
110
215
|
vendorId: device.vendorId,
|
|
111
216
|
productId: device.productId,
|
|
@@ -114,7 +219,7 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
114
219
|
}
|
|
115
220
|
|
|
116
221
|
return device;
|
|
117
|
-
} catch(error) {
|
|
222
|
+
} catch (error) {
|
|
118
223
|
throw new Error(`requestDevice error: ${error}`);
|
|
119
224
|
}
|
|
120
225
|
}
|
|
@@ -124,47 +229,54 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
124
229
|
* @returns Promise containing an array of devices
|
|
125
230
|
*/
|
|
126
231
|
public async getDevices(): Promise<USBDevice[]> {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
232
|
+
let preFilters: USBDeviceFilter[] | undefined;
|
|
233
|
+
|
|
234
|
+
if (!this.options.allowAllDevices) {
|
|
235
|
+
// Create pre-filters
|
|
236
|
+
preFilters = this.allowedDevices.map(device => ({
|
|
237
|
+
vendorId: device.vendorId || undefined,
|
|
238
|
+
productId: device.productId || undefined,
|
|
239
|
+
serialNumber: device.serialNumber || undefined
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
133
242
|
|
|
134
243
|
// 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;
|
|
244
|
+
const devices = await this.loadDevices(preFilters);
|
|
245
|
+
return devices.filter(device => this.isAllowedDevice(device));
|
|
147
246
|
}
|
|
148
247
|
|
|
149
|
-
private async loadDevices(preFilters?:
|
|
248
|
+
private async loadDevices(preFilters?: USBDeviceFilter[]): Promise<USBDevice[]> {
|
|
150
249
|
let devices = usb.getDeviceList();
|
|
151
250
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
devices = this.preFilterDevices(devices, preFilters);
|
|
155
|
-
}
|
|
251
|
+
// Pre-filter devices
|
|
252
|
+
devices = this.preFilterDevices(devices, preFilters);
|
|
156
253
|
|
|
157
254
|
const webDevices: USBDevice[] = [];
|
|
158
255
|
|
|
159
256
|
for (const device of devices) {
|
|
257
|
+
if (this.options.deviceTimeout) {
|
|
258
|
+
device.timeout = this.options.deviceTimeout;
|
|
259
|
+
}
|
|
260
|
+
|
|
160
261
|
const webDevice = await WebUSBDevice.createInstance(device);
|
|
161
|
-
|
|
262
|
+
if (webDevice) {
|
|
263
|
+
webDevices.push(webDevice);
|
|
264
|
+
|
|
265
|
+
const deviceId = this.getDeviceId(device);
|
|
266
|
+
if (deviceId) {
|
|
267
|
+
this.knownDevices.set(deviceId, webDevice);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
162
270
|
}
|
|
163
271
|
|
|
164
272
|
return webDevices;
|
|
165
273
|
}
|
|
166
274
|
|
|
167
|
-
private preFilterDevices(devices:
|
|
275
|
+
private preFilterDevices(devices: usb.Device[], preFilters?: USBDeviceFilter[]): usb.Device[] {
|
|
276
|
+
if (!preFilters || !preFilters.length) {
|
|
277
|
+
return devices;
|
|
278
|
+
}
|
|
279
|
+
|
|
168
280
|
// Just pre-filter on vid/pid
|
|
169
281
|
return devices.filter(device => preFilters.some(filter => {
|
|
170
282
|
// Vendor
|
|
@@ -178,28 +290,11 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
178
290
|
}));
|
|
179
291
|
}
|
|
180
292
|
|
|
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
|
-
}
|
|
293
|
+
private filterDevice(options: USBDeviceRequestOptions, device: USBDevice): boolean {
|
|
294
|
+
if (!options.filters || !options.filters.length) {
|
|
295
|
+
return true;
|
|
197
296
|
}
|
|
198
297
|
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
private filterDevice(options: USBDeviceRequestOptions, device: USBDevice): boolean {
|
|
203
298
|
return options.filters.some(filter => {
|
|
204
299
|
// Vendor
|
|
205
300
|
if (filter.vendorId && filter.vendorId !== device.vendorId) return false;
|
|
@@ -248,4 +343,32 @@ export class WebUSB extends TypedEventTarget<USBEvents> implements USB {
|
|
|
248
343
|
return true;
|
|
249
344
|
});
|
|
250
345
|
}
|
|
346
|
+
|
|
347
|
+
private getDeviceId(device: usb.Device): string | undefined {
|
|
348
|
+
if (device.busNumber === undefined || device.deviceAddress === undefined) {
|
|
349
|
+
return undefined;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return `${device.busNumber}.${device.deviceAddress}`;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
private isAllowedDevice(device: USBDeviceFilter): boolean {
|
|
356
|
+
if (this.options.allowAllDevices) {
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const isSameDevice = (device1: USBDeviceFilter, device2: USBDeviceFilter): boolean => {
|
|
361
|
+
return (device1.productId === device2.productId
|
|
362
|
+
&& device1.vendorId === device2.vendorId
|
|
363
|
+
&& device1.serialNumber === device2.serialNumber);
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
for (const i in this.allowedDevices) {
|
|
367
|
+
if (isSameDevice(device, this.allowedDevices[i])) {
|
|
368
|
+
return true;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
251
374
|
}
|
|
@@ -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,22 @@ 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();
|
|
403
|
+
} catch (error) {
|
|
404
|
+
throw new Error(`initialize error: ${error}`);
|
|
395
405
|
} finally {
|
|
396
|
-
this.
|
|
406
|
+
if (this.opened) {
|
|
407
|
+
this.device.close();
|
|
408
|
+
}
|
|
409
|
+
|
|
397
410
|
this.deviceMutex.unlock();
|
|
398
411
|
}
|
|
399
412
|
}
|
|
@@ -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"
|