usb 1.9.1 → 2.0.1
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/.eslintignore +4 -0
- package/.eslintrc.json +87 -0
- package/.gitattributes +1 -0
- package/.vscode/launch.json +15 -0
- package/.vscode/tasks.json +23 -0
- package/CHANGELOG.md +13 -0
- package/README.md +400 -175
- package/dist/index.d.ts +17 -0
- package/dist/index.js +133 -0
- package/dist/index.js.map +1 -0
- package/dist/usb/bindings.d.ts +253 -0
- package/dist/usb/bindings.js +10 -0
- package/dist/usb/bindings.js.map +1 -0
- package/dist/usb/capability.d.ts +14 -0
- package/dist/usb/capability.js +18 -0
- package/dist/usb/capability.js.map +1 -0
- package/dist/usb/descriptors.d.ts +129 -0
- package/dist/usb/descriptors.js +3 -0
- package/dist/usb/descriptors.js.map +1 -0
- package/dist/usb/device.d.ts +94 -0
- package/dist/usb/device.js +300 -0
- package/dist/usb/device.js.map +1 -0
- package/dist/usb/endpoint.d.ts +91 -0
- package/dist/usb/endpoint.js +236 -0
- package/dist/usb/endpoint.js.map +1 -0
- package/dist/usb/index.d.ts +25 -0
- package/dist/usb/index.js +116 -0
- package/dist/usb/index.js.map +1 -0
- package/dist/usb/interface.d.ts +78 -0
- package/dist/usb/interface.js +137 -0
- package/dist/usb/interface.js.map +1 -0
- package/dist/webusb/index.d.ts +56 -0
- package/dist/webusb/index.js +412 -0
- package/dist/webusb/index.js.map +1 -0
- package/dist/webusb/mutex.d.ts +22 -0
- package/dist/webusb/mutex.js +89 -0
- package/dist/webusb/mutex.js.map +1 -0
- package/dist/webusb/webusb-device.d.ts +49 -0
- package/dist/webusb/webusb-device.js +888 -0
- package/dist/webusb/webusb-device.js.map +1 -0
- package/package.json +28 -15
- 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 +6 -6
- package/test/usb.coffee +13 -7
- package/test/webusb.coffee +189 -0
- package/tsc/index.ts +67 -0
- package/tsc/usb/bindings.ts +304 -0
- package/tsc/usb/capability.ts +22 -0
- package/tsc/usb/descriptors.ts +180 -0
- package/tsc/usb/device.ts +325 -0
- package/tsc/usb/endpoint.ts +228 -0
- package/tsc/usb/index.ts +111 -0
- package/tsc/usb/interface.ts +172 -0
- package/tsc/webusb/index.ts +363 -0
- package/tsc/webusb/mutex.ts +38 -0
- package/tsc/webusb/webusb-device.ts +534 -0
- package/tsconfig.json +17 -0
- package/typedoc.json +9 -0
- package/usb.js +0 -573
package/usb.js
DELETED
|
@@ -1,573 +0,0 @@
|
|
|
1
|
-
var usb = exports = module.exports = require('node-gyp-build')(__dirname);
|
|
2
|
-
var events = require('events');
|
|
3
|
-
var util = require('util');
|
|
4
|
-
|
|
5
|
-
var isBuffer = function(obj) {
|
|
6
|
-
return obj && obj instanceof Uint8Array
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
if (usb.INIT_ERROR) {
|
|
10
|
-
console.warn("Failed to initialize libusb.")
|
|
11
|
-
usb.Device = function () { throw new Error("Device cannot be instantiated directly.") };
|
|
12
|
-
usb.Transfer = function () { throw new Error("Transfer cannot be instantiated directly.") };
|
|
13
|
-
usb.setDebugLevel = function () { };
|
|
14
|
-
usb.getDeviceList = function () { return []; };
|
|
15
|
-
usb._enableHotplugEvents = function () { };
|
|
16
|
-
usb._disableHotplugEvents = function () { };
|
|
17
|
-
usb.refHotplugEvents = function () { };
|
|
18
|
-
usb.unrefHotplugEvents = function () { };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
Object.keys(events.EventEmitter.prototype).forEach(function (key) {
|
|
22
|
-
exports[key] = events.EventEmitter.prototype[key];
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// convenience method for finding a device by vendor and product id
|
|
26
|
-
exports.findByIds = function(vid, pid) {
|
|
27
|
-
var devices = usb.getDeviceList()
|
|
28
|
-
|
|
29
|
-
for (var i = 0; i < devices.length; i++) {
|
|
30
|
-
var deviceDesc = devices[i].deviceDescriptor
|
|
31
|
-
if ((deviceDesc.idVendor == vid) && (deviceDesc.idProduct == pid)) {
|
|
32
|
-
return devices[i]
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
usb.Device.prototype.timeout = 1000
|
|
38
|
-
|
|
39
|
-
usb.Device.prototype.open = function(defaultConfig){
|
|
40
|
-
this.__open()
|
|
41
|
-
if (defaultConfig === false) return
|
|
42
|
-
this.interfaces = []
|
|
43
|
-
var len = this.configDescriptor ? this.configDescriptor.interfaces.length : 0
|
|
44
|
-
for (var i=0; i<len; i++){
|
|
45
|
-
this.interfaces[i] = new Interface(this, i)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
usb.Device.prototype.close = function(){
|
|
50
|
-
this.__close()
|
|
51
|
-
this.interfaces = null
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
Object.defineProperty(usb.Device.prototype, "configDescriptor", {
|
|
55
|
-
get: function() {
|
|
56
|
-
try {
|
|
57
|
-
return this._configDescriptor || (this._configDescriptor = this.__getConfigDescriptor())
|
|
58
|
-
} catch(e) {
|
|
59
|
-
// Check descriptor exists
|
|
60
|
-
if (e.errno == usb.LIBUSB_ERROR_NOT_FOUND) return null;
|
|
61
|
-
throw e;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
Object.defineProperty(usb.Device.prototype, "allConfigDescriptors", {
|
|
67
|
-
get: function() {
|
|
68
|
-
try {
|
|
69
|
-
return this._allConfigDescriptors || (this._allConfigDescriptors = this.__getAllConfigDescriptors())
|
|
70
|
-
} catch(e) {
|
|
71
|
-
// Check descriptors exist
|
|
72
|
-
if (e.errno == usb.LIBUSB_ERROR_NOT_FOUND) return [];
|
|
73
|
-
throw e;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
Object.defineProperty(usb.Device.prototype, "parent", {
|
|
79
|
-
get: function() {
|
|
80
|
-
return this._parent || (this._parent = this.__getParent())
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
usb.Device.prototype.interface = function(addr){
|
|
85
|
-
if (!this.interfaces){
|
|
86
|
-
throw new Error("Device must be open before searching for interfaces")
|
|
87
|
-
}
|
|
88
|
-
addr = addr || 0
|
|
89
|
-
for (var i=0; i<this.interfaces.length; i++){
|
|
90
|
-
if (this.interfaces[i].interfaceNumber == addr){
|
|
91
|
-
return this.interfaces[i]
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
var SETUP_SIZE = usb.LIBUSB_CONTROL_SETUP_SIZE
|
|
97
|
-
|
|
98
|
-
usb.Device.prototype.controlTransfer =
|
|
99
|
-
function(bmRequestType, bRequest, wValue, wIndex, data_or_length, callback){
|
|
100
|
-
var self = this
|
|
101
|
-
var isIn = !!(bmRequestType & usb.LIBUSB_ENDPOINT_IN)
|
|
102
|
-
var wLength
|
|
103
|
-
|
|
104
|
-
if (isIn){
|
|
105
|
-
if (!(data_or_length >= 0)){
|
|
106
|
-
throw new TypeError("Expected size number for IN transfer (based on bmRequestType)")
|
|
107
|
-
}
|
|
108
|
-
wLength = data_or_length
|
|
109
|
-
}else{
|
|
110
|
-
if (!isBuffer(data_or_length)){
|
|
111
|
-
throw new TypeError("Expected buffer for OUT transfer (based on bmRequestType)")
|
|
112
|
-
}
|
|
113
|
-
wLength = data_or_length.length
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Buffer for the setup packet
|
|
117
|
-
// http://libusbx.sourceforge.net/api-1.0/structlibusb__control__setup.html
|
|
118
|
-
var buf = Buffer.alloc(wLength + SETUP_SIZE)
|
|
119
|
-
buf.writeUInt8( bmRequestType, 0)
|
|
120
|
-
buf.writeUInt8( bRequest, 1)
|
|
121
|
-
buf.writeUInt16LE(wValue, 2)
|
|
122
|
-
buf.writeUInt16LE(wIndex, 4)
|
|
123
|
-
buf.writeUInt16LE(wLength, 6)
|
|
124
|
-
|
|
125
|
-
if (!isIn){
|
|
126
|
-
buf.set(data_or_length, SETUP_SIZE)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
var transfer = new usb.Transfer(this, 0, usb.LIBUSB_TRANSFER_TYPE_CONTROL, this.timeout,
|
|
130
|
-
function(error, buf, actual){
|
|
131
|
-
if (callback){
|
|
132
|
-
if (isIn){
|
|
133
|
-
callback.call(self, error, buf.slice(SETUP_SIZE, SETUP_SIZE + actual))
|
|
134
|
-
}else{
|
|
135
|
-
callback.call(self, error)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
try {
|
|
142
|
-
transfer.submit(buf)
|
|
143
|
-
} catch (e) {
|
|
144
|
-
if (callback){
|
|
145
|
-
process.nextTick(function() { callback.call(self, e); });
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return this;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
usb.Device.prototype.getStringDescriptor = function (desc_index, callback) {
|
|
152
|
-
var langid = 0x0409;
|
|
153
|
-
var length = 255;
|
|
154
|
-
this.controlTransfer(
|
|
155
|
-
usb.LIBUSB_ENDPOINT_IN,
|
|
156
|
-
usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
|
|
157
|
-
((usb.LIBUSB_DT_STRING << 8) | desc_index),
|
|
158
|
-
langid,
|
|
159
|
-
length,
|
|
160
|
-
function (error, buf) {
|
|
161
|
-
if (error) return callback(error);
|
|
162
|
-
callback(undefined, buf.toString('utf16le', 2));
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
usb.Device.prototype.getBosDescriptor = function (callback) {
|
|
168
|
-
|
|
169
|
-
if (this._bosDescriptor) {
|
|
170
|
-
// Cached descriptor
|
|
171
|
-
return callback(undefined, this._bosDescriptor);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (this.deviceDescriptor.bcdUSB < 0x201) {
|
|
175
|
-
// BOS is only supported from USB 2.0.1
|
|
176
|
-
return callback(undefined, null);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
this.controlTransfer(
|
|
180
|
-
usb.LIBUSB_ENDPOINT_IN,
|
|
181
|
-
usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
|
|
182
|
-
(usb.LIBUSB_DT_BOS << 8),
|
|
183
|
-
0,
|
|
184
|
-
usb.LIBUSB_DT_BOS_SIZE,
|
|
185
|
-
function (error, buffer) {
|
|
186
|
-
if (error) {
|
|
187
|
-
// Check BOS descriptor exists
|
|
188
|
-
if (error.errno == usb.LIBUSB_TRANSFER_STALL) return callback(undefined, null);
|
|
189
|
-
return callback(error, null);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
var totalLength = buffer.readUInt16LE(2);
|
|
193
|
-
this.controlTransfer(
|
|
194
|
-
usb.LIBUSB_ENDPOINT_IN,
|
|
195
|
-
usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
|
|
196
|
-
(usb.LIBUSB_DT_BOS << 8),
|
|
197
|
-
0,
|
|
198
|
-
totalLength,
|
|
199
|
-
function (error, buffer) {
|
|
200
|
-
if (error) {
|
|
201
|
-
// Check BOS descriptor exists
|
|
202
|
-
if (error.errno == usb.LIBUSB_TRANSFER_STALL) return callback(undefined, null);
|
|
203
|
-
return callback(error, null);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
var descriptor = {
|
|
207
|
-
bLength: buffer.readUInt8(0),
|
|
208
|
-
bDescriptorType: buffer.readUInt8(1),
|
|
209
|
-
wTotalLength: buffer.readUInt16LE(2),
|
|
210
|
-
bNumDeviceCaps: buffer.readUInt8(4),
|
|
211
|
-
capabilities: []
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
var i = usb.LIBUSB_DT_BOS_SIZE;
|
|
215
|
-
while (i < descriptor.wTotalLength) {
|
|
216
|
-
var capability = {
|
|
217
|
-
bLength: buffer.readUInt8(i + 0),
|
|
218
|
-
bDescriptorType: buffer.readUInt8(i + 1),
|
|
219
|
-
bDevCapabilityType: buffer.readUInt8(i + 2)
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
capability.dev_capability_data = buffer.slice(i + 3, i + capability.bLength);
|
|
223
|
-
descriptor.capabilities.push(capability);
|
|
224
|
-
i += capability.bLength;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Cache descriptor
|
|
228
|
-
this._bosDescriptor = descriptor;
|
|
229
|
-
callback(undefined, this._bosDescriptor);
|
|
230
|
-
}
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
usb.Device.prototype.getCapabilities = function (callback) {
|
|
237
|
-
var capabilities = [];
|
|
238
|
-
var self = this;
|
|
239
|
-
|
|
240
|
-
this.getBosDescriptor(function(error, descriptor) {
|
|
241
|
-
if (error) return callback(error, null);
|
|
242
|
-
|
|
243
|
-
var len = descriptor ? descriptor.capabilities.length : 0
|
|
244
|
-
for (var i=0; i<len; i++){
|
|
245
|
-
capabilities.push(new Capability(self, i))
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
callback(undefined, capabilities);
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
usb.Device.prototype.setConfiguration = function(desired, cb) {
|
|
253
|
-
var self = this;
|
|
254
|
-
this.__setConfiguration(desired, function(err) {
|
|
255
|
-
if (!err) {
|
|
256
|
-
this.interfaces = []
|
|
257
|
-
var len = this.configDescriptor ? this.configDescriptor.interfaces.length : 0
|
|
258
|
-
for (var i=0; i<len; i++) {
|
|
259
|
-
this.interfaces[i] = new Interface(this, i)
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
cb.call(self, err)
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function Interface(device, id){
|
|
267
|
-
this.device = device
|
|
268
|
-
this.id = id
|
|
269
|
-
this.altSetting = 0;
|
|
270
|
-
this.__refresh()
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
Interface.prototype.__refresh = function(){
|
|
274
|
-
this.descriptor = this.device.configDescriptor.interfaces[this.id][this.altSetting]
|
|
275
|
-
this.interfaceNumber = this.descriptor.bInterfaceNumber
|
|
276
|
-
this.endpoints = []
|
|
277
|
-
var len = this.descriptor.endpoints.length
|
|
278
|
-
for (var i=0; i<len; i++){
|
|
279
|
-
var desc = this.descriptor.endpoints[i]
|
|
280
|
-
var c = (desc.bEndpointAddress&usb.LIBUSB_ENDPOINT_IN)?InEndpoint:OutEndpoint
|
|
281
|
-
this.endpoints[i] = new c(this.device, desc)
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
Interface.prototype.claim = function(){
|
|
286
|
-
this.device.__claimInterface(this.id)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
Interface.prototype.release = function(closeEndpoints, cb){
|
|
290
|
-
var self = this;
|
|
291
|
-
if (typeof closeEndpoints == 'function') {
|
|
292
|
-
cb = closeEndpoints;
|
|
293
|
-
closeEndpoints = null;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (!closeEndpoints || this.endpoints.length == 0) {
|
|
297
|
-
next();
|
|
298
|
-
} else {
|
|
299
|
-
var n = self.endpoints.length;
|
|
300
|
-
self.endpoints.forEach(function (ep, i) {
|
|
301
|
-
if (ep.pollActive) {
|
|
302
|
-
ep.once('end', function () {
|
|
303
|
-
if (--n == 0) next();
|
|
304
|
-
});
|
|
305
|
-
ep.stopPoll();
|
|
306
|
-
} else {
|
|
307
|
-
if (--n == 0) next();
|
|
308
|
-
}
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function next () {
|
|
313
|
-
self.device.__releaseInterface(self.id, function(err){
|
|
314
|
-
if (!err){
|
|
315
|
-
self.altSetting = 0;
|
|
316
|
-
self.__refresh()
|
|
317
|
-
}
|
|
318
|
-
cb.call(self, err)
|
|
319
|
-
})
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
Interface.prototype.isKernelDriverActive = function(){
|
|
324
|
-
return this.device.__isKernelDriverActive(this.id)
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
Interface.prototype.detachKernelDriver = function() {
|
|
328
|
-
return this.device.__detachKernelDriver(this.id)
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
Interface.prototype.attachKernelDriver = function() {
|
|
332
|
-
return this.device.__attachKernelDriver(this.id)
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
Interface.prototype.setAltSetting = function(altSetting, cb){
|
|
337
|
-
var self = this;
|
|
338
|
-
this.device.__setInterface(this.id, altSetting, function(err){
|
|
339
|
-
if (!err){
|
|
340
|
-
self.altSetting = altSetting;
|
|
341
|
-
self.__refresh();
|
|
342
|
-
}
|
|
343
|
-
cb.call(self, err)
|
|
344
|
-
})
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
Interface.prototype.endpoint = function(addr){
|
|
348
|
-
for (var i=0; i<this.endpoints.length; i++){
|
|
349
|
-
if (this.endpoints[i].address == addr){
|
|
350
|
-
return this.endpoints[i]
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
function Capability(device, id){
|
|
356
|
-
this.device = device
|
|
357
|
-
this.id = id
|
|
358
|
-
this.descriptor = this.device._bosDescriptor.capabilities[this.id]
|
|
359
|
-
this.type = this.descriptor.bDevCapabilityType
|
|
360
|
-
this.data = this.descriptor.dev_capability_data
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
function Endpoint(device, descriptor){
|
|
364
|
-
this.device = device
|
|
365
|
-
this.descriptor = descriptor
|
|
366
|
-
this.address = descriptor.bEndpointAddress
|
|
367
|
-
this.transferType = descriptor.bmAttributes&0x03
|
|
368
|
-
}
|
|
369
|
-
util.inherits(Endpoint, events.EventEmitter)
|
|
370
|
-
|
|
371
|
-
Endpoint.prototype.timeout = 0
|
|
372
|
-
|
|
373
|
-
Endpoint.prototype.clearHalt = function(callback){
|
|
374
|
-
return this.device.__clearHalt(this.address, callback);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
Endpoint.prototype.makeTransfer = function(timeout, callback){
|
|
378
|
-
return new usb.Transfer(this.device, this.address, this.transferType, timeout, callback)
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
Endpoint.prototype.startPoll = function(nTransfers, transferSize, callback){
|
|
382
|
-
if (this.pollTransfers){
|
|
383
|
-
throw new Error("Polling already active")
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
nTransfers = nTransfers || 3;
|
|
387
|
-
this.pollTransferSize = transferSize || this.descriptor.wMaxPacketSize;
|
|
388
|
-
this.pollActive = true
|
|
389
|
-
this.pollPending = 0
|
|
390
|
-
|
|
391
|
-
var transfers = []
|
|
392
|
-
for (var i=0; i<nTransfers; i++){
|
|
393
|
-
transfers[i] = this.makeTransfer(0, callback)
|
|
394
|
-
}
|
|
395
|
-
return transfers;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
Endpoint.prototype.stopPoll = function(cb){
|
|
399
|
-
if (!this.pollTransfers) {
|
|
400
|
-
throw new Error('Polling is not active.');
|
|
401
|
-
}
|
|
402
|
-
for (var i=0; i<this.pollTransfers.length; i++){
|
|
403
|
-
try {
|
|
404
|
-
this.pollTransfers[i].cancel()
|
|
405
|
-
} catch (err) {
|
|
406
|
-
this.emit('error', err);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
this.pollActive = false
|
|
410
|
-
if (cb) this.once('end', cb);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
function InEndpoint(device, descriptor){
|
|
414
|
-
Endpoint.call(this, device, descriptor)
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
exports.InEndpoint = InEndpoint
|
|
418
|
-
util.inherits(InEndpoint, Endpoint)
|
|
419
|
-
InEndpoint.prototype.direction = "in"
|
|
420
|
-
|
|
421
|
-
InEndpoint.prototype.transfer = function(length, cb){
|
|
422
|
-
var self = this
|
|
423
|
-
var buffer = Buffer.alloc(length)
|
|
424
|
-
|
|
425
|
-
function callback(error, buf, actual){
|
|
426
|
-
cb.call(self, error, buffer.slice(0, actual))
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
try {
|
|
430
|
-
this.makeTransfer(this.timeout, callback).submit(buffer)
|
|
431
|
-
} catch (e) {
|
|
432
|
-
process.nextTick(function() { cb.call(self, e); });
|
|
433
|
-
}
|
|
434
|
-
return this;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
InEndpoint.prototype.startPoll = function(nTransfers, transferSize){
|
|
438
|
-
var self = this
|
|
439
|
-
this.pollTransfers = InEndpoint.super_.prototype.startPoll.call(this, nTransfers, transferSize, transferDone)
|
|
440
|
-
|
|
441
|
-
function transferDone(error, buf, actual){
|
|
442
|
-
if (!error){
|
|
443
|
-
self.emit("data", buf.slice(0, actual))
|
|
444
|
-
}else if (error.errno != usb.LIBUSB_TRANSFER_CANCELLED){
|
|
445
|
-
self.emit("error", error)
|
|
446
|
-
self.stopPoll()
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
if (self.pollActive){
|
|
450
|
-
startTransfer(this)
|
|
451
|
-
}else{
|
|
452
|
-
self.pollPending--
|
|
453
|
-
|
|
454
|
-
if (self.pollPending == 0){
|
|
455
|
-
delete self.pollTransfers;
|
|
456
|
-
self.emit('end')
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
function startTransfer(t){
|
|
462
|
-
try {
|
|
463
|
-
t.submit(Buffer.alloc(self.pollTransferSize), transferDone);
|
|
464
|
-
} catch (e) {
|
|
465
|
-
self.emit("error", e);
|
|
466
|
-
self.stopPoll();
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
this.pollTransfers.forEach(startTransfer)
|
|
471
|
-
self.pollPending = this.pollTransfers.length
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
function OutEndpoint(device, descriptor){
|
|
477
|
-
Endpoint.call(this, device, descriptor)
|
|
478
|
-
}
|
|
479
|
-
exports.OutEndpoint = OutEndpoint
|
|
480
|
-
util.inherits(OutEndpoint, Endpoint)
|
|
481
|
-
OutEndpoint.prototype.direction = "out"
|
|
482
|
-
|
|
483
|
-
OutEndpoint.prototype.transfer = function(buffer, cb){
|
|
484
|
-
var self = this
|
|
485
|
-
if (!buffer){
|
|
486
|
-
buffer = Buffer.alloc(0)
|
|
487
|
-
}else if (!isBuffer(buffer)){
|
|
488
|
-
buffer = Buffer.from(buffer)
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
function callback(error, buf, actual){
|
|
492
|
-
if (cb) cb.call(self, error)
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
try {
|
|
496
|
-
this.makeTransfer(this.timeout, callback).submit(buffer);
|
|
497
|
-
} catch (e) {
|
|
498
|
-
process.nextTick(function() { callback(e); });
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
return this;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
OutEndpoint.prototype.transferWithZLP = function (buf, cb) {
|
|
505
|
-
if (buf.length % this.descriptor.wMaxPacketSize == 0) {
|
|
506
|
-
this.transfer(buf);
|
|
507
|
-
this.transfer(Buffer.alloc(0), cb);
|
|
508
|
-
} else {
|
|
509
|
-
this.transfer(buf, cb);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// Polling mechanism for discovering device changes until this is fixed:
|
|
514
|
-
// https://github.com/libusb/libusb/issues/86
|
|
515
|
-
exports._pollTimeout = 500;
|
|
516
|
-
var hotplugSupported = usb._getLibusbCapability(usb.LIBUSB_CAP_HAS_HOTPLUG) > 0;
|
|
517
|
-
var pollingHotplug = false;
|
|
518
|
-
var pollDevices = [];
|
|
519
|
-
function pollHotplug(start) {
|
|
520
|
-
if (start) {
|
|
521
|
-
pollingHotplug = true;
|
|
522
|
-
} else if (!pollingHotplug) {
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
var devices = usb.getDeviceList();
|
|
527
|
-
|
|
528
|
-
if (!start) {
|
|
529
|
-
// Find attached devices
|
|
530
|
-
for (var device of devices) {
|
|
531
|
-
var found = pollDevices.find(item => item.deviceAddress === device.deviceAddress);
|
|
532
|
-
if (!found) {
|
|
533
|
-
usb.emit('attach', device);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
// Find detached devices
|
|
538
|
-
for (var device of pollDevices) {
|
|
539
|
-
var found = devices.find(item => item.deviceAddress === device.deviceAddress);
|
|
540
|
-
if (!found) {
|
|
541
|
-
usb.emit('detach', device);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
pollDevices = devices;
|
|
547
|
-
setTimeout(() => {
|
|
548
|
-
pollHotplug();
|
|
549
|
-
}, exports._pollTimeout);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
var hotplugListeners = 0;
|
|
553
|
-
exports.on('newListener', function(name) {
|
|
554
|
-
if (name !== 'attach' && name !== 'detach') return;
|
|
555
|
-
if (++hotplugListeners === 1) {
|
|
556
|
-
if (hotplugSupported) {
|
|
557
|
-
usb._enableHotplugEvents();
|
|
558
|
-
} else {
|
|
559
|
-
pollHotplug(true);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
exports.on('removeListener', function(name) {
|
|
565
|
-
if (name !== 'attach' && name !== 'detach') return;
|
|
566
|
-
if (--hotplugListeners === 0) {
|
|
567
|
-
if (hotplugSupported) {
|
|
568
|
-
usb._disableHotplugEvents();
|
|
569
|
-
} else {
|
|
570
|
-
pollingHotplug = false;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
});
|