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
@@ -0,0 +1,888 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __values = (this && this.__values) || function(o) {
39
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
40
+ if (m) return m.call(o);
41
+ if (o && typeof o.length === "number") return {
42
+ next: function () {
43
+ if (o && i >= o.length) o = void 0;
44
+ return { value: o && o[i++], done: !o };
45
+ }
46
+ };
47
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.WebUSBDevice = void 0;
51
+ var usb = require("../usb");
52
+ var util_1 = require("util");
53
+ var mutex_1 = require("./mutex");
54
+ var LIBUSB_TRANSFER_TYPE_MASK = 0x03;
55
+ var ENDPOINT_NUMBER_MASK = 0x7f;
56
+ var CLEAR_FEATURE = 0x01;
57
+ var ENDPOINT_HALT = 0x00;
58
+ /**
59
+ * Wrapper to make a node-usb device look like a webusb device
60
+ */
61
+ var WebUSBDevice = /** @class */ (function () {
62
+ function WebUSBDevice(device) {
63
+ this.device = device;
64
+ this.configurations = [];
65
+ this.deviceMutex = new mutex_1.Mutex();
66
+ var usbVersion = this.decodeVersion(device.deviceDescriptor.bcdUSB);
67
+ this.usbVersionMajor = usbVersion.major;
68
+ this.usbVersionMinor = usbVersion.minor;
69
+ this.usbVersionSubminor = usbVersion.sub;
70
+ this.deviceClass = device.deviceDescriptor.bDeviceClass;
71
+ this.deviceSubclass = device.deviceDescriptor.bDeviceSubClass;
72
+ this.deviceProtocol = device.deviceDescriptor.bDeviceProtocol;
73
+ this.vendorId = device.deviceDescriptor.idVendor;
74
+ this.productId = device.deviceDescriptor.idProduct;
75
+ var deviceVersion = this.decodeVersion(device.deviceDescriptor.bcdDevice);
76
+ this.deviceVersionMajor = deviceVersion.major;
77
+ this.deviceVersionMinor = deviceVersion.minor;
78
+ this.deviceVersionSubminor = deviceVersion.sub;
79
+ }
80
+ WebUSBDevice.createInstance = function (device) {
81
+ return __awaiter(this, void 0, void 0, function () {
82
+ var instance, _a;
83
+ return __generator(this, function (_b) {
84
+ switch (_b.label) {
85
+ case 0:
86
+ _b.trys.push([0, 2, , 3]);
87
+ instance = new WebUSBDevice(device);
88
+ return [4 /*yield*/, instance.initialize()];
89
+ case 1:
90
+ _b.sent();
91
+ return [2 /*return*/, instance];
92
+ case 2:
93
+ _a = _b.sent();
94
+ return [2 /*return*/, undefined];
95
+ case 3: return [2 /*return*/];
96
+ }
97
+ });
98
+ });
99
+ };
100
+ Object.defineProperty(WebUSBDevice.prototype, "configuration", {
101
+ get: function () {
102
+ if (!this.device.configDescriptor) {
103
+ return undefined;
104
+ }
105
+ var currentConfiguration = this.device.configDescriptor.bConfigurationValue;
106
+ return this.configurations.find(function (configuration) { return configuration.configurationValue === currentConfiguration; });
107
+ },
108
+ enumerable: false,
109
+ configurable: true
110
+ });
111
+ Object.defineProperty(WebUSBDevice.prototype, "opened", {
112
+ get: function () {
113
+ return (!!this.device.interfaces);
114
+ },
115
+ enumerable: false,
116
+ configurable: true
117
+ });
118
+ WebUSBDevice.prototype.open = function () {
119
+ return __awaiter(this, void 0, void 0, function () {
120
+ var error_1;
121
+ return __generator(this, function (_a) {
122
+ switch (_a.label) {
123
+ case 0:
124
+ _a.trys.push([0, 2, 3, 4]);
125
+ return [4 /*yield*/, this.deviceMutex.lock()];
126
+ case 1:
127
+ _a.sent();
128
+ if (this.opened) {
129
+ return [2 /*return*/];
130
+ }
131
+ this.device.open();
132
+ return [3 /*break*/, 4];
133
+ case 2:
134
+ error_1 = _a.sent();
135
+ throw new Error("open error: " + error_1);
136
+ case 3:
137
+ this.deviceMutex.unlock();
138
+ return [7 /*endfinally*/];
139
+ case 4: return [2 /*return*/];
140
+ }
141
+ });
142
+ });
143
+ };
144
+ WebUSBDevice.prototype.close = function () {
145
+ var _a;
146
+ return __awaiter(this, void 0, void 0, function () {
147
+ var _b, _c, iface, e_1_1, _error_1, error_2;
148
+ var e_1, _d;
149
+ return __generator(this, function (_e) {
150
+ switch (_e.label) {
151
+ case 0:
152
+ _e.trys.push([0, 13, 14, 15]);
153
+ return [4 /*yield*/, this.deviceMutex.lock()];
154
+ case 1:
155
+ _e.sent();
156
+ if (!this.opened) {
157
+ return [2 /*return*/];
158
+ }
159
+ _e.label = 2;
160
+ case 2:
161
+ _e.trys.push([2, 11, , 12]);
162
+ if (!this.configuration) return [3 /*break*/, 10];
163
+ _e.label = 3;
164
+ case 3:
165
+ _e.trys.push([3, 8, 9, 10]);
166
+ _b = __values((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.interfaces), _c = _b.next();
167
+ _e.label = 4;
168
+ case 4:
169
+ if (!!_c.done) return [3 /*break*/, 7];
170
+ iface = _c.value;
171
+ return [4 /*yield*/, this._releaseInterface(iface.interfaceNumber)];
172
+ case 5:
173
+ _e.sent();
174
+ // Re-create the USBInterface to set the claimed attribute
175
+ this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
176
+ interfaceNumber: iface.interfaceNumber,
177
+ alternate: iface.alternate,
178
+ alternates: iface.alternates,
179
+ claimed: false
180
+ };
181
+ _e.label = 6;
182
+ case 6:
183
+ _c = _b.next();
184
+ return [3 /*break*/, 4];
185
+ case 7: return [3 /*break*/, 10];
186
+ case 8:
187
+ e_1_1 = _e.sent();
188
+ e_1 = { error: e_1_1 };
189
+ return [3 /*break*/, 10];
190
+ case 9:
191
+ try {
192
+ if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
193
+ }
194
+ finally { if (e_1) throw e_1.error; }
195
+ return [7 /*endfinally*/];
196
+ case 10: return [3 /*break*/, 12];
197
+ case 11:
198
+ _error_1 = _e.sent();
199
+ return [3 /*break*/, 12];
200
+ case 12:
201
+ this.device.close();
202
+ return [3 /*break*/, 15];
203
+ case 13:
204
+ error_2 = _e.sent();
205
+ throw new Error("close error: " + error_2);
206
+ case 14:
207
+ this.deviceMutex.unlock();
208
+ return [7 /*endfinally*/];
209
+ case 15: return [2 /*return*/];
210
+ }
211
+ });
212
+ });
213
+ };
214
+ WebUSBDevice.prototype.selectConfiguration = function (configurationValue) {
215
+ return __awaiter(this, void 0, void 0, function () {
216
+ var config, setConfiguration, error_3;
217
+ return __generator(this, function (_a) {
218
+ switch (_a.label) {
219
+ case 0:
220
+ _a.trys.push([0, , 6, 7]);
221
+ return [4 /*yield*/, this.deviceMutex.lock()];
222
+ case 1:
223
+ _a.sent();
224
+ if (!this.opened || !this.device.configDescriptor) {
225
+ throw new Error('selectConfiguration error: invalid state');
226
+ }
227
+ if (this.device.configDescriptor.bConfigurationValue === configurationValue) {
228
+ return [2 /*return*/];
229
+ }
230
+ config = this.configurations.find(function (configuration) { return configuration.configurationValue === configurationValue; });
231
+ if (!config) {
232
+ throw new Error('selectConfiguration error: configuration not found');
233
+ }
234
+ _a.label = 2;
235
+ case 2:
236
+ _a.trys.push([2, 4, , 5]);
237
+ setConfiguration = util_1.promisify(this.device.setConfiguration).bind(this.device);
238
+ return [4 /*yield*/, setConfiguration(configurationValue)];
239
+ case 3:
240
+ _a.sent();
241
+ return [3 /*break*/, 5];
242
+ case 4:
243
+ error_3 = _a.sent();
244
+ throw new Error("selectConfiguration error: " + error_3);
245
+ case 5: return [3 /*break*/, 7];
246
+ case 6:
247
+ this.deviceMutex.unlock();
248
+ return [7 /*endfinally*/];
249
+ case 7: return [2 /*return*/];
250
+ }
251
+ });
252
+ });
253
+ };
254
+ WebUSBDevice.prototype.claimInterface = function (interfaceNumber) {
255
+ return __awaiter(this, void 0, void 0, function () {
256
+ var iface;
257
+ return __generator(this, function (_a) {
258
+ switch (_a.label) {
259
+ case 0:
260
+ _a.trys.push([0, , 2, 3]);
261
+ return [4 /*yield*/, this.deviceMutex.lock()];
262
+ case 1:
263
+ _a.sent();
264
+ if (!this.opened) {
265
+ throw new Error('claimInterface error: invalid state');
266
+ }
267
+ if (!this.configuration) {
268
+ throw new Error('claimInterface error: interface not found');
269
+ }
270
+ iface = this.configuration.interfaces.find(function (usbInterface) { return usbInterface.interfaceNumber === interfaceNumber; });
271
+ if (!iface) {
272
+ throw new Error('claimInterface error: interface not found');
273
+ }
274
+ if (iface.claimed) {
275
+ return [2 /*return*/];
276
+ }
277
+ try {
278
+ this.device.interface(interfaceNumber).claim();
279
+ // Re-create the USBInterface to set the claimed attribute
280
+ this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
281
+ interfaceNumber: interfaceNumber,
282
+ alternate: iface.alternate,
283
+ alternates: iface.alternates,
284
+ claimed: true
285
+ };
286
+ }
287
+ catch (error) {
288
+ throw new Error("claimInterface error: " + error);
289
+ }
290
+ return [3 /*break*/, 3];
291
+ case 2:
292
+ this.deviceMutex.unlock();
293
+ return [7 /*endfinally*/];
294
+ case 3: return [2 /*return*/];
295
+ }
296
+ });
297
+ });
298
+ };
299
+ WebUSBDevice.prototype.releaseInterface = function (interfaceNumber) {
300
+ return __awaiter(this, void 0, void 0, function () {
301
+ var iface;
302
+ return __generator(this, function (_a) {
303
+ switch (_a.label) {
304
+ case 0:
305
+ _a.trys.push([0, , 3, 4]);
306
+ return [4 /*yield*/, this.deviceMutex.lock()];
307
+ case 1:
308
+ _a.sent();
309
+ return [4 /*yield*/, this._releaseInterface(interfaceNumber)];
310
+ case 2:
311
+ _a.sent();
312
+ if (this.configuration) {
313
+ iface = this.configuration.interfaces.find(function (usbInterface) { return usbInterface.interfaceNumber === interfaceNumber; });
314
+ if (iface) {
315
+ // Re-create the USBInterface to set the claimed attribute
316
+ this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
317
+ interfaceNumber: interfaceNumber,
318
+ alternate: iface.alternate,
319
+ alternates: iface.alternates,
320
+ claimed: false
321
+ };
322
+ }
323
+ }
324
+ return [3 /*break*/, 4];
325
+ case 3:
326
+ this.deviceMutex.unlock();
327
+ return [7 /*endfinally*/];
328
+ case 4: return [2 /*return*/];
329
+ }
330
+ });
331
+ });
332
+ };
333
+ WebUSBDevice.prototype.selectAlternateInterface = function (interfaceNumber, alternateSetting) {
334
+ return __awaiter(this, void 0, void 0, function () {
335
+ var iface, iface_1, setAltSetting, error_4;
336
+ return __generator(this, function (_a) {
337
+ switch (_a.label) {
338
+ case 0:
339
+ _a.trys.push([0, , 6, 7]);
340
+ return [4 /*yield*/, this.deviceMutex.lock()];
341
+ case 1:
342
+ _a.sent();
343
+ if (!this.opened) {
344
+ throw new Error('selectAlternateInterface error: invalid state');
345
+ }
346
+ if (!this.configuration) {
347
+ throw new Error('selectAlternateInterface error: interface not found');
348
+ }
349
+ iface = this.configuration.interfaces.find(function (usbInterface) { return usbInterface.interfaceNumber === interfaceNumber; });
350
+ if (!iface) {
351
+ throw new Error('selectAlternateInterface error: interface not found');
352
+ }
353
+ if (!iface.claimed) {
354
+ throw new Error('selectAlternateInterface error: invalid state');
355
+ }
356
+ _a.label = 2;
357
+ case 2:
358
+ _a.trys.push([2, 4, , 5]);
359
+ iface_1 = this.device.interface(interfaceNumber);
360
+ setAltSetting = util_1.promisify(iface_1.setAltSetting).bind(iface_1);
361
+ return [4 /*yield*/, setAltSetting(alternateSetting)];
362
+ case 3:
363
+ _a.sent();
364
+ return [3 /*break*/, 5];
365
+ case 4:
366
+ error_4 = _a.sent();
367
+ throw new Error("selectAlternateInterface error: " + error_4);
368
+ case 5: return [3 /*break*/, 7];
369
+ case 6:
370
+ this.deviceMutex.unlock();
371
+ return [7 /*endfinally*/];
372
+ case 7: return [2 /*return*/];
373
+ }
374
+ });
375
+ });
376
+ };
377
+ WebUSBDevice.prototype.controlTransferIn = function (setup, length) {
378
+ return __awaiter(this, void 0, void 0, function () {
379
+ var type, controlTransfer, result, error_5;
380
+ return __generator(this, function (_a) {
381
+ switch (_a.label) {
382
+ case 0:
383
+ _a.trys.push([0, 3, 4, 5]);
384
+ return [4 /*yield*/, this.deviceMutex.lock()];
385
+ case 1:
386
+ _a.sent();
387
+ type = this.controlTransferParamsToType(setup, usb.LIBUSB_ENDPOINT_IN);
388
+ controlTransfer = util_1.promisify(this.device.controlTransfer).bind(this.device);
389
+ return [4 /*yield*/, controlTransfer(type, setup.request, setup.value, setup.index, length)];
390
+ case 2:
391
+ result = _a.sent();
392
+ return [2 /*return*/, {
393
+ data: result ? new DataView(new Uint8Array(result).buffer) : undefined,
394
+ status: 'ok'
395
+ }];
396
+ case 3:
397
+ error_5 = _a.sent();
398
+ if (error_5.errno === usb.LIBUSB_TRANSFER_STALL) {
399
+ return [2 /*return*/, {
400
+ status: 'stall'
401
+ }];
402
+ }
403
+ if (error_5.errno === usb.LIBUSB_TRANSFER_OVERFLOW) {
404
+ return [2 /*return*/, {
405
+ status: 'babble'
406
+ }];
407
+ }
408
+ throw new Error("controlTransferIn error: " + error_5);
409
+ case 4:
410
+ this.deviceMutex.unlock();
411
+ return [7 /*endfinally*/];
412
+ case 5: return [2 /*return*/];
413
+ }
414
+ });
415
+ });
416
+ };
417
+ WebUSBDevice.prototype.controlTransferOut = function (setup, data) {
418
+ return __awaiter(this, void 0, void 0, function () {
419
+ var type, controlTransfer, buffer, bytesWritten, error_6;
420
+ return __generator(this, function (_a) {
421
+ switch (_a.label) {
422
+ case 0:
423
+ _a.trys.push([0, 3, 4, 5]);
424
+ return [4 /*yield*/, this.deviceMutex.lock()];
425
+ case 1:
426
+ _a.sent();
427
+ type = this.controlTransferParamsToType(setup, usb.LIBUSB_ENDPOINT_OUT);
428
+ controlTransfer = util_1.promisify(this.device.controlTransfer).bind(this.device);
429
+ buffer = data ? Buffer.from(data) : Buffer.alloc(0);
430
+ return [4 /*yield*/, controlTransfer(type, setup.request, setup.value, setup.index, buffer)];
431
+ case 2:
432
+ bytesWritten = _a.sent();
433
+ return [2 /*return*/, {
434
+ bytesWritten: bytesWritten,
435
+ status: 'ok'
436
+ }];
437
+ case 3:
438
+ error_6 = _a.sent();
439
+ if (error_6.errno === usb.LIBUSB_TRANSFER_STALL) {
440
+ return [2 /*return*/, {
441
+ bytesWritten: 0,
442
+ status: 'stall'
443
+ }];
444
+ }
445
+ throw new Error("controlTransferOut error: " + error_6);
446
+ case 4:
447
+ this.deviceMutex.unlock();
448
+ return [7 /*endfinally*/];
449
+ case 5: return [2 /*return*/];
450
+ }
451
+ });
452
+ });
453
+ };
454
+ WebUSBDevice.prototype.clearHalt = function (direction, endpointNumber) {
455
+ return __awaiter(this, void 0, void 0, function () {
456
+ var wIndex, controlTransfer, error_7;
457
+ return __generator(this, function (_a) {
458
+ switch (_a.label) {
459
+ case 0:
460
+ _a.trys.push([0, 3, 4, 5]);
461
+ return [4 /*yield*/, this.deviceMutex.lock()];
462
+ case 1:
463
+ _a.sent();
464
+ wIndex = endpointNumber | (direction === 'in' ? usb.LIBUSB_ENDPOINT_IN : usb.LIBUSB_ENDPOINT_OUT);
465
+ controlTransfer = util_1.promisify(this.device.controlTransfer).bind(this.device);
466
+ return [4 /*yield*/, controlTransfer(usb.LIBUSB_RECIPIENT_ENDPOINT, CLEAR_FEATURE, ENDPOINT_HALT, wIndex, 0)];
467
+ case 2:
468
+ _a.sent();
469
+ return [3 /*break*/, 5];
470
+ case 3:
471
+ error_7 = _a.sent();
472
+ throw new Error("clearHalt error: " + error_7);
473
+ case 4:
474
+ this.deviceMutex.unlock();
475
+ return [7 /*endfinally*/];
476
+ case 5: return [2 /*return*/];
477
+ }
478
+ });
479
+ });
480
+ };
481
+ WebUSBDevice.prototype.transferIn = function (endpointNumber, length) {
482
+ return __awaiter(this, void 0, void 0, function () {
483
+ var endpoint, transfer, result, error_8;
484
+ return __generator(this, function (_a) {
485
+ switch (_a.label) {
486
+ case 0:
487
+ _a.trys.push([0, 3, 4, 5]);
488
+ return [4 /*yield*/, this.deviceMutex.lock()];
489
+ case 1:
490
+ _a.sent();
491
+ endpoint = this.getEndpoint(endpointNumber | usb.LIBUSB_ENDPOINT_IN);
492
+ transfer = util_1.promisify(endpoint.transfer).bind(endpoint);
493
+ return [4 /*yield*/, transfer(length)];
494
+ case 2:
495
+ result = _a.sent();
496
+ return [2 /*return*/, {
497
+ data: result ? new DataView(new Uint8Array(result).buffer) : undefined,
498
+ status: 'ok'
499
+ }];
500
+ case 3:
501
+ error_8 = _a.sent();
502
+ if (error_8.errno === usb.LIBUSB_TRANSFER_STALL) {
503
+ return [2 /*return*/, {
504
+ status: 'stall'
505
+ }];
506
+ }
507
+ if (error_8.errno === usb.LIBUSB_TRANSFER_OVERFLOW) {
508
+ return [2 /*return*/, {
509
+ status: 'babble'
510
+ }];
511
+ }
512
+ throw new Error("transferIn error: " + error_8);
513
+ case 4:
514
+ this.deviceMutex.unlock();
515
+ return [7 /*endfinally*/];
516
+ case 5: return [2 /*return*/];
517
+ }
518
+ });
519
+ });
520
+ };
521
+ WebUSBDevice.prototype.transferOut = function (endpointNumber, data) {
522
+ return __awaiter(this, void 0, void 0, function () {
523
+ var endpoint, transfer, buffer, bytesWritten, error_9;
524
+ return __generator(this, function (_a) {
525
+ switch (_a.label) {
526
+ case 0:
527
+ _a.trys.push([0, 3, 4, 5]);
528
+ return [4 /*yield*/, this.deviceMutex.lock()];
529
+ case 1:
530
+ _a.sent();
531
+ endpoint = this.getEndpoint(endpointNumber | usb.LIBUSB_ENDPOINT_OUT);
532
+ transfer = util_1.promisify(endpoint.transfer).bind(endpoint);
533
+ buffer = Buffer.from(data);
534
+ return [4 /*yield*/, transfer(buffer)];
535
+ case 2:
536
+ bytesWritten = _a.sent();
537
+ return [2 /*return*/, {
538
+ bytesWritten: bytesWritten,
539
+ status: 'ok'
540
+ }];
541
+ case 3:
542
+ error_9 = _a.sent();
543
+ if (error_9.errno === usb.LIBUSB_TRANSFER_STALL) {
544
+ return [2 /*return*/, {
545
+ bytesWritten: 0,
546
+ status: 'stall'
547
+ }];
548
+ }
549
+ throw new Error("transferOut error: " + error_9);
550
+ case 4:
551
+ this.deviceMutex.unlock();
552
+ return [7 /*endfinally*/];
553
+ case 5: return [2 /*return*/];
554
+ }
555
+ });
556
+ });
557
+ };
558
+ WebUSBDevice.prototype.isochronousTransferIn = function (_endpointNumber, _packetLengths) {
559
+ return __awaiter(this, void 0, void 0, function () {
560
+ return __generator(this, function (_a) {
561
+ throw new Error('isochronousTransferIn error: method not implemented');
562
+ });
563
+ });
564
+ };
565
+ WebUSBDevice.prototype.isochronousTransferOut = function (_endpointNumber, _data, _packetLengths) {
566
+ return __awaiter(this, void 0, void 0, function () {
567
+ return __generator(this, function (_a) {
568
+ throw new Error('isochronousTransferOut error: method not implemented');
569
+ });
570
+ });
571
+ };
572
+ WebUSBDevice.prototype.reset = function () {
573
+ return __awaiter(this, void 0, void 0, function () {
574
+ var reset, error_10;
575
+ return __generator(this, function (_a) {
576
+ switch (_a.label) {
577
+ case 0:
578
+ _a.trys.push([0, 3, 4, 5]);
579
+ return [4 /*yield*/, this.deviceMutex.lock()];
580
+ case 1:
581
+ _a.sent();
582
+ reset = util_1.promisify(this.device.reset).bind(this.device);
583
+ return [4 /*yield*/, reset()];
584
+ case 2:
585
+ _a.sent();
586
+ return [3 /*break*/, 5];
587
+ case 3:
588
+ error_10 = _a.sent();
589
+ throw new Error("reset error: " + error_10);
590
+ case 4:
591
+ this.deviceMutex.unlock();
592
+ return [7 /*endfinally*/];
593
+ case 5: return [2 /*return*/];
594
+ }
595
+ });
596
+ });
597
+ };
598
+ WebUSBDevice.prototype.initialize = function () {
599
+ return __awaiter(this, void 0, void 0, function () {
600
+ var _a, _b, _c, _d;
601
+ return __generator(this, function (_e) {
602
+ switch (_e.label) {
603
+ case 0:
604
+ _e.trys.push([0, , 6, 7]);
605
+ return [4 /*yield*/, this.deviceMutex.lock()];
606
+ case 1:
607
+ _e.sent();
608
+ this.device.open();
609
+ _a = this;
610
+ return [4 /*yield*/, this.getStringDescriptor(this.device.deviceDescriptor.iManufacturer)];
611
+ case 2:
612
+ _a.manufacturerName = _e.sent();
613
+ _b = this;
614
+ return [4 /*yield*/, this.getStringDescriptor(this.device.deviceDescriptor.iProduct)];
615
+ case 3:
616
+ _b.productName = _e.sent();
617
+ _c = this;
618
+ return [4 /*yield*/, this.getStringDescriptor(this.device.deviceDescriptor.iSerialNumber)];
619
+ case 4:
620
+ _c.serialNumber = _e.sent();
621
+ _d = this;
622
+ return [4 /*yield*/, this.getConfigurations()];
623
+ case 5:
624
+ _d.configurations = _e.sent();
625
+ return [3 /*break*/, 7];
626
+ case 6:
627
+ this.device.close();
628
+ this.deviceMutex.unlock();
629
+ return [7 /*endfinally*/];
630
+ case 7: return [2 /*return*/];
631
+ }
632
+ });
633
+ });
634
+ };
635
+ WebUSBDevice.prototype.decodeVersion = function (version) {
636
+ var hex = ("0000" + version.toString(16)).slice(-4);
637
+ return {
638
+ major: parseInt(hex.substr(0, 2), undefined),
639
+ minor: parseInt(hex.substr(2, 1), undefined),
640
+ sub: parseInt(hex.substr(3, 1), undefined),
641
+ };
642
+ };
643
+ WebUSBDevice.prototype.getStringDescriptor = function (index) {
644
+ return __awaiter(this, void 0, void 0, function () {
645
+ var getStringDescriptor, buffer, error_11;
646
+ return __generator(this, function (_a) {
647
+ switch (_a.label) {
648
+ case 0:
649
+ _a.trys.push([0, 2, , 3]);
650
+ getStringDescriptor = util_1.promisify(this.device.getStringDescriptor).bind(this.device);
651
+ return [4 /*yield*/, getStringDescriptor(index)];
652
+ case 1:
653
+ buffer = _a.sent();
654
+ return [2 /*return*/, buffer ? buffer.toString() : ''];
655
+ case 2:
656
+ error_11 = _a.sent();
657
+ return [2 /*return*/, ''];
658
+ case 3: return [2 /*return*/];
659
+ }
660
+ });
661
+ });
662
+ };
663
+ WebUSBDevice.prototype.getConfigurations = function () {
664
+ return __awaiter(this, void 0, void 0, function () {
665
+ var configs, _a, _b, config, interfaces, _loop_1, this_1, _c, _d, iface, e_2_1, _e, _f, e_3_1;
666
+ var e_3, _g, e_2, _h, _j;
667
+ var _this = this;
668
+ return __generator(this, function (_k) {
669
+ switch (_k.label) {
670
+ case 0:
671
+ configs = [];
672
+ _k.label = 1;
673
+ case 1:
674
+ _k.trys.push([1, 14, 15, 16]);
675
+ _a = __values(this.device.allConfigDescriptors), _b = _a.next();
676
+ _k.label = 2;
677
+ case 2:
678
+ if (!!_b.done) return [3 /*break*/, 13];
679
+ config = _b.value;
680
+ interfaces = [];
681
+ _loop_1 = function (iface) {
682
+ var alternates, iface_2, iface_2_1, alternate_1, endpoints, _l, _m, endpoint, _o, _p, e_4_1, interfaceNumber, alternate;
683
+ var e_4, _q, e_5, _r, _s;
684
+ return __generator(this, function (_t) {
685
+ switch (_t.label) {
686
+ case 0:
687
+ alternates = [];
688
+ _t.label = 1;
689
+ case 1:
690
+ _t.trys.push([1, 6, 7, 8]);
691
+ iface_2 = (e_4 = void 0, __values(iface)), iface_2_1 = iface_2.next();
692
+ _t.label = 2;
693
+ case 2:
694
+ if (!!iface_2_1.done) return [3 /*break*/, 5];
695
+ alternate_1 = iface_2_1.value;
696
+ endpoints = [];
697
+ try {
698
+ for (_l = (e_5 = void 0, __values(alternate_1.endpoints)), _m = _l.next(); !_m.done; _m = _l.next()) {
699
+ endpoint = _m.value;
700
+ endpoints.push({
701
+ endpointNumber: endpoint.bEndpointAddress & ENDPOINT_NUMBER_MASK,
702
+ direction: endpoint.bEndpointAddress & usb.LIBUSB_ENDPOINT_IN ? 'in' : 'out',
703
+ type: (endpoint.bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) === usb.LIBUSB_TRANSFER_TYPE_BULK ? 'bulk'
704
+ : (endpoint.bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) === usb.LIBUSB_TRANSFER_TYPE_INTERRUPT ? 'interrupt'
705
+ : 'isochronous',
706
+ packetSize: endpoint.wMaxPacketSize
707
+ });
708
+ }
709
+ }
710
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
711
+ finally {
712
+ try {
713
+ if (_m && !_m.done && (_r = _l.return)) _r.call(_l);
714
+ }
715
+ finally { if (e_5) throw e_5.error; }
716
+ }
717
+ _p = (_o = alternates).push;
718
+ _s = {
719
+ alternateSetting: alternate_1.bAlternateSetting,
720
+ interfaceClass: alternate_1.bInterfaceClass,
721
+ interfaceSubclass: alternate_1.bInterfaceSubClass,
722
+ interfaceProtocol: alternate_1.bInterfaceProtocol
723
+ };
724
+ return [4 /*yield*/, this_1.getStringDescriptor(alternate_1.iInterface)];
725
+ case 3:
726
+ _p.apply(_o, [(_s.interfaceName = _t.sent(),
727
+ _s.endpoints = endpoints,
728
+ _s)]);
729
+ _t.label = 4;
730
+ case 4:
731
+ iface_2_1 = iface_2.next();
732
+ return [3 /*break*/, 2];
733
+ case 5: return [3 /*break*/, 8];
734
+ case 6:
735
+ e_4_1 = _t.sent();
736
+ e_4 = { error: e_4_1 };
737
+ return [3 /*break*/, 8];
738
+ case 7:
739
+ try {
740
+ if (iface_2_1 && !iface_2_1.done && (_q = iface_2.return)) _q.call(iface_2);
741
+ }
742
+ finally { if (e_4) throw e_4.error; }
743
+ return [7 /*endfinally*/];
744
+ case 8:
745
+ interfaceNumber = iface[0].bInterfaceNumber;
746
+ alternate = alternates.find(function (alt) { return alt.alternateSetting === _this.device.interface(interfaceNumber).altSetting; });
747
+ if (alternate) {
748
+ interfaces.push({
749
+ interfaceNumber: interfaceNumber,
750
+ alternate: alternate,
751
+ alternates: alternates,
752
+ claimed: false
753
+ });
754
+ }
755
+ return [2 /*return*/];
756
+ }
757
+ });
758
+ };
759
+ this_1 = this;
760
+ _k.label = 3;
761
+ case 3:
762
+ _k.trys.push([3, 8, 9, 10]);
763
+ _c = (e_2 = void 0, __values(config.interfaces)), _d = _c.next();
764
+ _k.label = 4;
765
+ case 4:
766
+ if (!!_d.done) return [3 /*break*/, 7];
767
+ iface = _d.value;
768
+ return [5 /*yield**/, _loop_1(iface)];
769
+ case 5:
770
+ _k.sent();
771
+ _k.label = 6;
772
+ case 6:
773
+ _d = _c.next();
774
+ return [3 /*break*/, 4];
775
+ case 7: return [3 /*break*/, 10];
776
+ case 8:
777
+ e_2_1 = _k.sent();
778
+ e_2 = { error: e_2_1 };
779
+ return [3 /*break*/, 10];
780
+ case 9:
781
+ try {
782
+ if (_d && !_d.done && (_h = _c.return)) _h.call(_c);
783
+ }
784
+ finally { if (e_2) throw e_2.error; }
785
+ return [7 /*endfinally*/];
786
+ case 10:
787
+ _f = (_e = configs).push;
788
+ _j = {
789
+ configurationValue: config.bConfigurationValue
790
+ };
791
+ return [4 /*yield*/, this.getStringDescriptor(config.iConfiguration)];
792
+ case 11:
793
+ _f.apply(_e, [(_j.configurationName = _k.sent(),
794
+ _j.interfaces = interfaces,
795
+ _j)]);
796
+ _k.label = 12;
797
+ case 12:
798
+ _b = _a.next();
799
+ return [3 /*break*/, 2];
800
+ case 13: return [3 /*break*/, 16];
801
+ case 14:
802
+ e_3_1 = _k.sent();
803
+ e_3 = { error: e_3_1 };
804
+ return [3 /*break*/, 16];
805
+ case 15:
806
+ try {
807
+ if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
808
+ }
809
+ finally { if (e_3) throw e_3.error; }
810
+ return [7 /*endfinally*/];
811
+ case 16: return [2 /*return*/, configs];
812
+ }
813
+ });
814
+ });
815
+ };
816
+ WebUSBDevice.prototype.getEndpoint = function (address) {
817
+ var e_6, _a;
818
+ if (!this.device.interfaces) {
819
+ return undefined;
820
+ }
821
+ try {
822
+ for (var _b = __values(this.device.interfaces), _c = _b.next(); !_c.done; _c = _b.next()) {
823
+ var iface = _c.value;
824
+ var endpoint = iface.endpoint(address);
825
+ if (endpoint) {
826
+ return endpoint;
827
+ }
828
+ }
829
+ }
830
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
831
+ finally {
832
+ try {
833
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
834
+ }
835
+ finally { if (e_6) throw e_6.error; }
836
+ }
837
+ return undefined;
838
+ };
839
+ WebUSBDevice.prototype.controlTransferParamsToType = function (setup, direction) {
840
+ var recipient = setup.recipient === 'device' ? usb.LIBUSB_RECIPIENT_DEVICE
841
+ : setup.recipient === 'interface' ? usb.LIBUSB_RECIPIENT_INTERFACE
842
+ : setup.recipient === 'endpoint' ? usb.LIBUSB_RECIPIENT_ENDPOINT
843
+ : usb.LIBUSB_RECIPIENT_OTHER;
844
+ var requestType = setup.requestType === 'standard' ? usb.LIBUSB_REQUEST_TYPE_STANDARD
845
+ : setup.requestType === 'class' ? usb.LIBUSB_REQUEST_TYPE_CLASS
846
+ : usb.LIBUSB_REQUEST_TYPE_VENDOR;
847
+ return recipient | requestType | direction;
848
+ };
849
+ WebUSBDevice.prototype._releaseInterface = function (interfaceNumber) {
850
+ return __awaiter(this, void 0, void 0, function () {
851
+ var iface, iface_3, release, error_12;
852
+ return __generator(this, function (_a) {
853
+ switch (_a.label) {
854
+ case 0:
855
+ if (!this.opened) {
856
+ throw new Error('releaseInterface error: invalid state');
857
+ }
858
+ if (!this.configuration) {
859
+ throw new Error('releaseInterface error: interface not found');
860
+ }
861
+ iface = this.configuration.interfaces.find(function (usbInterface) { return usbInterface.interfaceNumber === interfaceNumber; });
862
+ if (!iface) {
863
+ throw new Error('releaseInterface error: interface not found');
864
+ }
865
+ if (!iface.claimed) {
866
+ return [2 /*return*/];
867
+ }
868
+ _a.label = 1;
869
+ case 1:
870
+ _a.trys.push([1, 3, , 4]);
871
+ iface_3 = this.device.interface(interfaceNumber);
872
+ release = util_1.promisify(iface_3.release).bind(iface_3);
873
+ return [4 /*yield*/, release()];
874
+ case 2:
875
+ _a.sent();
876
+ return [3 /*break*/, 4];
877
+ case 3:
878
+ error_12 = _a.sent();
879
+ throw new Error("releaseInterface error: " + error_12);
880
+ case 4: return [2 /*return*/];
881
+ }
882
+ });
883
+ });
884
+ };
885
+ return WebUSBDevice;
886
+ }());
887
+ exports.WebUSBDevice = WebUSBDevice;
888
+ //# sourceMappingURL=webusb-device.js.map