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