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.
Files changed (69) hide show
  1. package/.eslintignore +4 -0
  2. package/.eslintrc.json +87 -0
  3. package/.gitattributes +1 -0
  4. package/.vscode/launch.json +15 -0
  5. package/.vscode/tasks.json +23 -0
  6. package/CHANGELOG.md +13 -0
  7. package/README.md +400 -175
  8. package/dist/index.d.ts +17 -0
  9. package/dist/index.js +133 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/usb/bindings.d.ts +253 -0
  12. package/dist/usb/bindings.js +10 -0
  13. package/dist/usb/bindings.js.map +1 -0
  14. package/dist/usb/capability.d.ts +14 -0
  15. package/dist/usb/capability.js +18 -0
  16. package/dist/usb/capability.js.map +1 -0
  17. package/dist/usb/descriptors.d.ts +129 -0
  18. package/dist/usb/descriptors.js +3 -0
  19. package/dist/usb/descriptors.js.map +1 -0
  20. package/dist/usb/device.d.ts +94 -0
  21. package/dist/usb/device.js +300 -0
  22. package/dist/usb/device.js.map +1 -0
  23. package/dist/usb/endpoint.d.ts +91 -0
  24. package/dist/usb/endpoint.js +236 -0
  25. package/dist/usb/endpoint.js.map +1 -0
  26. package/dist/usb/index.d.ts +25 -0
  27. package/dist/usb/index.js +116 -0
  28. package/dist/usb/index.js.map +1 -0
  29. package/dist/usb/interface.d.ts +78 -0
  30. package/dist/usb/interface.js +137 -0
  31. package/dist/usb/interface.js.map +1 -0
  32. package/dist/webusb/index.d.ts +56 -0
  33. package/dist/webusb/index.js +412 -0
  34. package/dist/webusb/index.js.map +1 -0
  35. package/dist/webusb/mutex.d.ts +22 -0
  36. package/dist/webusb/mutex.js +89 -0
  37. package/dist/webusb/mutex.js.map +1 -0
  38. package/dist/webusb/webusb-device.d.ts +49 -0
  39. package/dist/webusb/webusb-device.js +888 -0
  40. package/dist/webusb/webusb-device.js.map +1 -0
  41. package/package.json +28 -15
  42. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  43. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  44. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  45. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  46. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  47. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  48. package/prebuilds/linux-ia32/node.napi.node +0 -0
  49. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  50. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  51. package/prebuilds/win32-ia32/node.napi.node +0 -0
  52. package/prebuilds/win32-x64/node.napi.node +0 -0
  53. package/src/device.cc +6 -6
  54. package/test/usb.coffee +13 -7
  55. package/test/webusb.coffee +189 -0
  56. package/tsc/index.ts +67 -0
  57. package/tsc/usb/bindings.ts +304 -0
  58. package/tsc/usb/capability.ts +22 -0
  59. package/tsc/usb/descriptors.ts +180 -0
  60. package/tsc/usb/device.ts +325 -0
  61. package/tsc/usb/endpoint.ts +228 -0
  62. package/tsc/usb/index.ts +111 -0
  63. package/tsc/usb/interface.ts +172 -0
  64. package/tsc/webusb/index.ts +363 -0
  65. package/tsc/webusb/mutex.ts +38 -0
  66. package/tsc/webusb/webusb-device.ts +534 -0
  67. package/tsconfig.json +17 -0
  68. package/typedoc.json +9 -0
  69. 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
- });