@onekeyfe/hd-transport-web-device 1.2.2-alpha.1 → 1.2.2-alpha.100
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/__tests__/electron-ble-transport.test.ts +11 -95
- package/__tests__/webusb-protocol-cache.test.ts +0 -32
- package/__tests__/webusb-protocol-v2-timeout.test.ts +1 -8
- package/dist/electron-ble-transport.d.ts +0 -2
- package/dist/electron-ble-transport.d.ts.map +1 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.js +20 -98
- package/dist/webusb.d.ts +0 -1
- package/dist/webusb.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/electron-ble-transport.ts +10 -87
- package/src/webusb.ts +5 -37
|
@@ -73,26 +73,8 @@ const protocolV2Schema = {
|
|
|
73
73
|
},
|
|
74
74
|
},
|
|
75
75
|
},
|
|
76
|
-
Failure: {
|
|
77
|
-
fields: {
|
|
78
|
-
code: {
|
|
79
|
-
type: 'FailureType',
|
|
80
|
-
id: 1,
|
|
81
|
-
},
|
|
82
|
-
message: {
|
|
83
|
-
type: 'string',
|
|
84
|
-
id: 2,
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
FailureType: {
|
|
89
|
-
values: {
|
|
90
|
-
Failure_ProcessError: 5,
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
76
|
MessageType: {
|
|
94
77
|
values: {
|
|
95
|
-
MessageType_Failure: 3,
|
|
96
78
|
MessageType_ProtocolInfoRequest: 60200,
|
|
97
79
|
MessageType_ProtocolInfo: 60201,
|
|
98
80
|
MessageType_Ping: 60206,
|
|
@@ -345,7 +327,7 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
345
327
|
}
|
|
346
328
|
});
|
|
347
329
|
|
|
348
|
-
test('reconnects
|
|
330
|
+
test('reconnects Protocol V1 with a non-destructive GetFeatures probe', async () => {
|
|
349
331
|
const device = { id: 'classic-id', name: 'OneKey Classic' };
|
|
350
332
|
const nobleBle = createNobleBle(device);
|
|
351
333
|
let notificationHandler: ((deviceId: string, data: string) => void) | undefined;
|
|
@@ -378,10 +360,7 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
378
360
|
uuid: device.id,
|
|
379
361
|
})
|
|
380
362
|
);
|
|
381
|
-
|
|
382
|
-
// declares V1 and must send nothing at all, leaving the first frame on
|
|
383
|
-
// the link to Core — which is what carries the wallet session.
|
|
384
|
-
expect(nobleBle.write).toHaveBeenCalledTimes(1);
|
|
363
|
+
expect(nobleBle.write).toHaveBeenCalledTimes(2);
|
|
385
364
|
expect(nobleBle.write.mock.calls.every(([, hex]) => /^3f23230037/.test(hex))).toBe(true);
|
|
386
365
|
expect(protocolV2Writer).not.toHaveBeenCalled();
|
|
387
366
|
} finally {
|
|
@@ -394,13 +373,19 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
394
373
|
const nobleBle = createNobleBle(device);
|
|
395
374
|
let notificationHandler: ((deviceId: string, data: string) => void) | undefined;
|
|
396
375
|
const v1ResponseHex = '3f23230002000000040a026f6b';
|
|
376
|
+
let writeCount = 0;
|
|
377
|
+
|
|
397
378
|
nobleBle.onNotification.mockImplementation(handler => {
|
|
398
379
|
notificationHandler = handler;
|
|
399
380
|
return jest.fn();
|
|
400
381
|
});
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
382
|
+
nobleBle.write.mockImplementation(() => {
|
|
383
|
+
writeCount += 1;
|
|
384
|
+
if (writeCount === 1) {
|
|
385
|
+
setTimeout(() => notificationHandler?.(device.id, v1ResponseHex), 0);
|
|
386
|
+
}
|
|
387
|
+
return Promise.resolve();
|
|
388
|
+
});
|
|
404
389
|
const bleTransport = configureTransport(nobleBle);
|
|
405
390
|
|
|
406
391
|
await bleTransport.acquire({ uuid: device.id, expectedProtocol: 'V1' });
|
|
@@ -479,41 +464,6 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
479
464
|
expect(transport.getProtocolType(device.id)).toBeUndefined();
|
|
480
465
|
});
|
|
481
466
|
|
|
482
|
-
test('surfaces Protocol V2 link disabled while the initial V1 probe is active', async () => {
|
|
483
|
-
const device = { id: 'usb-priority-pro2-id', name: 'OneKey Pro 2' };
|
|
484
|
-
const nobleBle = createNobleBle(device);
|
|
485
|
-
let notificationHandler: ((deviceId: string, data: string) => void) | undefined;
|
|
486
|
-
|
|
487
|
-
nobleBle.onNotification.mockImplementation(handler => {
|
|
488
|
-
notificationHandler = handler;
|
|
489
|
-
return jest.fn();
|
|
490
|
-
});
|
|
491
|
-
nobleBle.write.mockImplementation(() => {
|
|
492
|
-
const response = ProtocolV2.encodeFrame(
|
|
493
|
-
schemas,
|
|
494
|
-
'Failure',
|
|
495
|
-
{ code: 5, message: 'link disabled' },
|
|
496
|
-
{ router: PROTOCOL_V2_CHANNEL_BLE_UART }
|
|
497
|
-
);
|
|
498
|
-
const splitAt = 4;
|
|
499
|
-
setTimeout(() => {
|
|
500
|
-
notificationHandler?.(device.id, bytesToHex(response.subarray(0, splitAt)));
|
|
501
|
-
notificationHandler?.(device.id, bytesToHex(response.subarray(splitAt)));
|
|
502
|
-
}, 0);
|
|
503
|
-
return Promise.resolve();
|
|
504
|
-
});
|
|
505
|
-
const transport = configureTransport(nobleBle);
|
|
506
|
-
|
|
507
|
-
await expect(transport.acquire({ uuid: device.id })).rejects.toMatchObject({
|
|
508
|
-
name: 'ProtocolV2LinkDisabledError',
|
|
509
|
-
failureCode: 'Failure_ProcessError',
|
|
510
|
-
firmwareMessage: 'link disabled',
|
|
511
|
-
});
|
|
512
|
-
expect(nobleBle.write).toHaveBeenCalledTimes(1);
|
|
513
|
-
expect(nobleBle.unsubscribe).toHaveBeenCalledWith(device.id);
|
|
514
|
-
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
515
|
-
});
|
|
516
|
-
|
|
517
467
|
test('keeps a first expected Protocol V2 probe miss retryable', async () => {
|
|
518
468
|
const device = { id: 'first-v2-id', name: 'OneKey Pro 2' };
|
|
519
469
|
const nobleBle = createNobleBle(device);
|
|
@@ -550,40 +500,6 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
550
500
|
expect(transport.getProtocolType(device.id)).toBeUndefined();
|
|
551
501
|
});
|
|
552
502
|
|
|
553
|
-
test('fails Protocol V2 acquire immediately when subscribe reports insufficient encryption', async () => {
|
|
554
|
-
const device = { id: 'stale-bond-pro2-id', name: 'OneKey Pro 2' };
|
|
555
|
-
const nobleBle = createNobleBle(device);
|
|
556
|
-
nobleBle.subscribe.mockRejectedValue(new Error('Encryption is insufficient'));
|
|
557
|
-
const transport = configureTransport(nobleBle);
|
|
558
|
-
const probe = jest.spyOn(transport as any, 'probeProtocolV2');
|
|
559
|
-
|
|
560
|
-
await expect(
|
|
561
|
-
transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
|
|
562
|
-
).rejects.toMatchObject({
|
|
563
|
-
errorCode: HardwareErrorCode.BleDeviceBondError,
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
expect(probe).not.toHaveBeenCalled();
|
|
567
|
-
expect(nobleBle.unsubscribe).toHaveBeenCalledWith(device.id);
|
|
568
|
-
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
569
|
-
});
|
|
570
|
-
|
|
571
|
-
test('keeps stale-bond subscribe mapping out of Protocol V1 acquire', async () => {
|
|
572
|
-
const device = { id: 'classic-v1-id', name: 'OneKey Classic' };
|
|
573
|
-
const nobleBle = createNobleBle(device);
|
|
574
|
-
nobleBle.subscribe.mockRejectedValue(new Error('Encryption is insufficient'));
|
|
575
|
-
const transport = configureTransport(nobleBle);
|
|
576
|
-
|
|
577
|
-
try {
|
|
578
|
-
await transport.acquire({ uuid: device.id, expectedProtocol: 'V1' });
|
|
579
|
-
throw new Error('Expected Protocol V1 acquire to fail');
|
|
580
|
-
} catch (error) {
|
|
581
|
-
expect(error).toBeInstanceOf(Error);
|
|
582
|
-
expect((error as Error).message).toBe('Encryption is insufficient');
|
|
583
|
-
expect((error as { errorCode?: unknown }).errorCode).toBeUndefined();
|
|
584
|
-
}
|
|
585
|
-
});
|
|
586
|
-
|
|
587
503
|
test('reports a stale bond when a previously confirmed Protocol V2 device stops responding', async () => {
|
|
588
504
|
const device = { id: 'reset-pro2-id', name: 'OneKey Pro 2' };
|
|
589
505
|
const nobleBle = createNobleBle(device);
|
|
@@ -69,38 +69,6 @@ describe('WebUsbTransport protocol probe cache', () => {
|
|
|
69
69
|
expect(webusb.detectProtocol).toHaveBeenCalledWith(path, 'V1', undefined);
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
-
test('acquire reuses a previously confirmed protocol during explicit no-probe recovery', async () => {
|
|
73
|
-
const webusb = buildAcquirableTransport();
|
|
74
|
-
const path = 'pro-webusb';
|
|
75
|
-
webusb.deviceProtocol.set(path, 'V1');
|
|
76
|
-
webusb.confirmedDeviceProtocols.set(path, 'V2');
|
|
77
|
-
webusb.markProtocolStale(path);
|
|
78
|
-
webusb.detectProtocol = jest.fn();
|
|
79
|
-
|
|
80
|
-
await expect(
|
|
81
|
-
webusb.acquire({ path, expectedProtocol: 'V2', skipProtocolProbe: true })
|
|
82
|
-
).resolves.toBe(path);
|
|
83
|
-
|
|
84
|
-
expect(webusb.detectProtocol).not.toHaveBeenCalled();
|
|
85
|
-
expect(webusb.deviceProtocol.get(path)).toBe('V2');
|
|
86
|
-
expect(webusb.staleProtocolPaths.has(path)).toBe(false);
|
|
87
|
-
expect(webusb.acquiredPaths.has(path)).toBe(true);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
test('acquire rejects no-probe recovery without a previously confirmed protocol', async () => {
|
|
91
|
-
const webusb = buildAcquirableTransport();
|
|
92
|
-
const path = 'pro-webusb';
|
|
93
|
-
webusb.detectProtocol = jest.fn();
|
|
94
|
-
|
|
95
|
-
await expect(
|
|
96
|
-
webusb.acquire({ path, expectedProtocol: 'V2', skipProtocolProbe: true })
|
|
97
|
-
).rejects.toThrow('previously confirmed protocol');
|
|
98
|
-
|
|
99
|
-
expect(webusb.detectProtocol).not.toHaveBeenCalled();
|
|
100
|
-
expect(webusb.deviceProtocol.has(path)).toBe(false);
|
|
101
|
-
expect(webusb.acquiredPaths.has(path)).toBe(false);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
72
|
test('forced protocol detection bypasses a valid cache and probes on the wire', async () => {
|
|
105
73
|
const webusb = buildAcquirableTransport();
|
|
106
74
|
const path = 'pro-webusb';
|
|
@@ -387,13 +387,6 @@ describe('WebUsbTransport Protocol V2 timeout recovery', () => {
|
|
|
387
387
|
webusb.callProtocolV2(path, 'Ping', { message: 'short' }, { timeoutMs: 25 }),
|
|
388
388
|
]);
|
|
389
389
|
|
|
390
|
-
|
|
391
|
-
// queued one is a deadline, so it arrives with whatever the first call left
|
|
392
|
-
// of its 25ms — asserting the exact remainder makes this fail on a loaded
|
|
393
|
-
// machine, which is timing, not behaviour.
|
|
394
|
-
expect(readTimeouts).toHaveLength(2);
|
|
395
|
-
expect(readTimeouts[0]).toBe(1_000);
|
|
396
|
-
expect(readTimeouts[1]).toBeGreaterThan(0);
|
|
397
|
-
expect(readTimeouts[1]).toBeLessThanOrEqual(25);
|
|
390
|
+
expect(readTimeouts).toEqual([1_000, 25]);
|
|
398
391
|
});
|
|
399
392
|
});
|
|
@@ -41,7 +41,6 @@ export default class ElectronBleTransport {
|
|
|
41
41
|
private hostDisconnectCleanup?;
|
|
42
42
|
private notificationTokens;
|
|
43
43
|
private nextNotificationToken;
|
|
44
|
-
private toStaleBondError;
|
|
45
44
|
private handleBluetoothError;
|
|
46
45
|
private cleanupDeviceState;
|
|
47
46
|
init(logger: any, emitter?: EventEmitter): void;
|
|
@@ -79,7 +78,6 @@ export default class ElectronBleTransport {
|
|
|
79
78
|
private createMtuSubscription;
|
|
80
79
|
private writeProtocolV2Frame;
|
|
81
80
|
private handleNotification;
|
|
82
|
-
private readProtocolV2LinkDisabledFailure;
|
|
83
81
|
private handleProtocolV2Notification;
|
|
84
82
|
private getProtocolV2FrameQueue;
|
|
85
83
|
private resolveProtocolV2Frame;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,8 +19,6 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
|
|
|
19
19
|
private protocolV2SchemaSource;
|
|
20
20
|
/** Per-path protocol type detected by active wire-level probe. */
|
|
21
21
|
private deviceProtocol;
|
|
22
|
-
/** Protocols previously confirmed by an active response for this transport instance. */
|
|
23
|
-
private confirmedDeviceProtocols;
|
|
24
22
|
private deviceProtocolHints;
|
|
25
23
|
/**
|
|
26
24
|
* Paths whose cached protocol must be re-probed on the next acquire (a USB
|
|
@@ -242,7 +240,6 @@ declare class ElectronBleTransport {
|
|
|
242
240
|
private hostDisconnectCleanup?;
|
|
243
241
|
private notificationTokens;
|
|
244
242
|
private nextNotificationToken;
|
|
245
|
-
private toStaleBondError;
|
|
246
243
|
private handleBluetoothError;
|
|
247
244
|
private cleanupDeviceState;
|
|
248
245
|
init(logger: any, emitter?: EventEmitter): void;
|
|
@@ -285,7 +282,6 @@ declare class ElectronBleTransport {
|
|
|
285
282
|
private createMtuSubscription;
|
|
286
283
|
private writeProtocolV2Frame;
|
|
287
284
|
private handleNotification;
|
|
288
|
-
private readProtocolV2LinkDisabledFailure;
|
|
289
285
|
private handleProtocolV2Notification;
|
|
290
286
|
private getProtocolV2FrameQueue;
|
|
291
287
|
private resolveProtocolV2Frame;
|
package/dist/index.js
CHANGED
|
@@ -79,7 +79,6 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
79
79
|
logPrefix: 'ProtocolV2 WebUSB',
|
|
80
80
|
});
|
|
81
81
|
this.deviceProtocol = new Map();
|
|
82
|
-
this.confirmedDeviceProtocols = new Map();
|
|
83
82
|
this.deviceProtocolHints = new Map();
|
|
84
83
|
this.staleProtocolPaths = new Set();
|
|
85
84
|
this.acquiredPaths = new Set();
|
|
@@ -183,7 +182,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
183
182
|
});
|
|
184
183
|
}
|
|
185
184
|
acquire(input) {
|
|
186
|
-
var _a, _b, _c, _d, _e, _f
|
|
185
|
+
var _a, _b, _c, _d, _e, _f;
|
|
187
186
|
return __awaiter(this, void 0, void 0, function* () {
|
|
188
187
|
if (!input.path)
|
|
189
188
|
return;
|
|
@@ -191,53 +190,35 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
191
190
|
yield this.rotateProtocolV2UsbGeneration(input.path, 'WebUSB transport acquired');
|
|
192
191
|
yield this.closeOpenDevice(input.path);
|
|
193
192
|
yield this.connect((_a = input.path) !== null && _a !== void 0 ? _a : '', true);
|
|
194
|
-
if (input.
|
|
195
|
-
if (!input.expectedProtocol) {
|
|
196
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'skipProtocolProbe requires an expected protocol');
|
|
197
|
-
}
|
|
198
|
-
if (this.confirmedDeviceProtocols.get(input.path) !== input.expectedProtocol) {
|
|
199
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'skipProtocolProbe requires a previously confirmed protocol for this WebUSB endpoint');
|
|
200
|
-
}
|
|
201
|
-
this.staleProtocolPaths.delete(input.path);
|
|
202
|
-
this.deviceProtocol.set(input.path, input.expectedProtocol);
|
|
203
|
-
const currentDevice = (_b = this.deviceList.find(d => d.path === input.path)) === null || _b === void 0 ? void 0 : _b.device;
|
|
204
|
-
if (currentDevice) {
|
|
205
|
-
this.probedDeviceObjects.set(input.path, currentDevice);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
else if (input.forceProtocolDetection) {
|
|
193
|
+
if (input.forceProtocolDetection) {
|
|
209
194
|
this.staleProtocolPaths.delete(input.path);
|
|
210
195
|
this.deviceProtocol.delete(input.path);
|
|
211
196
|
this.deviceProtocolHints.delete(input.path);
|
|
212
197
|
}
|
|
213
|
-
if (
|
|
198
|
+
if (this.staleProtocolPaths.has(input.path)) {
|
|
214
199
|
this.staleProtocolPaths.delete(input.path);
|
|
215
200
|
this.deviceProtocol.delete(input.path);
|
|
216
201
|
}
|
|
217
|
-
if (
|
|
218
|
-
const currentDevice = (
|
|
202
|
+
if (this.deviceProtocol.has(input.path)) {
|
|
203
|
+
const currentDevice = (_b = this.deviceList.find(d => d.path === input.path)) === null || _b === void 0 ? void 0 : _b.device;
|
|
219
204
|
if (!currentDevice || currentDevice !== this.probedDeviceObjects.get(input.path)) {
|
|
220
205
|
this.deviceProtocol.delete(input.path);
|
|
221
206
|
}
|
|
222
207
|
}
|
|
223
208
|
const cachedProtocol = this.deviceProtocol.get(input.path);
|
|
224
|
-
if (
|
|
225
|
-
cachedProtocol &&
|
|
226
|
-
input.expectedProtocol &&
|
|
227
|
-
cachedProtocol !== input.expectedProtocol) {
|
|
209
|
+
if (cachedProtocol && input.expectedProtocol && cachedProtocol !== input.expectedProtocol) {
|
|
228
210
|
this.deviceProtocol.delete(input.path);
|
|
229
211
|
}
|
|
230
212
|
if (!this.deviceProtocol.has(input.path)) {
|
|
231
|
-
const usbDevice = (
|
|
213
|
+
const usbDevice = (_c = this.deviceList.find(device => device.path === input.path)) === null || _c === void 0 ? void 0 : _c.device;
|
|
232
214
|
const protocolHint = input.expectedProtocol
|
|
233
215
|
? undefined
|
|
234
|
-
: (
|
|
216
|
+
: (_e = (_d = input.protocolHint) !== null && _d !== void 0 ? _d : this.deviceProtocolHints.get(input.path)) !== null && _e !== void 0 ? _e : hdShared.inferProtocolHintFromUsbId(usbDevice === null || usbDevice === void 0 ? void 0 : usbDevice.vendorId, usbDevice === null || usbDevice === void 0 ? void 0 : usbDevice.productId);
|
|
235
217
|
if (protocolHint) {
|
|
236
218
|
this.deviceProtocolHints.set(input.path, protocolHint);
|
|
237
219
|
}
|
|
238
|
-
|
|
239
|
-
this.
|
|
240
|
-
const probedDevice = (_g = this.deviceList.find(d => d.path === input.path)) === null || _g === void 0 ? void 0 : _g.device;
|
|
220
|
+
yield this.detectProtocol(input.path, input.expectedProtocol, protocolHint);
|
|
221
|
+
const probedDevice = (_f = this.deviceList.find(d => d.path === input.path)) === null || _f === void 0 ? void 0 : _f.device;
|
|
241
222
|
if (probedDevice) {
|
|
242
223
|
this.probedDeviceObjects.set(input.path, probedDevice);
|
|
243
224
|
}
|
|
@@ -871,29 +852,7 @@ class ElectronBleTransport {
|
|
|
871
852
|
this.notificationTokens = new Map();
|
|
872
853
|
this.nextNotificationToken = 1;
|
|
873
854
|
}
|
|
874
|
-
|
|
875
|
-
var _a;
|
|
876
|
-
if (hdShared.isBleStaleBondHardwareError(error)) {
|
|
877
|
-
return error;
|
|
878
|
-
}
|
|
879
|
-
const errorMessage = error && typeof error === 'object' && 'message' in error
|
|
880
|
-
? String((_a = error.message) !== null && _a !== void 0 ? _a : '')
|
|
881
|
-
: String(error !== null && error !== void 0 ? error : '');
|
|
882
|
-
if (!hdShared.isBleStaleBondErrorText(errorMessage)) {
|
|
883
|
-
return null;
|
|
884
|
-
}
|
|
885
|
-
const normalizedErrorMessage = errorMessage.toLowerCase();
|
|
886
|
-
return hdShared.ERRORS.TypedError(normalizedErrorMessage.includes('peer removed pairing information')
|
|
887
|
-
? hdShared.HardwareErrorCode.BlePeerRemovedPairingInformation
|
|
888
|
-
: hdShared.HardwareErrorCode.BleDeviceBondError, errorMessage);
|
|
889
|
-
}
|
|
890
|
-
handleBluetoothError(error, mapProtocolV2StaleBond = false) {
|
|
891
|
-
if (mapProtocolV2StaleBond) {
|
|
892
|
-
const staleBondError = this.toStaleBondError(error);
|
|
893
|
-
if (staleBondError) {
|
|
894
|
-
throw staleBondError;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
855
|
+
handleBluetoothError(error) {
|
|
897
856
|
if (error && typeof error === 'object') {
|
|
898
857
|
if ('code' in error) {
|
|
899
858
|
if (error.code === hdShared.HardwareErrorCode.BlePoweredOff) {
|
|
@@ -1024,9 +983,6 @@ class ElectronBleTransport {
|
|
|
1024
983
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1025
984
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1026
985
|
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
1027
|
-
const shouldMapProtocolV2StaleBond = expectedProtocol
|
|
1028
|
-
? expectedProtocol === 'V2'
|
|
1029
|
-
: this.confirmedProtocolV2.has(uuid);
|
|
1030
986
|
if (!uuid) {
|
|
1031
987
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleRequiredUUID);
|
|
1032
988
|
}
|
|
@@ -1058,7 +1014,7 @@ class ElectronBleTransport {
|
|
|
1058
1014
|
this.connectedDevices.add(uuid);
|
|
1059
1015
|
}
|
|
1060
1016
|
catch (error) {
|
|
1061
|
-
this.handleBluetoothError(error
|
|
1017
|
+
this.handleBluetoothError(error);
|
|
1062
1018
|
}
|
|
1063
1019
|
const mtuCleanup = this.createMtuSubscription(uuid);
|
|
1064
1020
|
if (mtuCleanup) {
|
|
@@ -1066,12 +1022,7 @@ class ElectronBleTransport {
|
|
|
1066
1022
|
}
|
|
1067
1023
|
this.v1Buffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
1068
1024
|
this.v2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler(transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
1069
|
-
|
|
1070
|
-
yield window.desktopApi.nobleBle.subscribe(uuid);
|
|
1071
|
-
}
|
|
1072
|
-
catch (error) {
|
|
1073
|
-
this.handleBluetoothError(error, shouldMapProtocolV2StaleBond);
|
|
1074
|
-
}
|
|
1025
|
+
yield window.desktopApi.nobleBle.subscribe(uuid);
|
|
1075
1026
|
yield this.refreshBlePacketCapacity(uuid);
|
|
1076
1027
|
const cleanup = this.createNotificationSubscription(uuid);
|
|
1077
1028
|
this.notificationCleanups.set(uuid, cleanup);
|
|
@@ -1177,9 +1128,12 @@ class ElectronBleTransport {
|
|
|
1177
1128
|
var _a, _b, _c;
|
|
1178
1129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1179
1130
|
if (expectedProtocol === 'V1') {
|
|
1180
|
-
this.
|
|
1181
|
-
|
|
1182
|
-
|
|
1131
|
+
if (yield this.probeProtocolV1(uuid)) {
|
|
1132
|
+
this.deviceProtocol.set(uuid, 'V1');
|
|
1133
|
+
(_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V1 (expected)`);
|
|
1134
|
+
return 'V1';
|
|
1135
|
+
}
|
|
1136
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
1183
1137
|
}
|
|
1184
1138
|
if (expectedProtocol === 'V2') {
|
|
1185
1139
|
if (yield this.probeProtocolV2(uuid)) {
|
|
@@ -1257,9 +1211,6 @@ class ElectronBleTransport {
|
|
|
1257
1211
|
catch (error) {
|
|
1258
1212
|
this.clearProbeProtocol(uuid, 'V1');
|
|
1259
1213
|
(_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[Electron BLE] Protocol V1 GetFeatures probe failed:', error);
|
|
1260
|
-
if (transport.isProtocolV2LinkDisabledError(error)) {
|
|
1261
|
-
throw error;
|
|
1262
|
-
}
|
|
1263
1214
|
return false;
|
|
1264
1215
|
}
|
|
1265
1216
|
});
|
|
@@ -1282,7 +1233,6 @@ class ElectronBleTransport {
|
|
|
1282
1233
|
(_a = this.v2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1283
1234
|
this.resetProtocolV2Frames(uuid);
|
|
1284
1235
|
},
|
|
1285
|
-
shouldRethrow: error => hdShared.isBleStaleBondHardwareError(error) || transport.isProtocolV2LinkDisabledError(error),
|
|
1286
1236
|
});
|
|
1287
1237
|
if (!detected) {
|
|
1288
1238
|
this.clearProbeProtocol(uuid, 'V2');
|
|
@@ -1297,16 +1247,7 @@ class ElectronBleTransport {
|
|
|
1297
1247
|
if (!nobleBle) {
|
|
1298
1248
|
throw new Error('Noble BLE API not available');
|
|
1299
1249
|
}
|
|
1300
|
-
|
|
1301
|
-
yield nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
|
|
1302
|
-
}
|
|
1303
|
-
catch (error) {
|
|
1304
|
-
const staleBondError = this.toStaleBondError(error);
|
|
1305
|
-
if (staleBondError) {
|
|
1306
|
-
throw staleBondError;
|
|
1307
|
-
}
|
|
1308
|
-
throw error;
|
|
1309
|
-
}
|
|
1250
|
+
yield nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
|
|
1310
1251
|
});
|
|
1311
1252
|
}
|
|
1312
1253
|
refreshBlePacketCapacity(uuid) {
|
|
@@ -1375,27 +1316,8 @@ class ElectronBleTransport {
|
|
|
1375
1316
|
this.handleProtocolV2Notification(deviceId, hexData);
|
|
1376
1317
|
return;
|
|
1377
1318
|
}
|
|
1378
|
-
const linkDisabledError = this.readProtocolV2LinkDisabledFailure(deviceId, hexData);
|
|
1379
|
-
if (linkDisabledError) {
|
|
1380
|
-
if (this.runPromise && this.runPromiseDeviceId === deviceId) {
|
|
1381
|
-
this.runPromise.reject(linkDisabledError);
|
|
1382
|
-
}
|
|
1383
|
-
return;
|
|
1384
|
-
}
|
|
1385
1319
|
this.handleProtocolV1Notification(deviceId, hexData);
|
|
1386
1320
|
}
|
|
1387
|
-
readProtocolV2LinkDisabledFailure(deviceId, hexData) {
|
|
1388
|
-
if (!this._messages || !this._messagesV2)
|
|
1389
|
-
return undefined;
|
|
1390
|
-
const assembler = this.v2Assemblers.get(deviceId);
|
|
1391
|
-
if (!assembler)
|
|
1392
|
-
return undefined;
|
|
1393
|
-
return transport.detectProtocolV2LinkDisabledError({
|
|
1394
|
-
schemas: { protocolV1: this._messages, protocolV2: this._messagesV2 },
|
|
1395
|
-
assembler,
|
|
1396
|
-
bytes: transport.hexToBytes(hexData),
|
|
1397
|
-
});
|
|
1398
|
-
}
|
|
1399
1321
|
handleProtocolV2Notification(deviceId, hexData) {
|
|
1400
1322
|
var _a;
|
|
1401
1323
|
try {
|
package/dist/webusb.d.ts
CHANGED
|
@@ -13,7 +13,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
13
13
|
messagesV2: ReturnType<typeof transport.parseConfigure> | undefined;
|
|
14
14
|
private protocolV2SchemaSource;
|
|
15
15
|
private deviceProtocol;
|
|
16
|
-
private confirmedDeviceProtocols;
|
|
17
16
|
private deviceProtocolHints;
|
|
18
17
|
private staleProtocolPaths;
|
|
19
18
|
private acquiredPaths;
|
package/dist/webusb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":";;AACA,OAAO,SAAS,EAAE,EAQhB,0BAA0B,EAG3B,MAAM,wBAAwB,CAAC;AAYhC,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAuBhC,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAuCD,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,0BAA0B,CAAC,MAAM,CAAC;IAC7E,QAAQ,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAGlE,UAAU,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEpE,OAAO,CAAC,sBAAsB,CAAqB;IAGnD,OAAO,CAAC,cAAc,CAAwC;
|
|
1
|
+
{"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.2.2-alpha.
|
|
3
|
+
"version": "1.2.2-alpha.100",
|
|
4
4
|
"author": "OneKey",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"lint:fix": "eslint . --fix"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@onekeyfe/hd-shared": "1.2.2-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.2-alpha.
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.2-alpha.100",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.2-alpha.100"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@onekeyfe/hd-transport-electron": "1.2.2-alpha.
|
|
28
|
+
"@onekeyfe/hd-transport-electron": "1.2.2-alpha.100",
|
|
29
29
|
"@types/w3c-web-usb": "^1.0.6",
|
|
30
30
|
"@types/web-bluetooth": "^0.0.17"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "c40dad085297b0e3cc2020bd218c146dff6ed3e1"
|
|
33
33
|
}
|
|
@@ -6,9 +6,7 @@ import transport, {
|
|
|
6
6
|
ProtocolV2LinkManager,
|
|
7
7
|
TRANSPORT_EVENT,
|
|
8
8
|
bytesToHex,
|
|
9
|
-
detectProtocolV2LinkDisabledError,
|
|
10
9
|
hexToBytes,
|
|
11
|
-
isProtocolV2LinkDisabledError,
|
|
12
10
|
probeProtocolV2 as probeProtocolV2Helper,
|
|
13
11
|
writeProtocolV2BleFrame,
|
|
14
12
|
} from '@onekeyfe/hd-transport';
|
|
@@ -18,8 +16,6 @@ import {
|
|
|
18
16
|
HardwareErrorCode,
|
|
19
17
|
HardwareErrorCodeMessage,
|
|
20
18
|
createDeferred,
|
|
21
|
-
isBleStaleBondErrorText,
|
|
22
|
-
isBleStaleBondHardwareError,
|
|
23
19
|
isHeaderChunk,
|
|
24
20
|
} from '@onekeyfe/hd-shared';
|
|
25
21
|
|
|
@@ -163,33 +159,7 @@ export default class ElectronBleTransport {
|
|
|
163
159
|
|
|
164
160
|
private nextNotificationToken = 1;
|
|
165
161
|
|
|
166
|
-
private
|
|
167
|
-
if (isBleStaleBondHardwareError(error)) {
|
|
168
|
-
return error as Error;
|
|
169
|
-
}
|
|
170
|
-
const errorMessage =
|
|
171
|
-
error && typeof error === 'object' && 'message' in error
|
|
172
|
-
? String((error as { message?: unknown }).message ?? '')
|
|
173
|
-
: String(error ?? '');
|
|
174
|
-
if (!isBleStaleBondErrorText(errorMessage)) {
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
const normalizedErrorMessage = errorMessage.toLowerCase();
|
|
178
|
-
return ERRORS.TypedError(
|
|
179
|
-
normalizedErrorMessage.includes('peer removed pairing information')
|
|
180
|
-
? HardwareErrorCode.BlePeerRemovedPairingInformation
|
|
181
|
-
: HardwareErrorCode.BleDeviceBondError,
|
|
182
|
-
errorMessage
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
private handleBluetoothError(error: any, mapProtocolV2StaleBond = false): never {
|
|
187
|
-
if (mapProtocolV2StaleBond) {
|
|
188
|
-
const staleBondError = this.toStaleBondError(error);
|
|
189
|
-
if (staleBondError) {
|
|
190
|
-
throw staleBondError;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
162
|
+
private handleBluetoothError(error: any): never {
|
|
193
163
|
if (error && typeof error === 'object') {
|
|
194
164
|
if ('code' in error) {
|
|
195
165
|
if (error.code === HardwareErrorCode.BlePoweredOff) {
|
|
@@ -350,9 +320,6 @@ export default class ElectronBleTransport {
|
|
|
350
320
|
|
|
351
321
|
async acquire(input: BleAcquireInput) {
|
|
352
322
|
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
353
|
-
const shouldMapProtocolV2StaleBond = expectedProtocol
|
|
354
|
-
? expectedProtocol === 'V2'
|
|
355
|
-
: this.confirmedProtocolV2.has(uuid);
|
|
356
323
|
|
|
357
324
|
if (!uuid) {
|
|
358
325
|
throw ERRORS.TypedError(HardwareErrorCode.BleRequiredUUID);
|
|
@@ -389,7 +356,7 @@ export default class ElectronBleTransport {
|
|
|
389
356
|
await window.desktopApi.nobleBle.connect(uuid);
|
|
390
357
|
this.connectedDevices.add(uuid);
|
|
391
358
|
} catch (error) {
|
|
392
|
-
this.handleBluetoothError(error
|
|
359
|
+
this.handleBluetoothError(error);
|
|
393
360
|
}
|
|
394
361
|
|
|
395
362
|
const mtuCleanup = this.createMtuSubscription(uuid);
|
|
@@ -400,11 +367,7 @@ export default class ElectronBleTransport {
|
|
|
400
367
|
this.v1Buffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
401
368
|
this.v2Assemblers.set(uuid, new ProtocolV2FrameAssembler(PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
402
369
|
|
|
403
|
-
|
|
404
|
-
await window.desktopApi.nobleBle.subscribe(uuid);
|
|
405
|
-
} catch (error) {
|
|
406
|
-
this.handleBluetoothError(error, shouldMapProtocolV2StaleBond);
|
|
407
|
-
}
|
|
370
|
+
await window.desktopApi.nobleBle.subscribe(uuid);
|
|
408
371
|
await this.refreshBlePacketCapacity(uuid);
|
|
409
372
|
|
|
410
373
|
const cleanup = this.createNotificationSubscription(uuid);
|
|
@@ -524,20 +487,13 @@ export default class ElectronBleTransport {
|
|
|
524
487
|
expectedProtocol?: ProtocolType,
|
|
525
488
|
protocolHint?: ProtocolType
|
|
526
489
|
): Promise<ProtocolType> {
|
|
527
|
-
// A declared V1 is taken at face value, as the React Native transport
|
|
528
|
-
// already does on iOS: the caller reads the protocol off its own device
|
|
529
|
-
// record, so probing re-asks a question that is already answered and adds a
|
|
530
|
-
// round trip to every cold connect. It also fails in a way that costs the
|
|
531
|
-
// session: a device whose protocol session has stalled ignores the probe
|
|
532
|
-
// frame, and the timeout became a protocol-mismatch error that stopped Core
|
|
533
|
-
// from ever sending Initialize — the one frame such a device still answers,
|
|
534
|
-
// and how it gets revived. A declared V2 keeps probing, matching iOS, so a
|
|
535
|
-
// USB-priority "link disabled" surfaces here rather than as an unmapped
|
|
536
|
-
// error later. An undeclared protocol still goes through full detection.
|
|
537
490
|
if (expectedProtocol === 'V1') {
|
|
538
|
-
this.
|
|
539
|
-
|
|
540
|
-
|
|
491
|
+
if (await this.probeProtocolV1(uuid)) {
|
|
492
|
+
this.deviceProtocol.set(uuid, 'V1');
|
|
493
|
+
this.Log?.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V1 (expected)`);
|
|
494
|
+
return 'V1';
|
|
495
|
+
}
|
|
496
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
541
497
|
}
|
|
542
498
|
|
|
543
499
|
if (expectedProtocol === 'V2') {
|
|
@@ -632,9 +588,6 @@ export default class ElectronBleTransport {
|
|
|
632
588
|
} catch (error) {
|
|
633
589
|
this.clearProbeProtocol(uuid, 'V1');
|
|
634
590
|
this.Log?.debug('[Electron BLE] Protocol V1 GetFeatures probe failed:', error);
|
|
635
|
-
if (isProtocolV2LinkDisabledError(error)) {
|
|
636
|
-
throw error;
|
|
637
|
-
}
|
|
638
591
|
return false;
|
|
639
592
|
}
|
|
640
593
|
}
|
|
@@ -655,8 +608,6 @@ export default class ElectronBleTransport {
|
|
|
655
608
|
this.v2Assemblers.get(uuid)?.reset();
|
|
656
609
|
this.resetProtocolV2Frames(uuid);
|
|
657
610
|
},
|
|
658
|
-
shouldRethrow: error =>
|
|
659
|
-
isBleStaleBondHardwareError(error) || isProtocolV2LinkDisabledError(error),
|
|
660
611
|
});
|
|
661
612
|
if (!detected) {
|
|
662
613
|
this.clearProbeProtocol(uuid, 'V2');
|
|
@@ -670,15 +621,7 @@ export default class ElectronBleTransport {
|
|
|
670
621
|
throw new Error('Noble BLE API not available');
|
|
671
622
|
}
|
|
672
623
|
|
|
673
|
-
|
|
674
|
-
await nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
|
|
675
|
-
} catch (error) {
|
|
676
|
-
const staleBondError = this.toStaleBondError(error);
|
|
677
|
-
if (staleBondError) {
|
|
678
|
-
throw staleBondError;
|
|
679
|
-
}
|
|
680
|
-
throw error;
|
|
681
|
-
}
|
|
624
|
+
await nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
|
|
682
625
|
}
|
|
683
626
|
|
|
684
627
|
private async refreshBlePacketCapacity(uuid: string): Promise<void> {
|
|
@@ -752,29 +695,9 @@ export default class ElectronBleTransport {
|
|
|
752
695
|
this.handleProtocolV2Notification(deviceId, hexData);
|
|
753
696
|
return;
|
|
754
697
|
}
|
|
755
|
-
const linkDisabledError = this.readProtocolV2LinkDisabledFailure(deviceId, hexData);
|
|
756
|
-
if (linkDisabledError) {
|
|
757
|
-
if (this.runPromise && this.runPromiseDeviceId === deviceId) {
|
|
758
|
-
this.runPromise.reject(linkDisabledError);
|
|
759
|
-
}
|
|
760
|
-
return;
|
|
761
|
-
}
|
|
762
698
|
this.handleProtocolV1Notification(deviceId, hexData);
|
|
763
699
|
}
|
|
764
700
|
|
|
765
|
-
private readProtocolV2LinkDisabledFailure(deviceId: string, hexData: string) {
|
|
766
|
-
if (!this._messages || !this._messagesV2) return undefined;
|
|
767
|
-
|
|
768
|
-
const assembler = this.v2Assemblers.get(deviceId);
|
|
769
|
-
if (!assembler) return undefined;
|
|
770
|
-
|
|
771
|
-
return detectProtocolV2LinkDisabledError({
|
|
772
|
-
schemas: { protocolV1: this._messages, protocolV2: this._messagesV2 },
|
|
773
|
-
assembler,
|
|
774
|
-
bytes: hexToBytes(hexData),
|
|
775
|
-
});
|
|
776
|
-
}
|
|
777
|
-
|
|
778
701
|
private handleProtocolV2Notification(deviceId: string, hexData: string): void {
|
|
779
702
|
try {
|
|
780
703
|
const bytes = hexToBytes(hexData);
|
package/src/webusb.ts
CHANGED
|
@@ -107,9 +107,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
107
107
|
/** Per-path protocol type detected by active wire-level probe. */
|
|
108
108
|
private deviceProtocol: Map<string, ProtocolType> = new Map();
|
|
109
109
|
|
|
110
|
-
/** Protocols previously confirmed by an active response for this transport instance. */
|
|
111
|
-
private confirmedDeviceProtocols: Map<string, ProtocolType> = new Map();
|
|
112
|
-
|
|
113
110
|
private deviceProtocolHints: Map<string, ProtocolType> = new Map();
|
|
114
111
|
|
|
115
112
|
/**
|
|
@@ -312,26 +309,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
312
309
|
await this.rotateProtocolV2UsbGeneration(input.path, 'WebUSB transport acquired');
|
|
313
310
|
await this.closeOpenDevice(input.path);
|
|
314
311
|
await this.connect(input.path ?? '', true);
|
|
315
|
-
if (input.
|
|
316
|
-
if (!input.expectedProtocol) {
|
|
317
|
-
throw ERRORS.TypedError(
|
|
318
|
-
HardwareErrorCode.RuntimeError,
|
|
319
|
-
'skipProtocolProbe requires an expected protocol'
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
if (this.confirmedDeviceProtocols.get(input.path) !== input.expectedProtocol) {
|
|
323
|
-
throw ERRORS.TypedError(
|
|
324
|
-
HardwareErrorCode.RuntimeError,
|
|
325
|
-
'skipProtocolProbe requires a previously confirmed protocol for this WebUSB endpoint'
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
this.staleProtocolPaths.delete(input.path);
|
|
329
|
-
this.deviceProtocol.set(input.path, input.expectedProtocol);
|
|
330
|
-
const currentDevice = this.deviceList.find(d => d.path === input.path)?.device;
|
|
331
|
-
if (currentDevice) {
|
|
332
|
-
this.probedDeviceObjects.set(input.path, currentDevice);
|
|
333
|
-
}
|
|
334
|
-
} else if (input.forceProtocolDetection) {
|
|
312
|
+
if (input.forceProtocolDetection) {
|
|
335
313
|
// Explicit recovery/discovery (e.g. detectDeviceConnectProtocol) must
|
|
336
314
|
// probe on the wire regardless of any cached result — the cached
|
|
337
315
|
// binding may be exactly what the caller is trying to recover from.
|
|
@@ -339,13 +317,13 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
339
317
|
this.deviceProtocol.delete(input.path);
|
|
340
318
|
this.deviceProtocolHints.delete(input.path);
|
|
341
319
|
}
|
|
342
|
-
if (
|
|
320
|
+
if (this.staleProtocolPaths.has(input.path)) {
|
|
343
321
|
// The device disconnected (possibly rebooting into another mode) since
|
|
344
322
|
// the protocol was probed — drop the cache so it is re-probed below.
|
|
345
323
|
this.staleProtocolPaths.delete(input.path);
|
|
346
324
|
this.deviceProtocol.delete(input.path);
|
|
347
325
|
}
|
|
348
|
-
if (
|
|
326
|
+
if (this.deviceProtocol.has(input.path)) {
|
|
349
327
|
const currentDevice = this.deviceList.find(d => d.path === input.path)?.device;
|
|
350
328
|
if (!currentDevice || currentDevice !== this.probedDeviceObjects.get(input.path)) {
|
|
351
329
|
// The OS re-enumerated the device since the probe (a replug/reboot we
|
|
@@ -355,12 +333,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
355
333
|
}
|
|
356
334
|
}
|
|
357
335
|
const cachedProtocol = this.deviceProtocol.get(input.path);
|
|
358
|
-
if (
|
|
359
|
-
!input.skipProtocolProbe &&
|
|
360
|
-
cachedProtocol &&
|
|
361
|
-
input.expectedProtocol &&
|
|
362
|
-
cachedProtocol !== input.expectedProtocol
|
|
363
|
-
) {
|
|
336
|
+
if (cachedProtocol && input.expectedProtocol && cachedProtocol !== input.expectedProtocol) {
|
|
364
337
|
// The caller expects a different protocol than the cached probe result;
|
|
365
338
|
// the cache is stale — drop it and re-probe on the wire below.
|
|
366
339
|
this.deviceProtocol.delete(input.path);
|
|
@@ -375,12 +348,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
375
348
|
if (protocolHint) {
|
|
376
349
|
this.deviceProtocolHints.set(input.path, protocolHint);
|
|
377
350
|
}
|
|
378
|
-
|
|
379
|
-
input.path,
|
|
380
|
-
input.expectedProtocol,
|
|
381
|
-
protocolHint
|
|
382
|
-
);
|
|
383
|
-
this.confirmedDeviceProtocols.set(input.path, detectedProtocol);
|
|
351
|
+
await this.detectProtocol(input.path, input.expectedProtocol, protocolHint);
|
|
384
352
|
const probedDevice = this.deviceList.find(d => d.path === input.path)?.device;
|
|
385
353
|
if (probedDevice) {
|
|
386
354
|
this.probedDeviceObjects.set(input.path, probedDevice);
|