@onekeyfe/hd-core 1.1.21-alpha.1 → 1.1.21-alpha.2
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/dist/api/FirmwareUpdateV3.d.ts +1 -0
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +1 -3
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/index.js +46 -20
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV3.ts +65 -3
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +3 -28
|
@@ -16,6 +16,7 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
16
16
|
private prepareFirmwareAndBleBinary;
|
|
17
17
|
private executeUpdate;
|
|
18
18
|
private extractUpdateModeProgress;
|
|
19
|
+
private isGetFeaturesTimeoutError;
|
|
19
20
|
private normalizeErrorMessage;
|
|
20
21
|
waitForDeviceReconnect(timeout: number): Promise<void>;
|
|
21
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateV3.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV3.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateV3.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV3.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAI/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,qBAAqB,CAAC;AAKnE,eAAO,MAAM,gCAAgC,UAAU,CAAC;AAcxD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE1C,IAAI;IAmCE,GAAG;;;;;IA8CT,OAAO,CAAC,wBAAwB;YAiBlB,qBAAqB;YAoBrB,uBAAuB;YAiBvB,2BAA2B;YAiD3B,aAAa;IA2M3B,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,qBAAqB;IAuBvB,sBAAsB,CAAC,OAAO,EAAE,MAAM;CA0E7C"}
|
|
@@ -7,16 +7,14 @@ import type { Deferred } from '@onekeyfe/hd-shared';
|
|
|
7
7
|
import type { TypedResponseMessage } from '../../device/DeviceCommands';
|
|
8
8
|
export declare class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
9
9
|
checkPromise: Deferred<any> | null;
|
|
10
|
-
protected hasPromptedWebUsbBootloaderReauth: boolean;
|
|
11
10
|
init(): void;
|
|
12
11
|
run(): Promise<any>;
|
|
13
12
|
isBleReconnect(): boolean;
|
|
14
13
|
postTipMessage: (message: IFirmwareUpdateTipMessage) => void;
|
|
15
14
|
postProcessingMessage: (type: 'firmware' | 'ble' | 'bootloader' | 'resource') => void;
|
|
16
15
|
postProgressMessage: (progress: number, progressType: IFirmwareUpdateProgressType) => void;
|
|
17
|
-
|
|
16
|
+
protected _promptDeviceInBootloaderForWebDevice(): Promise<unknown>;
|
|
18
17
|
checkDeviceToBootloader(connectId: string | undefined): void;
|
|
19
|
-
protected ensureWebUsbBootloaderReauthPrompt(): Promise<void>;
|
|
20
18
|
private _checkDeviceInBootloaderMode;
|
|
21
19
|
enterBootloaderMode(): Promise<true | undefined>;
|
|
22
20
|
startEmmcFirmwareUpdate({ path }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateBaseMethod.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareUpdateBaseMethod.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAexE,qBAAa,wBAAwB,CAAC,MAAM,CAAE,SAAQ,UAAU,CAAC,MAAM,CAAC;IACtE,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE1C,
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateBaseMethod.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareUpdateBaseMethod.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAexE,qBAAa,wBAAwB,CAAC,MAAM,CAAE,SAAQ,UAAU,CAAC,MAAM,CAAC;IACtE,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE1C,IAAI,IAAI,IAAI;IAEZ,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAInB,cAAc,IAAI,OAAO;IASzB,cAAc,YAAa,yBAAyB,UASlD;IAMF,qBAAqB,SAAU,UAAU,GAAG,KAAK,GAAG,YAAY,GAAG,UAAU,UAM3E;IAMF,mBAAmB,aAAc,MAAM,gBAAgB,2BAA2B,UAQhF;cAEc,qCAAqC;IAkBrD,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;YAmFvC,4BAA4B;IAuBpC,mBAAmB;IA8CnB,uBAAuB,CAAC,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IA6BlD,8BAA8B,CAAC,IAAI,EAAE,MAAM;IAW3C,uBAAuB,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,aAAa,EACb,SAAS,GACV,EAAE,KAAK,CAAC,cAAc,GAAG;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IA4CK,sBAAsB,CAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,GAAG,MAAM,EAC3B,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI;IAwEnB,MAAM,CAAC,UAAU,EAAE,UAAU;CAsBpC"}
|
package/dist/index.js
CHANGED
|
@@ -29369,7 +29369,6 @@ class FirmwareUpdateBaseMethod extends BaseMethod {
|
|
|
29369
29369
|
constructor() {
|
|
29370
29370
|
super(...arguments);
|
|
29371
29371
|
this.checkPromise = null;
|
|
29372
|
-
this.hasPromptedWebUsbBootloaderReauth = false;
|
|
29373
29372
|
this.postTipMessage = (message) => {
|
|
29374
29373
|
this.postMessage(createUiMessage(UI_REQUEST.FIRMWARE_TIP, {
|
|
29375
29374
|
device: this.device.toMessageObject(),
|
|
@@ -29477,23 +29476,6 @@ class FirmwareUpdateBaseMethod extends BaseMethod {
|
|
|
29477
29476
|
}
|
|
29478
29477
|
}, 30000);
|
|
29479
29478
|
}
|
|
29480
|
-
ensureWebUsbBootloaderReauthPrompt() {
|
|
29481
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
29482
|
-
if (this.hasPromptedWebUsbBootloaderReauth ||
|
|
29483
|
-
!DataManager.isBrowserWebUsb(DataManager.getSettings('env')) ||
|
|
29484
|
-
this.device.listenerCount(DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE) === 0) {
|
|
29485
|
-
return;
|
|
29486
|
-
}
|
|
29487
|
-
this.hasPromptedWebUsbBootloaderReauth = true;
|
|
29488
|
-
this.postTipMessage(exports.FirmwareUpdateTipMessage.SelectDeviceInBootloaderForWebDevice);
|
|
29489
|
-
try {
|
|
29490
|
-
yield this._promptDeviceInBootloaderForWebDevice();
|
|
29491
|
-
}
|
|
29492
|
-
catch (error) {
|
|
29493
|
-
Log$7.log('WebUSB 设备重新授权失败: ', error);
|
|
29494
|
-
}
|
|
29495
|
-
});
|
|
29496
|
-
}
|
|
29497
29479
|
_checkDeviceInBootloaderMode(connectId, intervalTimer, timeoutTimer) {
|
|
29498
29480
|
var _a, _b, _c, _d, _e;
|
|
29499
29481
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -30504,18 +30486,22 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
30504
30486
|
this.postProgressMessage(0, 'installingFirmware');
|
|
30505
30487
|
const installStartTime = Date.now();
|
|
30506
30488
|
const maxWaitTimeForInstallingFirmware = 5 * 60 * 1000;
|
|
30489
|
+
let getFeaturesTimeoutCount = 0;
|
|
30490
|
+
const maxGetFeaturesTimeoutBeforeReauth = 3;
|
|
30507
30491
|
while (true) {
|
|
30508
30492
|
if (Date.now() - installStartTime > maxWaitTimeForInstallingFirmware) {
|
|
30509
30493
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware update process timeout after 5 minutes');
|
|
30510
30494
|
}
|
|
30511
30495
|
try {
|
|
30512
30496
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
30497
|
+
const timeoutMs = 3000;
|
|
30513
30498
|
const featuresRes = yield Promise.race([
|
|
30514
30499
|
typedCall('GetFeatures', 'Features', {}),
|
|
30515
30500
|
new Promise((_, reject) => {
|
|
30516
|
-
setTimeout(() => reject(
|
|
30501
|
+
setTimeout(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodNotResponse, 'GetFeatures timeout', { method: 'GetFeatures', timeoutMs })), timeoutMs);
|
|
30517
30502
|
}),
|
|
30518
30503
|
]);
|
|
30504
|
+
getFeaturesTimeoutCount = 0;
|
|
30519
30505
|
const features = featuresRes.message;
|
|
30520
30506
|
const bootloaderVersion = getDeviceBootloaderVersion(features).join('.');
|
|
30521
30507
|
const bleVersion = getDeviceBLEFirmwareVersion(features).join('.');
|
|
@@ -30532,17 +30518,31 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
30532
30518
|
yield hdShared.wait(1000);
|
|
30533
30519
|
}
|
|
30534
30520
|
catch (error) {
|
|
30521
|
+
Log$4.log('getFeatures error', error);
|
|
30522
|
+
let shouldReconnect = true;
|
|
30535
30523
|
const progress = this.extractUpdateModeProgress(error);
|
|
30536
30524
|
if (progress !== null) {
|
|
30525
|
+
getFeaturesTimeoutCount = 0;
|
|
30537
30526
|
this.postProgressMessage(progress, 'installingFirmware');
|
|
30538
30527
|
yield hdShared.wait(1000);
|
|
30528
|
+
shouldReconnect = false;
|
|
30529
|
+
}
|
|
30530
|
+
else if (this.isGetFeaturesTimeoutError(error)) {
|
|
30531
|
+
getFeaturesTimeoutCount += 1;
|
|
30532
|
+
if (getFeaturesTimeoutCount <= maxGetFeaturesTimeoutBeforeReauth) {
|
|
30533
|
+
yield hdShared.wait(1000);
|
|
30534
|
+
shouldReconnect = false;
|
|
30535
|
+
}
|
|
30539
30536
|
}
|
|
30540
30537
|
else {
|
|
30538
|
+
getFeaturesTimeoutCount = 0;
|
|
30539
|
+
}
|
|
30540
|
+
if (shouldReconnect) {
|
|
30541
30541
|
yield hdShared.wait(1000);
|
|
30542
30542
|
const reconnectTimeout = this.isBleReconnect() && (this.params.bleBinary || this.params.bleVersion)
|
|
30543
30543
|
? 3 * 60 * 1000
|
|
30544
30544
|
: 60 * 1000;
|
|
30545
|
-
|
|
30545
|
+
getFeaturesTimeoutCount = 0;
|
|
30546
30546
|
yield this.waitForDeviceReconnect(reconnectTimeout);
|
|
30547
30547
|
}
|
|
30548
30548
|
}
|
|
@@ -30561,6 +30561,12 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
30561
30561
|
const progress = parseInt(match[1], 10);
|
|
30562
30562
|
return Number.isNaN(progress) ? null : progress;
|
|
30563
30563
|
}
|
|
30564
|
+
isGetFeaturesTimeoutError(error) {
|
|
30565
|
+
var _a;
|
|
30566
|
+
return (error instanceof hdShared.HardwareError &&
|
|
30567
|
+
error.errorCode === hdShared.HardwareErrorCode.CallMethodNotResponse &&
|
|
30568
|
+
((_a = error.params) === null || _a === void 0 ? void 0 : _a.method) === 'GetFeatures');
|
|
30569
|
+
}
|
|
30564
30570
|
normalizeErrorMessage(error) {
|
|
30565
30571
|
if (!error) {
|
|
30566
30572
|
return '';
|
|
@@ -30584,6 +30590,7 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
30584
30590
|
return __awaiter(this, void 0, void 0, function* () {
|
|
30585
30591
|
const startTime = Date.now();
|
|
30586
30592
|
const isBleReconnect = this.isBleReconnect();
|
|
30593
|
+
let webUsbCheckCount = 0;
|
|
30587
30594
|
while (Date.now() - startTime < timeout) {
|
|
30588
30595
|
try {
|
|
30589
30596
|
if (isBleReconnect) {
|
|
@@ -30607,6 +30614,25 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
30607
30614
|
else {
|
|
30608
30615
|
const deviceDiff = yield ((_b = this.device.deviceConnector) === null || _b === void 0 ? void 0 : _b.enumerate());
|
|
30609
30616
|
const devicesDescriptor = (_c = deviceDiff === null || deviceDiff === void 0 ? void 0 : deviceDiff.descriptors) !== null && _c !== void 0 ? _c : [];
|
|
30617
|
+
const canPromptWebUsbBootloader = DataManager.isBrowserWebUsb(DataManager.getSettings('env')) &&
|
|
30618
|
+
!this.payload.skipWebDevicePrompt &&
|
|
30619
|
+
this.device.listenerCount(DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE) > 0;
|
|
30620
|
+
if (canPromptWebUsbBootloader) {
|
|
30621
|
+
webUsbCheckCount += 1;
|
|
30622
|
+
if (webUsbCheckCount > 4) {
|
|
30623
|
+
this.postTipMessage(exports.FirmwareUpdateTipMessage.SelectDeviceInBootloaderForWebDevice);
|
|
30624
|
+
try {
|
|
30625
|
+
yield this._promptDeviceInBootloaderForWebDevice();
|
|
30626
|
+
}
|
|
30627
|
+
catch (e) {
|
|
30628
|
+
Log$4.log('WebUSB re-authorization failed: ', e);
|
|
30629
|
+
}
|
|
30630
|
+
webUsbCheckCount = 0;
|
|
30631
|
+
}
|
|
30632
|
+
}
|
|
30633
|
+
else {
|
|
30634
|
+
webUsbCheckCount = 0;
|
|
30635
|
+
}
|
|
30610
30636
|
const { deviceList } = yield DevicePool.getDevices(devicesDescriptor, this.connectId);
|
|
30611
30637
|
if (deviceList.length === 1) {
|
|
30612
30638
|
this.device.updateFromCache(deviceList[0]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.1.21-alpha.
|
|
3
|
+
"version": "1.1.21-alpha.2",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.1.21-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.1.21-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.1.21-alpha.2",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.1.21-alpha.2",
|
|
30
30
|
"axios": "1.12.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"bytebuffer": "^5.0.1",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@types/w3c-web-usb": "^1.0.10",
|
|
45
45
|
"@types/web-bluetooth": "^0.0.21"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "ed487b957d52b83b8fb5766578fe6b65f478100a"
|
|
48
48
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EDeviceType, ERRORS, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
|
|
1
|
+
import { EDeviceType, ERRORS, HardwareError, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
|
|
2
2
|
import semver from 'semver';
|
|
3
3
|
import JSZip from 'jszip';
|
|
4
4
|
|
|
@@ -17,6 +17,7 @@ import { getBinary, getSysResourceBinary } from './firmware/getBinary';
|
|
|
17
17
|
import { DataManager } from '../data-manager';
|
|
18
18
|
import { FirmwareUpdateBaseMethod } from './firmware/FirmwareUpdateBaseMethod';
|
|
19
19
|
import { DevicePool } from '../device/DevicePool';
|
|
20
|
+
import { DEVICE } from '../events';
|
|
20
21
|
|
|
21
22
|
import type { FirmwareUpdateV3Params } from '../types/api/firmwareUpdate';
|
|
22
23
|
import type { Deferred, EFirmwareType } from '@onekeyfe/hd-shared';
|
|
@@ -26,6 +27,7 @@ const Log = getLogger(LoggerNames.Method);
|
|
|
26
27
|
|
|
27
28
|
export const MIN_UPDATE_V3_BOOTLOADER_VERSION = '2.8.0';
|
|
28
29
|
|
|
30
|
+
|
|
29
31
|
/**
|
|
30
32
|
* FirmwareUpdateV3 flow
|
|
31
33
|
1. StartDownloadFirmware
|
|
@@ -336,6 +338,9 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
336
338
|
const installStartTime = Date.now();
|
|
337
339
|
const maxWaitTimeForInstallingFirmware = 5 * 60 * 1000; // 5 minutes in milliseconds
|
|
338
340
|
|
|
341
|
+
let getFeaturesTimeoutCount = 0;
|
|
342
|
+
const maxGetFeaturesTimeoutBeforeReauth = 3;
|
|
343
|
+
|
|
339
344
|
// eslint-disable-next-line no-constant-condition
|
|
340
345
|
while (true) {
|
|
341
346
|
// Check if timeout exceeded
|
|
@@ -348,12 +353,24 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
348
353
|
|
|
349
354
|
try {
|
|
350
355
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
356
|
+
const timeoutMs = 3000;
|
|
351
357
|
const featuresRes = await Promise.race<TypedResponseMessage<'Features'>>([
|
|
352
358
|
typedCall('GetFeatures', 'Features', {}),
|
|
353
359
|
new Promise<never>((_, reject) => {
|
|
354
|
-
setTimeout(
|
|
360
|
+
setTimeout(
|
|
361
|
+
() =>
|
|
362
|
+
reject(
|
|
363
|
+
ERRORS.TypedError(
|
|
364
|
+
HardwareErrorCode.CallMethodNotResponse,
|
|
365
|
+
'GetFeatures timeout',
|
|
366
|
+
{ method: 'GetFeatures', timeoutMs }
|
|
367
|
+
)
|
|
368
|
+
),
|
|
369
|
+
timeoutMs
|
|
370
|
+
);
|
|
355
371
|
}),
|
|
356
372
|
]);
|
|
373
|
+
getFeaturesTimeoutCount = 0;
|
|
357
374
|
const features = featuresRes.message;
|
|
358
375
|
const bootloaderVersion = getDeviceBootloaderVersion(features).join('.');
|
|
359
376
|
const bleVersion = getDeviceBLEFirmwareVersion(features).join('.');
|
|
@@ -371,11 +388,26 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
371
388
|
// Still in update mode; continue polling (e.g., iOS may return firmwareVersion 0.0.0 during switches)
|
|
372
389
|
await wait(1000);
|
|
373
390
|
} catch (error) {
|
|
391
|
+
Log.log('getFeatures error', error);
|
|
392
|
+
let shouldReconnect = true;
|
|
374
393
|
const progress = this.extractUpdateModeProgress(error);
|
|
375
394
|
if (progress !== null) {
|
|
395
|
+
getFeaturesTimeoutCount = 0;
|
|
376
396
|
this.postProgressMessage(progress, 'installingFirmware');
|
|
377
397
|
await wait(1000);
|
|
398
|
+
shouldReconnect = false;
|
|
399
|
+
} else if (this.isGetFeaturesTimeoutError(error)) {
|
|
400
|
+
getFeaturesTimeoutCount += 1;
|
|
401
|
+
// Retry transient GetFeatures timeouts to avoid unnecessary WebUSB re-authorization prompts.
|
|
402
|
+
if (getFeaturesTimeoutCount <= maxGetFeaturesTimeoutBeforeReauth) {
|
|
403
|
+
await wait(1000);
|
|
404
|
+
shouldReconnect = false;
|
|
405
|
+
}
|
|
378
406
|
} else {
|
|
407
|
+
getFeaturesTimeoutCount = 0;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (shouldReconnect) {
|
|
379
411
|
await wait(1000);
|
|
380
412
|
/**
|
|
381
413
|
* Needs second reconnect case:
|
|
@@ -387,7 +419,7 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
387
419
|
? 3 * 60 * 1000 // 3 minutes for BLE reconnect
|
|
388
420
|
: 60 * 1000; // 1 minute for normal reconnect
|
|
389
421
|
|
|
390
|
-
|
|
422
|
+
getFeaturesTimeoutCount = 0;
|
|
391
423
|
await this.waitForDeviceReconnect(reconnectTimeout);
|
|
392
424
|
}
|
|
393
425
|
}
|
|
@@ -410,6 +442,14 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
410
442
|
return Number.isNaN(progress) ? null : progress;
|
|
411
443
|
}
|
|
412
444
|
|
|
445
|
+
private isGetFeaturesTimeoutError(error: unknown): boolean {
|
|
446
|
+
return (
|
|
447
|
+
error instanceof HardwareError &&
|
|
448
|
+
error.errorCode === HardwareErrorCode.CallMethodNotResponse &&
|
|
449
|
+
error.params?.method === 'GetFeatures'
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
|
|
413
453
|
private normalizeErrorMessage(error: unknown): string {
|
|
414
454
|
if (!error) {
|
|
415
455
|
return '';
|
|
@@ -436,6 +476,7 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
436
476
|
async waitForDeviceReconnect(timeout: number) {
|
|
437
477
|
const startTime = Date.now();
|
|
438
478
|
const isBleReconnect = this.isBleReconnect();
|
|
479
|
+
let webUsbCheckCount = 0;
|
|
439
480
|
while (Date.now() - startTime < timeout) {
|
|
440
481
|
try {
|
|
441
482
|
if (isBleReconnect) {
|
|
@@ -462,6 +503,27 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
462
503
|
} else {
|
|
463
504
|
const deviceDiff = await this.device.deviceConnector?.enumerate();
|
|
464
505
|
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
506
|
+
|
|
507
|
+
const canPromptWebUsbBootloader =
|
|
508
|
+
DataManager.isBrowserWebUsb(DataManager.getSettings('env')) &&
|
|
509
|
+
!this.payload.skipWebDevicePrompt &&
|
|
510
|
+
this.device.listenerCount(DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE) > 0;
|
|
511
|
+
|
|
512
|
+
if (canPromptWebUsbBootloader) {
|
|
513
|
+
webUsbCheckCount += 1;
|
|
514
|
+
if (webUsbCheckCount > 4) {
|
|
515
|
+
this.postTipMessage(FirmwareUpdateTipMessage.SelectDeviceInBootloaderForWebDevice);
|
|
516
|
+
try {
|
|
517
|
+
await this._promptDeviceInBootloaderForWebDevice();
|
|
518
|
+
} catch (e) {
|
|
519
|
+
Log.log('WebUSB re-authorization failed: ', e);
|
|
520
|
+
}
|
|
521
|
+
webUsbCheckCount = 0;
|
|
522
|
+
}
|
|
523
|
+
} else {
|
|
524
|
+
webUsbCheckCount = 0;
|
|
525
|
+
}
|
|
526
|
+
|
|
465
527
|
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, this.connectId);
|
|
466
528
|
|
|
467
529
|
if (deviceList.length === 1) {
|
|
@@ -40,8 +40,6 @@ const isDeviceDisconnectedError = (error: unknown) => {
|
|
|
40
40
|
export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
41
41
|
checkPromise: Deferred<any> | null = null;
|
|
42
42
|
|
|
43
|
-
protected hasPromptedWebUsbBootloaderReauth = false;
|
|
44
|
-
|
|
45
43
|
init(): void {}
|
|
46
44
|
|
|
47
45
|
run(): Promise<any> {
|
|
@@ -94,7 +92,7 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
94
92
|
);
|
|
95
93
|
};
|
|
96
94
|
|
|
97
|
-
|
|
95
|
+
protected async _promptDeviceInBootloaderForWebDevice() {
|
|
98
96
|
return new Promise((resolve, reject) => {
|
|
99
97
|
if (this.device.listenerCount(DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE) > 0) {
|
|
100
98
|
this.device.emit(
|
|
@@ -195,29 +193,6 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
195
193
|
}, 30000);
|
|
196
194
|
}
|
|
197
195
|
|
|
198
|
-
/**
|
|
199
|
-
* 仅在 firmware 被抹掉、需要重新授权的 bootloader 场景下才提示 WebUSB
|
|
200
|
-
* (比如 BTC-only 与通用固件互转后算作新设备)。
|
|
201
|
-
*/
|
|
202
|
-
protected async ensureWebUsbBootloaderReauthPrompt() {
|
|
203
|
-
if (
|
|
204
|
-
this.hasPromptedWebUsbBootloaderReauth ||
|
|
205
|
-
!DataManager.isBrowserWebUsb(DataManager.getSettings('env')) ||
|
|
206
|
-
this.device.listenerCount(DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE) === 0
|
|
207
|
-
) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
this.hasPromptedWebUsbBootloaderReauth = true;
|
|
212
|
-
this.postTipMessage(FirmwareUpdateTipMessage.SelectDeviceInBootloaderForWebDevice);
|
|
213
|
-
|
|
214
|
-
try {
|
|
215
|
-
await this._promptDeviceInBootloaderForWebDevice();
|
|
216
|
-
} catch (error) {
|
|
217
|
-
Log.log('WebUSB 设备重新授权失败: ', error);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
196
|
private async _checkDeviceInBootloaderMode(
|
|
222
197
|
connectId: string | undefined,
|
|
223
198
|
intervalTimer?: ReturnType<typeof setInterval>,
|
|
@@ -455,8 +430,8 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
455
430
|
}
|
|
456
431
|
|
|
457
432
|
/**
|
|
458
|
-
* @description
|
|
459
|
-
* @param rebootType
|
|
433
|
+
* @description Device reboot (available in bootloader mode)
|
|
434
|
+
* @param rebootType Reboot type, see the RebootType enum
|
|
460
435
|
*/
|
|
461
436
|
async reboot(rebootType: RebootType) {
|
|
462
437
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|