@onekeyfe/hd-core 1.2.0-alpha.50 → 1.2.0-alpha.52
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__/AllNetworkGetAddressBase.tracing.test.ts +0 -78
- package/__tests__/DeviceEventRegistration.test.ts +0 -6
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +3 -111
- package/__tests__/connectSettings.test.ts +47 -5
- package/__tests__/device-initialize-timeout.test.ts +56 -0
- package/__tests__/device-lifecycle-events.test.ts +3 -105
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
- package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
- package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +200 -0
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +294 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +593 -0
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +213 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +59 -31
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +58 -0
- package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
- package/__tests__/get-device-state.test.ts +12 -132
- package/__tests__/homescreen.test.ts +1 -41
- package/__tests__/logBlockEvent.test.ts +1 -1
- package/__tests__/method-protocol-support.test.ts +0 -19
- package/__tests__/open-wallet-session.test.ts +33 -446
- package/__tests__/protocol-v2-unlock-policy.test.ts +35 -196
- package/__tests__/protocol-v2.test.ts +1032 -1056
- package/__tests__/protocolV2UiInteraction.test.ts +0 -63
- package/__tests__/public-pro2-api-boundary.test.ts +0 -1
- package/__tests__/search-devices.test.ts +3 -12
- package/dist/api/BaseMethod.d.ts +1 -3
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +11 -0
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +7 -3
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +25 -9
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts +5 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
- package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
- package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +9 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +25 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +32 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/api/firmware/getBinary.d.ts +7 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/progressThrottle.d.ts +3 -0
- package/dist/api/firmware/progressThrottle.d.ts.map +1 -0
- package/dist/api/firmware/updateBootloader.d.ts +2 -0
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +9 -1
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +0 -2
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +0 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/core/deviceEventRegistration.d.ts +0 -2
- package/dist/core/deviceEventRegistration.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +2 -4
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +6 -29
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/events/device.d.ts +0 -4
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-promise.d.ts +2 -4
- package/dist/events/ui-promise.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +2 -31
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/events/ui-response.d.ts +2 -10
- package/dist/events/ui-response.d.ts.map +1 -1
- package/dist/index.d.ts +230 -203
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3469 -2419
- package/dist/inject.d.ts +1 -6
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/lockedError.d.ts +2 -0
- package/dist/protocols/protocol-v2/lockedError.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts +4 -7
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +3 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +10 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +1 -4
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +4 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +4 -1
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +70 -2
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +10 -7
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +0 -3
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/params.d.ts +0 -1
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +13 -22
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +1 -0
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +0 -2
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts +0 -4
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/dist/utils/pro2Wallpaper.d.ts +0 -10
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +10 -8
- package/src/api/CheckAllFirmwareRelease.ts +53 -41
- package/src/api/FirmwareUpdate.ts +15 -7
- package/src/api/FirmwareUpdateV2.ts +316 -126
- package/src/api/FirmwareUpdateV3.ts +265 -63
- package/src/api/FirmwareUpdateV4.ts +937 -430
- package/src/api/GetPassphraseState.ts +1 -7
- package/src/api/OpenWalletSession.ts +17 -54
- package/src/api/SearchDevices.ts +1 -3
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +11 -32
- package/src/api/device/DeviceUnlock.ts +1 -1
- package/src/api/device/DeviceUpdateBootloader.ts +122 -6
- package/src/api/firmware/FirmwareArtifactSource.ts +278 -0
- package/src/api/firmware/FirmwareHostBinding.ts +100 -0
- package/src/api/firmware/FirmwarePreparationError.ts +12 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +83 -16
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +772 -0
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +415 -0
- package/src/api/firmware/progressThrottle.ts +44 -0
- package/src/api/firmware/updateBootloader.ts +19 -4
- package/src/api/firmware/uploadFirmware.ts +144 -39
- package/src/api/helpers/protocolV2FileWrite.ts +4 -11
- package/src/api/index.ts +0 -2
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +1 -3
- package/src/core/deviceEventRegistration.ts +0 -4
- package/src/core/index.ts +83 -167
- package/src/data/messages/messages-protocol-v2.json +0 -25
- package/src/data-manager/DataManager.ts +38 -67
- package/src/data-manager/connectSettings.ts +11 -0
- package/src/device/Device.ts +42 -257
- package/src/device/DevicePool.ts +2 -7
- package/src/events/device.ts +0 -4
- package/src/events/logBlockEvent.ts +0 -1
- package/src/events/ui-promise.ts +2 -4
- package/src/events/ui-request.ts +2 -36
- package/src/events/ui-response.ts +2 -12
- package/src/index.ts +5 -0
- package/src/inject.ts +24 -60
- package/src/lowLevelInject.ts +8 -7
- package/src/protocols/protocol-v2/features.ts +2 -9
- package/src/protocols/protocol-v2/lockedError.ts +10 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +6 -46
- package/src/protocols/protocol-v2/unlockPolicy.ts +105 -1
- package/src/protocols/protocol-v2/unlockRetry.ts +109 -0
- package/src/protocols/protocol-v2/walletSession.ts +30 -169
- package/src/topLevelInject.ts +8 -7
- package/src/types/api/checkAllFirmwareRelease.ts +4 -1
- package/src/types/api/deviceUpdateBootloader.ts +6 -0
- package/src/types/api/export.ts +18 -0
- package/src/types/api/firmwareUpdate.ts +76 -3
- package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
- package/src/types/api/firmwareUpdatePlan.ts +38 -0
- package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
- package/src/types/api/index.ts +14 -13
- package/src/types/api/protocolV2.ts +0 -13
- package/src/types/params.ts +1 -7
- package/src/types/settings.ts +13 -42
- package/src/utils/deviceFeaturesCompat.ts +6 -0
- package/src/utils/deviceFeaturesUtils.ts +0 -4
- package/src/utils/homescreen.ts +6 -32
- package/src/utils/index.ts +1 -6
- package/src/utils/pro2Wallpaper.ts +8 -35
- package/__tests__/deviceUploadNft.test.ts +0 -293
- package/__tests__/pro2Nft.test.ts +0 -108
- package/__tests__/protocol-binding.test.ts +0 -89
- package/__tests__/protocol-v2-resources.test.ts +0 -284
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +0 -91
- package/__tests__/uiProgressThrottle.test.ts +0 -74
- package/__tests__/uiPromiseRegistry.test.ts +0 -86
- package/dist/api/DetectDeviceConnectProtocol.d.ts +0 -7
- package/dist/api/DetectDeviceConnectProtocol.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +0 -31
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +0 -1
- package/dist/core/uiPromiseRegistry.d.ts +0 -4
- package/dist/core/uiPromiseRegistry.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/resources.d.ts +0 -30
- package/dist/protocols/protocol-v2/resources.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +0 -22
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +0 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +0 -4
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +0 -1
- package/dist/utils/pro2Nft.d.ts +0 -31
- package/dist/utils/pro2Nft.d.ts.map +0 -1
- package/dist/utils/uiProgressThrottle.d.ts +0 -3
- package/dist/utils/uiProgressThrottle.d.ts.map +0 -1
- package/src/api/DetectDeviceConnectProtocol.ts +0 -18
- package/src/api/protocol-v2/DeviceUploadNft.ts +0 -189
- package/src/core/uiPromiseRegistry.ts +0 -41
- package/src/protocols/protocol-v2/resources.ts +0 -359
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +0 -124
- package/src/types/api/detectDeviceConnectProtocol.ts +0 -7
- package/src/utils/pro2Nft.ts +0 -142
- package/src/utils/uiProgressThrottle.ts +0 -63
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import type { FirmwareUpdateHostBinding } from '../../types/api/firmwareUpdate';
|
|
4
|
+
|
|
5
|
+
const bindingError = (message: string): never => {
|
|
6
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, message, {
|
|
7
|
+
firmwareUpdateCode: 'FirmwareArtifactReaderInvalid',
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
class FirmwareHostBindingRegistry {
|
|
12
|
+
private generation = 0;
|
|
13
|
+
|
|
14
|
+
private binding?: FirmwareUpdateHostBinding;
|
|
15
|
+
|
|
16
|
+
register(binding: FirmwareUpdateHostBinding): number {
|
|
17
|
+
if (
|
|
18
|
+
!binding ||
|
|
19
|
+
typeof binding.artifactReader?.open !== 'function' ||
|
|
20
|
+
typeof binding.artifactReader.read !== 'function' ||
|
|
21
|
+
typeof binding.artifactReader.close !== 'function'
|
|
22
|
+
) {
|
|
23
|
+
return bindingError('Firmware host binding is invalid');
|
|
24
|
+
}
|
|
25
|
+
this.generation += 1;
|
|
26
|
+
this.binding = binding;
|
|
27
|
+
return this.generation;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
unregister(generation?: number): boolean {
|
|
31
|
+
if (generation !== undefined && generation !== this.generation) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
this.generation += 1;
|
|
35
|
+
this.binding = undefined;
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getGeneration(): number {
|
|
40
|
+
return this.generation;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
resolve(generation: number): FirmwareUpdateHostBinding {
|
|
44
|
+
if (
|
|
45
|
+
!Number.isSafeInteger(generation) ||
|
|
46
|
+
generation <= 0 ||
|
|
47
|
+
generation !== this.generation ||
|
|
48
|
+
!this.binding
|
|
49
|
+
) {
|
|
50
|
+
return bindingError(`Firmware host binding generation ${generation} is stale`);
|
|
51
|
+
}
|
|
52
|
+
const { binding } = this;
|
|
53
|
+
const assertCurrent = () => {
|
|
54
|
+
if (generation !== this.generation || binding !== this.binding) {
|
|
55
|
+
bindingError(`Firmware host binding generation ${generation} is stale`);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
artifactReader: {
|
|
60
|
+
open: async input => {
|
|
61
|
+
assertCurrent();
|
|
62
|
+
const opened = await binding.artifactReader.open(input);
|
|
63
|
+
try {
|
|
64
|
+
assertCurrent();
|
|
65
|
+
} catch (error) {
|
|
66
|
+
if (opened?.readerId) {
|
|
67
|
+
await binding.artifactReader
|
|
68
|
+
.close({ readerId: opened.readerId })
|
|
69
|
+
.catch(() => undefined);
|
|
70
|
+
}
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
return opened;
|
|
74
|
+
},
|
|
75
|
+
read: async input => {
|
|
76
|
+
assertCurrent();
|
|
77
|
+
const result = await binding.artifactReader.read(input);
|
|
78
|
+
assertCurrent();
|
|
79
|
+
return result;
|
|
80
|
+
},
|
|
81
|
+
close: input => binding.artifactReader.close(input),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const firmwareHostBindingRegistry = new FirmwareHostBindingRegistry();
|
|
88
|
+
|
|
89
|
+
export const registerFirmwareUpdateHostBinding = (binding: FirmwareUpdateHostBinding): number =>
|
|
90
|
+
firmwareHostBindingRegistry.register(binding);
|
|
91
|
+
|
|
92
|
+
export const unregisterFirmwareUpdateHostBinding = (generation?: number): boolean =>
|
|
93
|
+
firmwareHostBindingRegistry.unregister(generation);
|
|
94
|
+
|
|
95
|
+
export const getFirmwareUpdateHostBindingGeneration = (): number =>
|
|
96
|
+
firmwareHostBindingRegistry.getGeneration();
|
|
97
|
+
|
|
98
|
+
export const resolveFirmwareUpdateHostBinding = (
|
|
99
|
+
generation: number | undefined
|
|
100
|
+
): FirmwareUpdateHostBinding => firmwareHostBindingRegistry.resolve(generation ?? Number.NaN);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ERRORS, HardwareError, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
export const normalizeFirmwarePreparationError = (error: unknown) => {
|
|
4
|
+
if (error instanceof HardwareError && error.params?.firmwareUpdateCode) {
|
|
5
|
+
return error;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return ERRORS.TypedError(
|
|
9
|
+
HardwareErrorCode.FirmwareUpdateDownloadFailed,
|
|
10
|
+
error instanceof Error ? error.message : String(error)
|
|
11
|
+
);
|
|
12
|
+
};
|
|
@@ -13,6 +13,8 @@ import { DeviceModelToTypes } from '../../types';
|
|
|
13
13
|
import { DataManager } from '../../data-manager';
|
|
14
14
|
import { BaseMethod } from '../BaseMethod';
|
|
15
15
|
import { DEVICE } from '../../events';
|
|
16
|
+
import { createFirmwareProgressThrottle } from './progressThrottle';
|
|
17
|
+
import { writeFirmwareByteSource } from './FirmwareArtifactSource';
|
|
16
18
|
|
|
17
19
|
import type {
|
|
18
20
|
IFirmwareUpdateProgressType,
|
|
@@ -23,11 +25,22 @@ import type { RebootType } from '@onekeyfe/hd-transport';
|
|
|
23
25
|
import type { Deferred } from '@onekeyfe/hd-shared';
|
|
24
26
|
import type { KnownDevice } from '../../types';
|
|
25
27
|
import type { TypedResponseMessage } from '../../device/DeviceCommands';
|
|
28
|
+
import type { FirmwareByteSource } from './FirmwareArtifactSource';
|
|
26
29
|
|
|
27
30
|
const Log = getLogger(LoggerNames.Method);
|
|
28
31
|
const SESSION_ERROR = 'session not found';
|
|
29
32
|
const FIRMWARE_UPDATE_CONFIRM = 'Firmware install confirmed';
|
|
30
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Response timeout for each Initialize probe while polling a rebooting device over BLE.
|
|
36
|
+
* Overlap safety comes from the poll's in-flight guard, not from this value. Keep it
|
|
37
|
+
* well below the 30s reboot budget so several attempts fit: a probe written into the
|
|
38
|
+
* dying pre-reboot connection is never answered, and its timeout tears that stale link
|
|
39
|
+
* down so the next tick reconnects fresh. Raise it only if a device model is proven to
|
|
40
|
+
* answer bootloader Initialize slower than this on a fresh connection.
|
|
41
|
+
*/
|
|
42
|
+
export const BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS = 5000;
|
|
43
|
+
|
|
31
44
|
const isDeviceDisconnectedError = (error: unknown) => {
|
|
32
45
|
const message = error instanceof Error ? error.message : String(error ?? '');
|
|
33
46
|
return (
|
|
@@ -40,6 +53,8 @@ const isDeviceDisconnectedError = (error: unknown) => {
|
|
|
40
53
|
export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
41
54
|
checkPromise: Deferred<any> | null = null;
|
|
42
55
|
|
|
56
|
+
private shouldPostFirmwareProgress = createFirmwareProgressThrottle();
|
|
57
|
+
|
|
43
58
|
init(): void {}
|
|
44
59
|
|
|
45
60
|
run(): Promise<any> {
|
|
@@ -83,6 +98,10 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
83
98
|
* @param progress Post the percentage of the progress
|
|
84
99
|
*/
|
|
85
100
|
postProgressMessage = (progress: number, progressType: IFirmwareUpdateProgressType) => {
|
|
101
|
+
if (!this.shouldPostFirmwareProgress(progress, progressType)) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
86
105
|
this.postMessage(
|
|
87
106
|
createUiMessage(UI_REQUEST.FIRMWARE_PROGRESS, {
|
|
88
107
|
device: this.device.toMessageObject() as KnownDevice,
|
|
@@ -132,6 +151,10 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
132
151
|
this.checkPromise = createDeferred();
|
|
133
152
|
const env = DataManager.getSettings('env');
|
|
134
153
|
const isBleReconnect = connectId && DataManager.isBleConnect(env);
|
|
154
|
+
// Tracks the in-flight BLE probe so interval ticks never overlap: a superseded
|
|
155
|
+
// Initialize left pending on the V1 transport is exactly what later times out
|
|
156
|
+
// and used to tear down the connection mid-firmware-upload.
|
|
157
|
+
let bleProbeInFlight = false;
|
|
135
158
|
|
|
136
159
|
Log.log('FirmwareUpdateBaseMethod [checkDeviceToBootloader] isBleReconnect: ', isBleReconnect);
|
|
137
160
|
|
|
@@ -187,14 +210,18 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
187
210
|
}
|
|
188
211
|
|
|
189
212
|
if (isBleReconnect) {
|
|
213
|
+
if (bleProbeInFlight) return;
|
|
214
|
+
bleProbeInFlight = true;
|
|
190
215
|
try {
|
|
191
216
|
await this.device.deviceConnector?.acquire(
|
|
192
217
|
this.device.originalDescriptor.id,
|
|
193
218
|
null,
|
|
194
|
-
true
|
|
195
|
-
this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType
|
|
219
|
+
true
|
|
196
220
|
);
|
|
197
|
-
|
|
221
|
+
// Bound each probe so a request the rebooting device never received
|
|
222
|
+
// frees the slot for the next tick instead of hanging into the
|
|
223
|
+
// 30s reboot budget.
|
|
224
|
+
await this.device.initialize({ timeoutMs: BOOTLOADER_POLL_INITIALIZE_TIMEOUT_MS });
|
|
198
225
|
if (this.device.isBootloader()) {
|
|
199
226
|
clearInterval(intervalTimer);
|
|
200
227
|
this.checkPromise?.resolve(true);
|
|
@@ -202,6 +229,8 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
202
229
|
} catch (e) {
|
|
203
230
|
// ignore error because of device is not connected
|
|
204
231
|
Log.log('catch Bluetooth error when device is restarting: ', e);
|
|
232
|
+
} finally {
|
|
233
|
+
bleProbeInFlight = false;
|
|
205
234
|
}
|
|
206
235
|
} else {
|
|
207
236
|
await this._checkDeviceInBootloaderMode(connectId, intervalTimer, timeoutTimer);
|
|
@@ -226,9 +255,7 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
226
255
|
) {
|
|
227
256
|
const deviceDiff = await this.device.deviceConnector?.enumerate();
|
|
228
257
|
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
229
|
-
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, connectId
|
|
230
|
-
connectProtocol: this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType,
|
|
231
|
-
});
|
|
258
|
+
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, connectId);
|
|
232
259
|
|
|
233
260
|
if (deviceList.length === 1 && deviceList[0]?.isBootloader()) {
|
|
234
261
|
// should update current device from cache
|
|
@@ -383,6 +410,54 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
383
410
|
return totalSize !== undefined ? (processedSize ?? 0) + payload.byteLength : 0;
|
|
384
411
|
}
|
|
385
412
|
|
|
413
|
+
async emmcCommonUpdateProcessFromSource({
|
|
414
|
+
source,
|
|
415
|
+
filePath,
|
|
416
|
+
processedSize,
|
|
417
|
+
totalSize,
|
|
418
|
+
}: {
|
|
419
|
+
source: FirmwareByteSource;
|
|
420
|
+
filePath: string;
|
|
421
|
+
processedSize?: number;
|
|
422
|
+
totalSize?: number;
|
|
423
|
+
}) {
|
|
424
|
+
if (!filePath.startsWith('0:')) {
|
|
425
|
+
throw new Error('filePath must start with 0:');
|
|
426
|
+
}
|
|
427
|
+
const env = DataManager.getSettings('env');
|
|
428
|
+
const chunkSize = 1024 * (DataManager.isBleConnect(env) ? 16 : 128);
|
|
429
|
+
|
|
430
|
+
await writeFirmwareByteSource({
|
|
431
|
+
source,
|
|
432
|
+
chunkSize,
|
|
433
|
+
write: async ({ data, sourceOffset, length, first }) => {
|
|
434
|
+
const progress =
|
|
435
|
+
totalSize !== undefined && processedSize !== undefined
|
|
436
|
+
? Math.min(Math.ceil(((processedSize + sourceOffset + length) / totalSize) * 100), 99)
|
|
437
|
+
: Math.min(Math.ceil(((sourceOffset + length) / source.size) * 100), 99);
|
|
438
|
+
const writeRes = await this.emmcFileWriteWithRetry(
|
|
439
|
+
filePath,
|
|
440
|
+
length,
|
|
441
|
+
sourceOffset,
|
|
442
|
+
data,
|
|
443
|
+
first,
|
|
444
|
+
progress
|
|
445
|
+
);
|
|
446
|
+
if (!writeRes) {
|
|
447
|
+
throw ERRORS.TypedError(
|
|
448
|
+
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
449
|
+
'transfer data error'
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
const processedBytes = Number(writeRes.message.processed_byte);
|
|
453
|
+
this.postProgressMessage(progress, 'transferData');
|
|
454
|
+
return Number.isFinite(processedBytes) ? processedBytes : length;
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
return totalSize !== undefined ? (processedSize ?? 0) + source.size : 0;
|
|
459
|
+
}
|
|
460
|
+
|
|
386
461
|
async emmcFileWriteWithRetry(
|
|
387
462
|
filePath: string,
|
|
388
463
|
chunkLength: number,
|
|
@@ -437,12 +512,7 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
437
512
|
const env = DataManager.getSettings('env');
|
|
438
513
|
if (DataManager.isBleConnect(env)) {
|
|
439
514
|
await wait(3000);
|
|
440
|
-
await this.device.deviceConnector?.acquire(
|
|
441
|
-
this.device.originalDescriptor.id,
|
|
442
|
-
null,
|
|
443
|
-
true,
|
|
444
|
-
this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType
|
|
445
|
-
);
|
|
515
|
+
await this.device.deviceConnector?.acquire(this.device.originalDescriptor.id, null, true);
|
|
446
516
|
await this.device.initialize();
|
|
447
517
|
} else if (
|
|
448
518
|
error?.message?.indexOf(SESSION_ERROR) > -1 ||
|
|
@@ -450,10 +520,7 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
|
|
|
450
520
|
) {
|
|
451
521
|
const deviceDiff = await this.device.deviceConnector?.enumerate();
|
|
452
522
|
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
453
|
-
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, undefined
|
|
454
|
-
connectProtocol:
|
|
455
|
-
this.payload.connectProtocol ?? this.device.originalDescriptor.protocolType,
|
|
456
|
-
});
|
|
523
|
+
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, undefined);
|
|
457
524
|
if (deviceList.length === 1 && deviceList[0]?.isBootloader()) {
|
|
458
525
|
this.device.updateFromCache(deviceList[0]);
|
|
459
526
|
await this.device.acquire();
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FirmwareUpdateCapabilities } from '../../types/api/firmwareUpdateCapabilities';
|
|
2
|
+
|
|
3
|
+
export const getFirmwareUpdateCapabilities = (): FirmwareUpdateCapabilities => ({
|
|
4
|
+
planSchemaVersion: 2,
|
|
5
|
+
preparedPlanSchemaVersion: 2,
|
|
6
|
+
hostBindingProtocolVersion: 2,
|
|
7
|
+
manifestModes: ['external-only', 'sdk-managed'],
|
|
8
|
+
supportsArtifactReader: true,
|
|
9
|
+
});
|