@trezor/connect 9.0.10 → 9.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +19 -2
- package/lib/api/bitcoin/createPendingTx.d.ts +1 -0
- package/lib/api/bitcoin/createPendingTx.js +1 -0
- package/lib/api/cancelCoinjoinAuthorization.d.ts +7 -0
- package/lib/api/cancelCoinjoinAuthorization.js +25 -0
- package/lib/api/cardanoGetPublicKey.d.ts +1 -0
- package/lib/api/cardanoGetPublicKey.js +9 -0
- package/lib/api/cipherKeyValue.js +3 -2
- package/lib/api/getAccountInfo.d.ts +2 -0
- package/lib/api/getPublicKey.d.ts +1 -0
- package/lib/api/getPublicKey.js +9 -0
- package/lib/api/index.d.ts +2 -0
- package/lib/api/index.js +6 -2
- package/lib/api/rebootToBootloader.js +1 -1
- package/lib/api/showDeviceTutorial.d.ts +7 -0
- package/lib/api/showDeviceTutorial.js +21 -0
- package/lib/constants/errors.d.ts +0 -3
- package/lib/constants/errors.js +1 -4
- package/lib/core/index.d.ts +5 -6
- package/lib/core/index.js +44 -50
- package/lib/core/method.d.ts +1 -1
- package/lib/data/coinInfo.d.ts +0 -1
- package/lib/data/coinInfo.js +7 -14
- package/lib/data/config.js +7 -1
- package/lib/data/version.d.ts +1 -1
- package/lib/data/version.js +1 -1
- package/lib/device/Device.d.ts +16 -24
- package/lib/device/Device.js +71 -107
- package/lib/device/DeviceCommands.d.ts +4 -3
- package/lib/device/DeviceCommands.js +42 -20
- package/lib/device/DeviceList.d.ts +17 -33
- package/lib/device/DeviceList.js +230 -264
- package/lib/events/transport.d.ts +2 -9
- package/lib/events/transport.js +3 -10
- package/lib/factory.js +2 -0
- package/lib/index.js +7 -7
- package/lib/types/api/cancelCoinjoinAuthorization.d.ts +8 -0
- package/lib/types/api/cancelCoinjoinAuthorization.js +3 -0
- package/lib/types/api/index.d.ts +4 -0
- package/lib/types/api/showDeviceTutorial.d.ts +4 -0
- package/lib/types/api/showDeviceTutorial.js +3 -0
- package/lib/types/device.d.ts +1 -1
- package/lib/types/device.js +3 -0
- package/lib/types/settings.d.ts +1 -1
- package/lib/utils/debug.js +2 -1
- package/lib/utils/deviceFeaturesUtils.d.ts +2 -1
- package/lib/utils/deviceFeaturesUtils.js +12 -1
- package/lib/workers/workers-browser.d.ts +1 -3
- package/lib/workers/workers-browser.js +1 -7
- package/lib/workers/workers-react-native.d.ts +1 -3
- package/lib/workers/workers-react-native.js +1 -7
- package/lib/workers/workers.d.ts +1 -5
- package/lib/workers/workers.js +1 -5
- package/package.json +21 -18
- package/lib/device/DescriptorStream.d.ts +0 -28
- package/lib/device/DescriptorStream.js +0 -139
- package/lib/utils/objectUtils.d.ts +0 -10
- package/lib/utils/objectUtils.js +0 -37
- package/lib/workers/RNUsbPlugin.d.ts +0 -31
- package/lib/workers/RNUsbPlugin.js +0 -65
|
@@ -1,21 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { TRANSPORT, DEVICE, TransportInfo } from '../events';
|
|
5
|
-
import { DescriptorStream } from './DescriptorStream';
|
|
1
|
+
import { TypedEmitter } from '@trezor/utils/lib/typedEventEmitter';
|
|
2
|
+
import { Transport, TRANSPORT, Descriptor } from '@trezor/transport';
|
|
3
|
+
import { DEVICE, TransportInfo } from '../events';
|
|
6
4
|
import { Device } from './Device';
|
|
7
5
|
import type { Device as DeviceTyped } from '../types';
|
|
8
|
-
type LowLevelPlugin = {
|
|
9
|
-
name: 'WebUsbPlugin' | 'ReactNativePlugin';
|
|
10
|
-
unreadableHidDeviceChange: {
|
|
11
|
-
on: (event: string, fn: any) => void;
|
|
12
|
-
};
|
|
13
|
-
unreadableHidDevice: boolean;
|
|
14
|
-
};
|
|
15
6
|
interface DeviceListEvents {
|
|
16
7
|
[TRANSPORT.START]: TransportInfo;
|
|
17
8
|
[TRANSPORT.ERROR]: string;
|
|
18
|
-
[TRANSPORT.STREAM]: DescriptorStream;
|
|
19
9
|
[DEVICE.CONNECT]: DeviceTyped;
|
|
20
10
|
[DEVICE.CONNECT_UNACQUIRED]: DeviceTyped;
|
|
21
11
|
[DEVICE.DISCONNECT]: DeviceTyped;
|
|
@@ -23,49 +13,43 @@ interface DeviceListEvents {
|
|
|
23
13
|
[DEVICE.RELEASED]: DeviceTyped;
|
|
24
14
|
[DEVICE.ACQUIRED]: DeviceTyped;
|
|
25
15
|
}
|
|
26
|
-
export
|
|
27
|
-
on<K extends keyof DeviceListEvents>(type: K, listener: (event: DeviceListEvents[K]) => void): this;
|
|
28
|
-
off<K extends keyof DeviceListEvents>(type: K, listener: (event: DeviceListEvents[K]) => void): this;
|
|
29
|
-
emit<K extends keyof DeviceListEvents>(type: K, args: DeviceListEvents[K]): boolean;
|
|
30
|
-
}
|
|
31
|
-
export declare class DeviceList extends EventEmitter {
|
|
16
|
+
export declare class DeviceList extends TypedEmitter<DeviceListEvents> {
|
|
32
17
|
transport: Transport;
|
|
33
|
-
|
|
34
|
-
stream: DescriptorStream;
|
|
18
|
+
transports: Transport[];
|
|
35
19
|
devices: {
|
|
36
20
|
[path: string]: Device;
|
|
37
21
|
};
|
|
22
|
+
messages: JSON | Record<string, any>;
|
|
38
23
|
creatingDevicesDescriptors: {
|
|
39
|
-
[k: string]:
|
|
24
|
+
[k: string]: Descriptor;
|
|
40
25
|
};
|
|
41
|
-
messages: JSON | Record<string, any>;
|
|
42
26
|
transportStartPending: number;
|
|
43
27
|
penalizedDevices: {
|
|
44
28
|
[deviceID: string]: number;
|
|
45
29
|
};
|
|
46
|
-
fetchController?: AbortController | null;
|
|
47
30
|
constructor();
|
|
48
31
|
init(): Promise<void>;
|
|
49
|
-
resolveTransportEvent
|
|
32
|
+
private resolveTransportEvent;
|
|
50
33
|
waitForTransportFirstEvent(): Promise<void>;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
_createUnreadableDevice(descriptor: DeviceDescriptor, unreadableError: string): Device;
|
|
34
|
+
private _createAndSaveDevice;
|
|
35
|
+
private _createUnacquiredDevice;
|
|
36
|
+
private _createUnreadableDevice;
|
|
55
37
|
getDevice(path: string): Device;
|
|
56
38
|
getFirstDevicePath(): string;
|
|
57
39
|
asArray(): DeviceTyped[];
|
|
58
40
|
allDevices(): Device[];
|
|
59
41
|
length(): number;
|
|
60
|
-
transportType():
|
|
42
|
+
transportType(): "BridgeTransport" | "NodeUsbTransport" | "WebUsbTransport";
|
|
61
43
|
getTransportInfo(): TransportInfo;
|
|
62
44
|
dispose(): Promise<void>;
|
|
63
45
|
disconnectDevices(): void;
|
|
64
|
-
enumerate(): void
|
|
46
|
+
enumerate(): Promise<void>;
|
|
65
47
|
addAuthPenalty(device: Device): void;
|
|
66
|
-
getAuthPenalty
|
|
48
|
+
private getAuthPenalty;
|
|
67
49
|
removeAuthPenalty(device: Device): void;
|
|
50
|
+
private handle;
|
|
51
|
+
private _takeAndCreateDevice;
|
|
52
|
+
private _handleUsedElsewhere;
|
|
68
53
|
}
|
|
69
|
-
export declare const getDeviceList: () => Promise<DeviceList>;
|
|
70
54
|
export {};
|
|
71
55
|
//# sourceMappingURL=DeviceList.d.ts.map
|
package/lib/device/DeviceList.js
CHANGED
|
@@ -1,148 +1,228 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const transport_1 = tslib_1.__importDefault(require("@trezor/transport"));
|
|
7
|
-
const cross_fetch_1 = tslib_1.__importDefault(require("cross-fetch"));
|
|
3
|
+
exports.DeviceList = void 0;
|
|
4
|
+
const typedEventEmitter_1 = require("@trezor/utils/lib/typedEventEmitter");
|
|
5
|
+
const transport_1 = require("@trezor/transport");
|
|
8
6
|
const constants_1 = require("../constants");
|
|
9
|
-
const
|
|
10
|
-
const DescriptorStream_1 = require("./DescriptorStream");
|
|
7
|
+
const events_1 = require("../events");
|
|
11
8
|
const Device_1 = require("./Device");
|
|
12
9
|
const DataManager_1 = require("../data/DataManager");
|
|
13
10
|
const transportInfo_1 = require("../data/transportInfo");
|
|
14
11
|
const debug_1 = require("../utils/debug");
|
|
15
12
|
const promiseUtils_1 = require("../utils/promiseUtils");
|
|
16
|
-
const workers_1 = require("../workers/workers");
|
|
17
|
-
const { BridgeV2, Fallback } = transport_1.default;
|
|
18
13
|
const _log = (0, debug_1.initLog)('DeviceList');
|
|
19
14
|
let autoResolveTransportEventTimeout;
|
|
20
|
-
class DeviceList extends
|
|
15
|
+
class DeviceList extends typedEventEmitter_1.TypedEmitter {
|
|
21
16
|
constructor() {
|
|
22
|
-
var _a;
|
|
23
17
|
super();
|
|
18
|
+
this.transports = [];
|
|
24
19
|
this.devices = {};
|
|
25
20
|
this.creatingDevicesDescriptors = {};
|
|
26
21
|
this.transportStartPending = 0;
|
|
27
22
|
this.penalizedDevices = {};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const transports = [];
|
|
31
|
-
if (!(transportSettings === null || transportSettings === void 0 ? void 0 : transportSettings.length)) {
|
|
32
|
-
transportSettings = ['BridgeTransport'];
|
|
33
|
-
}
|
|
34
|
-
if (env === 'react-native' && typeof workers_1.ReactNativeUsbPlugin !== 'undefined') {
|
|
35
|
-
transports.push((0, workers_1.ReactNativeUsbPlugin)());
|
|
36
|
-
}
|
|
37
|
-
else if (transportSettings === null || transportSettings === void 0 ? void 0 : transportSettings.includes('BridgeTransport')) {
|
|
38
|
-
const bridgeLatestVersion = (0, transportInfo_1.getBridgeInfo)().version.join('.');
|
|
39
|
-
const bridge = new BridgeV2(undefined, undefined);
|
|
40
|
-
bridge.setBridgeLatestVersion(bridgeLatestVersion);
|
|
41
|
-
this.fetchController = new AbortController();
|
|
42
|
-
const { signal } = this.fetchController;
|
|
43
|
-
const fetchWithSignal = (args, options = {}) => (0, cross_fetch_1.default)(args, { ...options, signal });
|
|
44
|
-
const isNode = !!((_a = process === null || process === void 0 ? void 0 : process.release) === null || _a === void 0 ? void 0 : _a.name) && process.release.name.search(/node|io\.js/) !== -1;
|
|
45
|
-
BridgeV2.setFetch(fetchWithSignal, isNode);
|
|
46
|
-
transports.push(bridge);
|
|
47
|
-
}
|
|
48
|
-
if ((transportSettings === null || transportSettings === void 0 ? void 0 : transportSettings.includes('WebUsbTransport')) && typeof workers_1.WebUsbPlugin !== 'undefined') {
|
|
49
|
-
transports.push((0, workers_1.WebUsbPlugin)());
|
|
50
|
-
}
|
|
51
|
-
this.transport = new Fallback(transports);
|
|
23
|
+
let { transports } = DataManager_1.DataManager.getSettings();
|
|
24
|
+
const { debug } = DataManager_1.DataManager.getSettings();
|
|
52
25
|
this.messages = DataManager_1.DataManager.getProtobufMessages();
|
|
26
|
+
if (!(transports === null || transports === void 0 ? void 0 : transports.length)) {
|
|
27
|
+
transports = ['BridgeTransport'];
|
|
28
|
+
}
|
|
29
|
+
const transportLogger = (0, debug_1.initLog)('@trezor/transport', debug);
|
|
30
|
+
transports.forEach(transportType => {
|
|
31
|
+
if (typeof transportType === 'string') {
|
|
32
|
+
switch (transportType) {
|
|
33
|
+
case 'WebUsbTransport':
|
|
34
|
+
this.transports.push(new transport_1.WebUsbTransport({
|
|
35
|
+
messages: this.messages,
|
|
36
|
+
logger: transportLogger,
|
|
37
|
+
}));
|
|
38
|
+
break;
|
|
39
|
+
case 'NodeUsbTransport':
|
|
40
|
+
this.transports.push(new transport_1.NodeUsbTransport({
|
|
41
|
+
messages: this.messages,
|
|
42
|
+
logger: transportLogger,
|
|
43
|
+
}));
|
|
44
|
+
break;
|
|
45
|
+
case 'BridgeTransport':
|
|
46
|
+
this.transports.push(new transport_1.BridgeTransport({
|
|
47
|
+
latestVersion: (0, transportInfo_1.getBridgeInfo)().version.join('.'),
|
|
48
|
+
messages: this.messages,
|
|
49
|
+
logger: transportLogger,
|
|
50
|
+
}));
|
|
51
|
+
break;
|
|
52
|
+
default:
|
|
53
|
+
throw constants_1.ERRORS.TypedError('Runtime', `DeviceList.init: transports[] of unexpected type: ${transportType}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (transportType instanceof transport_1.Transport) {
|
|
57
|
+
this.transports.unshift(transportType);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
throw constants_1.ERRORS.TypedError('Runtime', 'DeviceList.init: transports[] of unexpected type');
|
|
61
|
+
}
|
|
62
|
+
});
|
|
53
63
|
}
|
|
54
64
|
async init() {
|
|
55
|
-
const { transport } = this;
|
|
56
65
|
try {
|
|
57
66
|
_log.debug('Initializing transports');
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
let lastError;
|
|
68
|
+
for (const transport of this.transports) {
|
|
69
|
+
this.transport = transport;
|
|
70
|
+
const result = await this.transport.init().promise;
|
|
71
|
+
if (result.success) {
|
|
72
|
+
lastError = undefined;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
lastError = result.error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (lastError) {
|
|
80
|
+
this.emit(transport_1.TRANSPORT.ERROR, lastError);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this.transport.on(transport_1.TRANSPORT.UPDATE, diff => {
|
|
84
|
+
diff.connected.forEach(async (descriptor) => {
|
|
85
|
+
const path = descriptor.path.toString();
|
|
86
|
+
const priority = DataManager_1.DataManager.getSettings('priority');
|
|
87
|
+
const penalty = this.getAuthPenalty();
|
|
88
|
+
if (priority || penalty) {
|
|
89
|
+
await (0, promiseUtils_1.resolveAfter)(501 + penalty + 100 * priority, null).promise;
|
|
90
|
+
}
|
|
91
|
+
if (descriptor.session == null) {
|
|
92
|
+
await this._createAndSaveDevice(descriptor);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const device = this._createUnacquiredDevice(descriptor);
|
|
96
|
+
this.devices[path] = device;
|
|
97
|
+
this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
diff.acquiredElsewhere.forEach((descriptor) => {
|
|
101
|
+
const path = descriptor.path.toString();
|
|
102
|
+
const device = this.devices[path];
|
|
103
|
+
if (device) {
|
|
104
|
+
device.featuresNeedsReload = true;
|
|
105
|
+
device.interruptionFromOutside();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
diff.released.forEach(descriptor => {
|
|
109
|
+
var _a;
|
|
110
|
+
const path = descriptor.path.toString();
|
|
111
|
+
const device = this.devices[path];
|
|
112
|
+
const methodStillRunning = !((_a = device === null || device === void 0 ? void 0 : device.commands) === null || _a === void 0 ? void 0 : _a.disposed);
|
|
113
|
+
if (device && methodStillRunning) {
|
|
114
|
+
device.keepSession = false;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
diff.releasedElsewhere.forEach(async (descriptor) => {
|
|
118
|
+
const path = descriptor.path.toString();
|
|
119
|
+
const device = this.devices[path];
|
|
120
|
+
await (0, promiseUtils_1.resolveAfter)(1000, null).promise;
|
|
121
|
+
if (device) {
|
|
122
|
+
if (!device.isUsed() && device.isUnacquired() && !device.isInconsistent()) {
|
|
123
|
+
_log.debug('Create device from unacquired', device);
|
|
124
|
+
await this._createAndSaveDevice(descriptor);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
const events = [
|
|
129
|
+
{
|
|
130
|
+
d: diff.changedSessions,
|
|
131
|
+
e: events_1.DEVICE.CHANGED,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
d: diff.acquired,
|
|
135
|
+
e: events_1.DEVICE.ACQUIRED,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
d: diff.released,
|
|
139
|
+
e: events_1.DEVICE.RELEASED,
|
|
140
|
+
},
|
|
141
|
+
];
|
|
142
|
+
events.forEach(({ d, e }) => {
|
|
143
|
+
d.forEach(descriptor => {
|
|
144
|
+
const path = descriptor.path.toString();
|
|
145
|
+
const device = this.devices[path];
|
|
146
|
+
_log.debug('Event', e, device);
|
|
147
|
+
if (device) {
|
|
148
|
+
this.emit(e, device.toMessageObject());
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
diff.disconnected.forEach(descriptor => {
|
|
153
|
+
const path = descriptor.path.toString();
|
|
154
|
+
const device = this.devices[path];
|
|
155
|
+
if (device) {
|
|
156
|
+
device.disconnect();
|
|
157
|
+
delete this.devices[path];
|
|
158
|
+
this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
diff.descriptors.forEach(d => {
|
|
162
|
+
if (this.devices[d.path]) {
|
|
163
|
+
this.devices[d.path].originalDescriptor = {
|
|
164
|
+
session: d.session,
|
|
165
|
+
path: d.path,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
this.transport.on(transport_1.TRANSPORT.ERROR, error => {
|
|
171
|
+
this.emit(transport_1.TRANSPORT.ERROR, error);
|
|
172
|
+
});
|
|
173
|
+
const enumerateResult = await this.transport.enumerate().promise;
|
|
174
|
+
if (!enumerateResult.success) {
|
|
175
|
+
this.emit(transport_1.TRANSPORT.ERROR, enumerateResult.error);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const descriptors = enumerateResult.payload;
|
|
179
|
+
if (descriptors.length > 0 && DataManager_1.DataManager.getSettings('pendingTransportEvent')) {
|
|
180
|
+
this.transportStartPending = descriptors.length;
|
|
181
|
+
this.on(events_1.DEVICE.CONNECT, this.resolveTransportEvent.bind(this));
|
|
182
|
+
this.on(events_1.DEVICE.CONNECT_UNACQUIRED, this.resolveTransportEvent.bind(this));
|
|
183
|
+
autoResolveTransportEventTimeout = setTimeout(() => {
|
|
184
|
+
this.emit(transport_1.TRANSPORT.START, this.getTransportInfo());
|
|
185
|
+
}, 10000);
|
|
65
186
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
187
|
+
else {
|
|
188
|
+
this.emit(transport_1.TRANSPORT.START, this.getTransportInfo());
|
|
189
|
+
}
|
|
190
|
+
this.transport.handleDescriptorsChange(descriptors);
|
|
191
|
+
this.transport.listen();
|
|
69
192
|
}
|
|
70
193
|
catch (error) {
|
|
71
|
-
|
|
194
|
+
console.error('DeviceList init error', error);
|
|
72
195
|
}
|
|
73
196
|
}
|
|
74
197
|
resolveTransportEvent() {
|
|
75
198
|
this.transportStartPending--;
|
|
199
|
+
if (autoResolveTransportEventTimeout) {
|
|
200
|
+
clearTimeout(autoResolveTransportEventTimeout);
|
|
201
|
+
}
|
|
76
202
|
if (this.transportStartPending === 0) {
|
|
77
|
-
this.
|
|
203
|
+
this.emit(transport_1.TRANSPORT.START, this.getTransportInfo());
|
|
78
204
|
}
|
|
79
205
|
}
|
|
80
206
|
async waitForTransportFirstEvent() {
|
|
81
207
|
await new Promise(resolve => {
|
|
82
208
|
const handler = () => {
|
|
83
|
-
this.removeListener(
|
|
84
|
-
this.removeListener(
|
|
209
|
+
this.removeListener(transport_1.TRANSPORT.START, handler);
|
|
210
|
+
this.removeListener(transport_1.TRANSPORT.ERROR, handler);
|
|
85
211
|
resolve();
|
|
86
212
|
};
|
|
87
|
-
this.on(
|
|
88
|
-
this.on(
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
_initStream() {
|
|
92
|
-
const stream = new DescriptorStream_1.DescriptorStream(this.transport);
|
|
93
|
-
stream.on(events_2.TRANSPORT.START_PENDING, (pending) => {
|
|
94
|
-
this.transportStartPending = pending;
|
|
95
|
-
autoResolveTransportEventTimeout = setTimeout(() => {
|
|
96
|
-
this.resolveTransportEvent();
|
|
97
|
-
}, 5000);
|
|
213
|
+
this.on(transport_1.TRANSPORT.START, handler);
|
|
214
|
+
this.on(transport_1.TRANSPORT.ERROR, handler);
|
|
98
215
|
});
|
|
99
|
-
stream.on(events_2.TRANSPORT.START, () => {
|
|
100
|
-
this.emit(events_2.TRANSPORT.START, this.getTransportInfo());
|
|
101
|
-
if (autoResolveTransportEventTimeout) {
|
|
102
|
-
clearTimeout(autoResolveTransportEventTimeout);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
stream.on(events_2.TRANSPORT.UPDATE, (diff) => {
|
|
106
|
-
new DiffHandler(this, diff).handle();
|
|
107
|
-
});
|
|
108
|
-
stream.on(events_2.TRANSPORT.ERROR, error => {
|
|
109
|
-
this.emit(events_2.TRANSPORT.ERROR, error);
|
|
110
|
-
stream.stop();
|
|
111
|
-
});
|
|
112
|
-
stream.listen();
|
|
113
|
-
this.stream = stream;
|
|
114
|
-
if (this.transportPlugin && this.transportPlugin.name === 'WebUsbPlugin') {
|
|
115
|
-
const { unreadableHidDeviceChange } = this.transportPlugin;
|
|
116
|
-
const UNREADABLE_PATH = 'unreadable';
|
|
117
|
-
unreadableHidDeviceChange.on('change', () => {
|
|
118
|
-
if (this.transportPlugin && this.transportPlugin.unreadableHidDevice) {
|
|
119
|
-
const device = this._createUnreadableDevice({
|
|
120
|
-
path: UNREADABLE_PATH,
|
|
121
|
-
session: null,
|
|
122
|
-
debugSession: null,
|
|
123
|
-
debug: false,
|
|
124
|
-
}, 'HID_DEVICE');
|
|
125
|
-
this.devices[UNREADABLE_PATH] = device;
|
|
126
|
-
this.emit(events_2.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
const device = this.devices[UNREADABLE_PATH];
|
|
130
|
-
delete this.devices[UNREADABLE_PATH];
|
|
131
|
-
this.emit(events_2.DEVICE.DISCONNECT, device.toMessageObject());
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
this.emit(events_2.TRANSPORT.STREAM, stream);
|
|
136
216
|
}
|
|
137
217
|
async _createAndSaveDevice(descriptor) {
|
|
138
218
|
_log.debug('Creating Device', descriptor);
|
|
139
|
-
await
|
|
219
|
+
await this.handle(descriptor);
|
|
140
220
|
}
|
|
141
221
|
_createUnacquiredDevice(descriptor) {
|
|
142
222
|
_log.debug('Creating Unacquired Device', descriptor);
|
|
143
223
|
const device = Device_1.Device.createUnacquired(this.transport, descriptor);
|
|
144
|
-
device.once(
|
|
145
|
-
this.emit(
|
|
224
|
+
device.once(events_1.DEVICE.ACQUIRED, () => {
|
|
225
|
+
this.emit(events_1.DEVICE.CONNECT, device.toMessageObject());
|
|
146
226
|
});
|
|
147
227
|
return device;
|
|
148
228
|
}
|
|
@@ -166,9 +246,7 @@ class DeviceList extends events_1.default {
|
|
|
166
246
|
return this.asArray().length;
|
|
167
247
|
}
|
|
168
248
|
transportType() {
|
|
169
|
-
|
|
170
|
-
const { activeName } = transport;
|
|
171
|
-
return activeName || 'UnknownTransport';
|
|
249
|
+
return this.transport.name;
|
|
172
250
|
}
|
|
173
251
|
getTransportInfo() {
|
|
174
252
|
return {
|
|
@@ -179,35 +257,29 @@ class DeviceList extends events_1.default {
|
|
|
179
257
|
}
|
|
180
258
|
async dispose() {
|
|
181
259
|
this.removeAllListeners();
|
|
182
|
-
if (this.stream) {
|
|
183
|
-
this.stream.stop();
|
|
184
|
-
}
|
|
185
260
|
if (autoResolveTransportEventTimeout) {
|
|
186
261
|
clearTimeout(autoResolveTransportEventTimeout);
|
|
187
262
|
}
|
|
188
263
|
await Promise.all(this.allDevices().map(device => device.dispose()));
|
|
189
|
-
|
|
190
|
-
this.transport.stop();
|
|
191
|
-
}
|
|
192
|
-
if (this.fetchController) {
|
|
193
|
-
this.fetchController.abort();
|
|
194
|
-
this.fetchController = null;
|
|
195
|
-
}
|
|
264
|
+
this.transport.stop();
|
|
196
265
|
}
|
|
197
266
|
disconnectDevices() {
|
|
198
267
|
this.allDevices().forEach(device => {
|
|
199
|
-
this.emit(
|
|
268
|
+
this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
|
|
200
269
|
});
|
|
201
270
|
}
|
|
202
|
-
enumerate() {
|
|
203
|
-
this.
|
|
204
|
-
if (!
|
|
271
|
+
async enumerate() {
|
|
272
|
+
const res = await this.transport.enumerate().promise;
|
|
273
|
+
if (!res.success) {
|
|
205
274
|
return;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
275
|
+
}
|
|
276
|
+
res.payload.forEach(d => {
|
|
277
|
+
if (this.devices[d.path]) {
|
|
278
|
+
this.devices[d.path].originalDescriptor = {
|
|
279
|
+
session: d.session,
|
|
280
|
+
path: d.path,
|
|
281
|
+
};
|
|
282
|
+
this.devices[d.path].activitySessionID = d.session;
|
|
211
283
|
}
|
|
212
284
|
});
|
|
213
285
|
}
|
|
@@ -230,164 +302,58 @@ class DeviceList extends events_1.default {
|
|
|
230
302
|
const deviceID = device.features.device_id;
|
|
231
303
|
delete this.penalizedDevices[deviceID];
|
|
232
304
|
}
|
|
233
|
-
|
|
234
|
-
exports.DeviceList = DeviceList;
|
|
235
|
-
const getDeviceList = async () => {
|
|
236
|
-
const list = new DeviceList();
|
|
237
|
-
await list.init();
|
|
238
|
-
return list;
|
|
239
|
-
};
|
|
240
|
-
exports.getDeviceList = getDeviceList;
|
|
241
|
-
class CreateDeviceHandler {
|
|
242
|
-
constructor(descriptor, list) {
|
|
243
|
-
this.descriptor = descriptor;
|
|
244
|
-
this.list = list;
|
|
245
|
-
this.path = descriptor.path.toString();
|
|
246
|
-
}
|
|
247
|
-
async handle() {
|
|
305
|
+
async handle(descriptor) {
|
|
248
306
|
var _a;
|
|
249
|
-
|
|
307
|
+
const path = descriptor.path.toString();
|
|
308
|
+
this.creatingDevicesDescriptors[path] = descriptor;
|
|
250
309
|
try {
|
|
251
|
-
await this._takeAndCreateDevice();
|
|
310
|
+
await this._takeAndCreateDevice(descriptor);
|
|
252
311
|
}
|
|
253
312
|
catch (error) {
|
|
254
313
|
_log.debug('Cannot create device', error);
|
|
255
|
-
if (error.code === 'Device_NotFound' ||
|
|
314
|
+
if (error.code === 'Device_NotFound' ||
|
|
315
|
+
error.message === transport_1.TRANSPORT_ERROR.DEVICE_NOT_FOUND ||
|
|
316
|
+
error.message === transport_1.TRANSPORT_ERROR.DEVICE_DISCONNECTED_DURING_ACTION ||
|
|
317
|
+
error.message === transport_1.TRANSPORT_ERROR.UNEXPECTED_ERROR ||
|
|
318
|
+
error.message === transport_1.TRANSPORT_ERROR.INTERFACE_UNABLE_TO_OPEN_DEVICE) {
|
|
319
|
+
delete this.devices[path];
|
|
256
320
|
}
|
|
257
|
-
else if (error.message ===
|
|
258
|
-
|
|
259
|
-
this.
|
|
260
|
-
this._handleUsedElsewhere();
|
|
321
|
+
else if (error.message === transport_1.TRANSPORT_ERROR.SESSION_WRONG_PREVIOUS) {
|
|
322
|
+
this.enumerate();
|
|
323
|
+
this._handleUsedElsewhere(descriptor);
|
|
261
324
|
}
|
|
262
325
|
else if (((_a = error.message) === null || _a === void 0 ? void 0 : _a.indexOf(constants_1.ERRORS.LIBUSB_ERROR_MESSAGE)) >= 0) {
|
|
263
|
-
const device = this.
|
|
264
|
-
this.
|
|
265
|
-
this.
|
|
326
|
+
const device = this._createUnreadableDevice(this.creatingDevicesDescriptors[path], error.message);
|
|
327
|
+
this.devices[path] = device;
|
|
328
|
+
this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
266
329
|
}
|
|
267
330
|
else if (error.code === 'Device_InitializeFailed') {
|
|
268
|
-
this._handleUsedElsewhere();
|
|
331
|
+
this._handleUsedElsewhere(descriptor);
|
|
269
332
|
}
|
|
270
333
|
else if (error.code === 'Device_UsedElsewhere') {
|
|
271
|
-
this._handleUsedElsewhere();
|
|
334
|
+
this._handleUsedElsewhere(descriptor);
|
|
272
335
|
}
|
|
273
336
|
else {
|
|
274
337
|
await (0, promiseUtils_1.resolveAfter)(501, null).promise;
|
|
275
|
-
await this.handle();
|
|
338
|
+
await this.handle(descriptor);
|
|
276
339
|
}
|
|
277
340
|
}
|
|
278
|
-
delete this.
|
|
279
|
-
}
|
|
280
|
-
async _takeAndCreateDevice() {
|
|
281
|
-
const device = Device_1.Device.fromDescriptor(this.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
constructor(list, diff) {
|
|
294
|
-
this.list = list;
|
|
295
|
-
this.diff = diff;
|
|
296
|
-
}
|
|
297
|
-
handle() {
|
|
298
|
-
_log.debug('Update DescriptorStream', this.diff);
|
|
299
|
-
this._createConnectedDevices();
|
|
300
|
-
this._createReleasedDevices();
|
|
301
|
-
this._signalAcquiredDevices();
|
|
302
|
-
this._updateDescriptors();
|
|
303
|
-
this._emitEvents();
|
|
304
|
-
this._disconnectDevices();
|
|
305
|
-
}
|
|
306
|
-
_updateDescriptors() {
|
|
307
|
-
this.diff.descriptors.forEach((descriptor) => {
|
|
308
|
-
const path = descriptor.path.toString();
|
|
309
|
-
const device = this.list.devices[path];
|
|
310
|
-
if (device) {
|
|
311
|
-
device.updateDescriptor(descriptor);
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
_emitEvents() {
|
|
316
|
-
const events = [
|
|
317
|
-
{
|
|
318
|
-
d: this.diff.changedSessions,
|
|
319
|
-
e: events_2.DEVICE.CHANGED,
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
d: this.diff.acquired,
|
|
323
|
-
e: events_2.DEVICE.ACQUIRED,
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
d: this.diff.released,
|
|
327
|
-
e: events_2.DEVICE.RELEASED,
|
|
328
|
-
},
|
|
329
|
-
];
|
|
330
|
-
events.forEach(({ d, e }) => {
|
|
331
|
-
d.forEach(descriptor => {
|
|
332
|
-
const path = descriptor.path.toString();
|
|
333
|
-
const device = this.list.devices[path];
|
|
334
|
-
_log.debug('Event', e, device);
|
|
335
|
-
if (device) {
|
|
336
|
-
this.list.emit(e, device.toMessageObject());
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
_createConnectedDevices() {
|
|
342
|
-
this.diff.connected.forEach(async (descriptor) => {
|
|
343
|
-
const path = descriptor.path.toString();
|
|
344
|
-
const priority = DataManager_1.DataManager.getSettings('priority');
|
|
345
|
-
const penalty = this.list.getAuthPenalty();
|
|
346
|
-
_log.debug('Connected', priority, penalty, descriptor.session, this.list.devices);
|
|
347
|
-
if (priority || penalty) {
|
|
348
|
-
await (0, promiseUtils_1.resolveAfter)(501 + penalty + 100 * priority, null).promise;
|
|
349
|
-
}
|
|
350
|
-
if (descriptor.session == null) {
|
|
351
|
-
await this.list._createAndSaveDevice(descriptor);
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
const device = await this.list._createUnacquiredDevice(descriptor);
|
|
355
|
-
this.list.devices[path] = device;
|
|
356
|
-
this.list.emit(events_2.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
_signalAcquiredDevices() {
|
|
361
|
-
this.diff.acquired.forEach(descriptor => {
|
|
362
|
-
const path = descriptor.path.toString();
|
|
363
|
-
if (this.list.creatingDevicesDescriptors[path]) {
|
|
364
|
-
this.list.creatingDevicesDescriptors[path] = descriptor;
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
_createReleasedDevices() {
|
|
369
|
-
this.diff.released.forEach(async (descriptor) => {
|
|
370
|
-
const path = descriptor.path.toString();
|
|
371
|
-
const device = this.list.devices[path];
|
|
372
|
-
if (device) {
|
|
373
|
-
if (device.isUnacquired() && !device.isInconsistent()) {
|
|
374
|
-
await (0, promiseUtils_1.resolveAfter)(501, null).promise;
|
|
375
|
-
_log.debug('Create device from unacquired', device);
|
|
376
|
-
await this.list._createAndSaveDevice(descriptor);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
_disconnectDevices() {
|
|
382
|
-
this.diff.disconnected.forEach(descriptor => {
|
|
383
|
-
const path = descriptor.path.toString();
|
|
384
|
-
const device = this.list.devices[path];
|
|
385
|
-
if (device != null) {
|
|
386
|
-
device.disconnect();
|
|
387
|
-
delete this.list.devices[path];
|
|
388
|
-
this.list.emit(events_2.DEVICE.DISCONNECT, device.toMessageObject());
|
|
389
|
-
}
|
|
390
|
-
});
|
|
341
|
+
delete this.creatingDevicesDescriptors[path];
|
|
342
|
+
}
|
|
343
|
+
async _takeAndCreateDevice(descriptor) {
|
|
344
|
+
const device = Device_1.Device.fromDescriptor(this.transport, descriptor);
|
|
345
|
+
const path = descriptor.path.toString();
|
|
346
|
+
this.devices[path] = device;
|
|
347
|
+
const promise = device.run();
|
|
348
|
+
await promise;
|
|
349
|
+
this.emit(events_1.DEVICE.CONNECT, device.toMessageObject());
|
|
350
|
+
}
|
|
351
|
+
_handleUsedElsewhere(descriptor) {
|
|
352
|
+
const path = descriptor.path.toString();
|
|
353
|
+
const device = this._createUnacquiredDevice(this.creatingDevicesDescriptors[path]);
|
|
354
|
+
this.devices[path] = device;
|
|
355
|
+
this.emit(events_1.DEVICE.CONNECT_UNACQUIRED, device.toMessageObject());
|
|
391
356
|
}
|
|
392
357
|
}
|
|
358
|
+
exports.DeviceList = DeviceList;
|
|
393
359
|
//# sourceMappingURL=DeviceList.js.map
|