@onekeyfe/hd-core 1.2.0-alpha.1 → 1.2.0-alpha.11
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__/DeviceCommands.test.ts +25 -0
- package/__tests__/RequestQueue.test.ts +34 -0
- package/__tests__/connectSettings.test.ts +19 -0
- package/__tests__/device-wallet-session-store.test.ts +131 -0
- package/__tests__/preInitialize.test.ts +33 -0
- package/__tests__/pro2Wallpaper.test.ts +50 -0
- package/__tests__/protocol-v2-firmware-targets.test.ts +19 -0
- package/__tests__/protocol-v2.test.ts +3253 -1605
- package/dist/api/BaseMethod.d.ts +4 -0
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/ClearSessionCache.d.ts +9 -0
- package/dist/api/ClearSessionCache.d.ts.map +1 -0
- package/dist/api/FileRead.d.ts.map +1 -1
- package/dist/api/FileWrite.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +20 -3
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts +1 -6
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts +18 -0
- package/dist/api/UploadPortfolio.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +4 -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/index.d.ts +13 -10
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +7 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +1 -1
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +3 -2
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/{DeviceGetDeviceInfo.d.ts → DeviceInfoGet.d.ts} +10 -10
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceSettingsGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceSettingsGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts +16 -0
- package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceSettingsSet.d.ts +12 -0
- package/dist/api/protocol-v2/DeviceSettingsSet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceStatusGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +26 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -0
- package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
- package/dist/api/protocol-v2/{FilesystemFixPermission.d.ts → FilesystemPermissionFix.d.ts} +2 -2
- package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +6 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -0
- package/dist/api/protocol-v2/helpers.d.ts +27 -18
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/ton/TonSignData.d.ts +1 -5
- package/dist/api/ton/TonSignData.d.ts.map +1 -1
- package/dist/api/tron/TronSignMessage.d.ts +0 -1
- package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
- package/dist/api/tron/TronSignTransaction.d.ts +0 -1
- package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
- package/dist/core/RequestQueue.d.ts +2 -0
- package/dist/core/RequestQueue.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +1 -1
- 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 -3
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DeviceWalletSessionStore.d.ts +15 -0
- package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -0
- package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
- package/dist/deviceProfile/buildDeviceProfile.d.ts.map +1 -1
- package/dist/events/call.d.ts +7 -0
- package/dist/events/call.d.ts.map +1 -1
- package/dist/events/core.d.ts +2 -2
- package/dist/events/core.d.ts.map +1 -1
- package/dist/events/iframe.d.ts +1 -0
- package/dist/events/iframe.d.ts.map +1 -1
- package/dist/index.d.ts +166 -70
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2659 -1750
- package/dist/inject.d.ts +3 -2
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts +2 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts +12 -14
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/firmware.d.ts +11 -9
- package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/index.d.ts +1 -0
- package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +9 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +13 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -0
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +6 -6
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/getDeviceInfo.d.ts +2 -0
- package/dist/types/api/getDeviceInfo.d.ts.map +1 -1
- package/dist/types/api/getPassphraseState.d.ts +2 -10
- package/dist/types/api/getPassphraseState.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +18 -12
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +31 -17
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/api/sessionCache.d.ts +10 -0
- package/dist/types/api/sessionCache.d.ts.map +1 -0
- package/dist/types/device.d.ts +1 -0
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/params.d.ts +1 -0
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +21 -2
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +2 -2
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- 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 +12 -0
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +18 -0
- package/src/api/ClearSessionCache.ts +28 -0
- package/src/api/FileRead.ts +16 -3
- package/src/api/FileWrite.ts +22 -1
- package/src/api/FirmwareUpdateV4.ts +1006 -265
- package/src/api/GetOnekeyFeatures.ts +1 -1
- package/src/api/GetPassphraseState.ts +9 -15
- package/src/api/UploadPortfolio.ts +37 -0
- package/src/api/device/DeviceRebootToBoardloader.ts +4 -4
- package/src/api/device/DeviceRebootToBootloader.ts +4 -4
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +18 -4
- package/src/api/firmware/progressThrottle.ts +44 -0
- package/src/api/index.ts +13 -10
- package/src/api/protocol-v2/{FactoryGetDeviceInfo.ts → DeviceFactoryInfoGet.ts} +3 -3
- package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +32 -0
- package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +3 -5
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +39 -5
- package/src/api/protocol-v2/{DeviceGetDeviceInfo.ts → DeviceInfoGet.ts} +52 -22
- package/src/api/protocol-v2/DeviceReboot.ts +1 -1
- package/src/api/protocol-v2/DeviceSessionGet.ts +15 -0
- package/src/api/protocol-v2/{DeviceGetOnboardingStatus.ts → DeviceSettingsGet.ts} +3 -3
- package/src/api/protocol-v2/DeviceSettingsPageShow.ts +59 -0
- package/src/api/protocol-v2/DeviceSettingsSet.ts +39 -0
- package/src/api/protocol-v2/DeviceStatusGet.ts +14 -0
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +160 -0
- package/src/api/protocol-v2/FilesystemFormat.ts +4 -1
- package/src/api/protocol-v2/{FilesystemFixPermission.ts → FilesystemPermissionFix.ts} +2 -2
- package/src/api/protocol-v2/{GetProtoVersion.ts → ProtocolInfoRequest.ts} +2 -2
- package/src/api/protocol-v2/helpers.ts +71 -47
- package/src/api/ton/TonSignData.ts +1 -5
- package/src/api/tron/TronSignMessage.ts +0 -1
- package/src/api/tron/TronSignTransaction.ts +0 -1
- package/src/core/RequestQueue.ts +19 -0
- package/src/core/index.ts +29 -6
- package/src/data/messages/messages-protocol-v2.json +760 -1110
- package/src/data/messages/messages.json +8 -0
- package/src/data-manager/DataManager.ts +7 -0
- package/src/data-manager/connectSettings.ts +2 -4
- package/src/device/Device.ts +103 -70
- package/src/device/DeviceCommands.ts +9 -3
- package/src/device/DeviceWalletSessionStore.ts +78 -0
- package/src/deviceProfile/buildDeviceFeatures.ts +60 -63
- package/src/deviceProfile/buildDeviceProfile.ts +77 -58
- package/src/events/call.ts +6 -0
- package/src/events/core.ts +2 -0
- package/src/events/iframe.ts +1 -0
- package/src/index.ts +4 -0
- package/src/inject.ts +26 -16
- package/src/lowLevelInject.ts +3 -0
- package/src/protocols/protocol-v2/features.ts +26 -63
- package/src/protocols/protocol-v2/firmware.ts +12 -36
- package/src/protocols/protocol-v2/index.ts +1 -0
- package/src/protocols/protocol-v2/unlockRetry.ts +46 -0
- package/src/protocols/protocol-v2/walletSession.ts +92 -0
- package/src/topLevelInject.ts +2 -0
- package/src/types/api/firmwareUpdate.ts +28 -20
- package/src/types/api/getDeviceInfo.ts +2 -0
- package/src/types/api/getPassphraseState.ts +2 -11
- package/src/types/api/index.ts +29 -21
- package/src/types/api/protocolV2.ts +74 -35
- package/src/types/api/sessionCache.ts +14 -0
- package/src/types/device.ts +1 -0
- package/src/types/params.ts +4 -0
- package/src/types/settings.ts +42 -35
- package/src/utils/deviceFeaturesUtils.ts +46 -20
- package/src/utils/index.ts +6 -0
- package/src/utils/pro2Wallpaper.ts +111 -0
- package/dist/api/protocol-v2/DevReboot.d.ts +0 -7
- package/dist/api/protocol-v2/DevReboot.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +0 -6
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +0 -1
- package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts +0 -7
- package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts.map +0 -1
- package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts +0 -6
- package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts.map +0 -1
- package/dist/api/protocol-v2/FilesystemFixPermission.d.ts.map +0 -1
- package/dist/api/protocol-v2/GetProtoVersion.d.ts +0 -6
- package/dist/api/protocol-v2/GetProtoVersion.d.ts.map +0 -1
- package/src/api/protocol-v2/DevReboot.ts +0 -24
- package/src/api/protocol-v2/FactoryDeviceInfoSettings.ts +0 -29
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { DeviceSettingsPage } from '@onekeyfe/hd-transport';
|
|
2
|
+
|
|
3
|
+
import { BaseMethod } from '../BaseMethod';
|
|
4
|
+
import { invalidParameter } from '../helpers/filesystemValidation';
|
|
5
|
+
|
|
6
|
+
export type SupportedDeviceSettingsPage = DeviceSettingsPage;
|
|
7
|
+
|
|
8
|
+
export type DeviceSettingsPageShowParams = {
|
|
9
|
+
page?:
|
|
10
|
+
| SupportedDeviceSettingsPage
|
|
11
|
+
| 'DeviceReset'
|
|
12
|
+
| 'DevicePinChange'
|
|
13
|
+
| 'DevicePassphrase'
|
|
14
|
+
| 'DeviceAirgap';
|
|
15
|
+
fieldName?: string;
|
|
16
|
+
field_name?: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const SUPPORTED_PAGES = new Set<number>([
|
|
20
|
+
DeviceSettingsPage.DeviceReset,
|
|
21
|
+
DeviceSettingsPage.DevicePinChange,
|
|
22
|
+
DeviceSettingsPage.DevicePassphrase,
|
|
23
|
+
DeviceSettingsPage.DeviceAirgap,
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
function normalizePage(value: DeviceSettingsPageShowParams['page']): SupportedDeviceSettingsPage {
|
|
27
|
+
const page = typeof value === 'string' ? DeviceSettingsPage[value] : value;
|
|
28
|
+
if (page !== undefined && SUPPORTED_PAGES.has(page)) {
|
|
29
|
+
return page as SupportedDeviceSettingsPage;
|
|
30
|
+
}
|
|
31
|
+
throw invalidParameter(
|
|
32
|
+
'Parameter [page] must be DeviceReset, DevicePinChange, DevicePassphrase, or DeviceAirgap.'
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default class DeviceSettingsPageShow extends BaseMethod<{
|
|
37
|
+
page: SupportedDeviceSettingsPage;
|
|
38
|
+
field_name?: string;
|
|
39
|
+
}> {
|
|
40
|
+
init() {
|
|
41
|
+
this.requireProtocolV2 = true;
|
|
42
|
+
this.unlockPolicy = 'retry-on-locked';
|
|
43
|
+
this.skipForceUpdateCheck = true;
|
|
44
|
+
this.useDevicePassphraseState = false;
|
|
45
|
+
this.params = {
|
|
46
|
+
page: normalizePage(this.payload.page),
|
|
47
|
+
field_name: this.payload.field_name ?? this.payload.fieldName,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async run() {
|
|
52
|
+
const res = await this.device.commands.typedCall(
|
|
53
|
+
'DeviceSettingsPageShow',
|
|
54
|
+
'Success',
|
|
55
|
+
this.params
|
|
56
|
+
);
|
|
57
|
+
return Promise.resolve(res.message);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { BaseMethod } from '../BaseMethod';
|
|
2
|
+
import { invalidParameter } from '../helpers/filesystemValidation';
|
|
3
|
+
|
|
4
|
+
import type { DeviceSettings } from '@onekeyfe/hd-transport';
|
|
5
|
+
|
|
6
|
+
export type DeviceSettingsSetParams = {
|
|
7
|
+
settings?: Omit<DeviceSettings, 'passphrase_enable' | 'airgap_mode'>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default class DeviceSettingsSet extends BaseMethod<{
|
|
11
|
+
settings: Omit<DeviceSettings, 'passphrase_enable' | 'airgap_mode'>;
|
|
12
|
+
}> {
|
|
13
|
+
init() {
|
|
14
|
+
const settings = this.payload.settings;
|
|
15
|
+
if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
|
|
16
|
+
throw invalidParameter('Parameter [settings] must be an object.');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
passphrase_enable: _passphraseEnable,
|
|
21
|
+
airgap_mode: _airgapMode,
|
|
22
|
+
...supported
|
|
23
|
+
} = settings as DeviceSettings;
|
|
24
|
+
if (Object.keys(supported).length === 0) {
|
|
25
|
+
throw invalidParameter('Parameter [settings] must contain at least one supported setting.');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this.requireProtocolV2 = true;
|
|
29
|
+
this.unlockPolicy = 'retry-on-locked';
|
|
30
|
+
this.skipForceUpdateCheck = true;
|
|
31
|
+
this.useDevicePassphraseState = false;
|
|
32
|
+
this.params = { settings: supported };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async run() {
|
|
36
|
+
const res = await this.device.commands.typedCall('DeviceSettingsSet', 'Success', this.params);
|
|
37
|
+
return Promise.resolve(res.message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseMethod } from '../BaseMethod';
|
|
2
|
+
|
|
3
|
+
export default class DeviceStatusGet extends BaseMethod {
|
|
4
|
+
init() {
|
|
5
|
+
this.requireProtocolV2 = true;
|
|
6
|
+
this.useDevicePassphraseState = false;
|
|
7
|
+
this.skipForceUpdateCheck = true;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async run() {
|
|
11
|
+
const { message } = await this.device.commands.typedCall('DeviceStatusGet', 'DeviceStatus', {});
|
|
12
|
+
return message;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { blake2s } from '@noble/hashes/blake2s';
|
|
2
|
+
import { bytesToHex } from '@noble/hashes/utils';
|
|
3
|
+
import {
|
|
4
|
+
PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
|
|
5
|
+
PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE,
|
|
6
|
+
WallpaperTarget,
|
|
7
|
+
} from '@onekeyfe/hd-transport';
|
|
8
|
+
|
|
9
|
+
import { BaseMethod } from '../BaseMethod';
|
|
10
|
+
import { invalidParameter } from '../helpers/filesystemValidation';
|
|
11
|
+
import { DataManager } from '../../data-manager';
|
|
12
|
+
import {
|
|
13
|
+
encodePro2Wallpaper,
|
|
14
|
+
PRO2_WALLPAPER_HEIGHT,
|
|
15
|
+
PRO2_WALLPAPER_WIDTH,
|
|
16
|
+
type Pro2WallpaperColorFormat,
|
|
17
|
+
} from '../../utils/pro2Wallpaper';
|
|
18
|
+
|
|
19
|
+
export type DeviceUploadWallpaperParams = {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
rgba: Uint8Array | ArrayBuffer;
|
|
23
|
+
fileName?: string;
|
|
24
|
+
chunkSize?: number;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type DeviceUploadWallpaperResponse = {
|
|
28
|
+
path: string;
|
|
29
|
+
size: number;
|
|
30
|
+
colorFormat: Pro2WallpaperColorFormat;
|
|
31
|
+
message?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const WALLPAPER_DIRECTORY = 'vol0:/wallpapers/user';
|
|
35
|
+
const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
|
|
36
|
+
|
|
37
|
+
function getDefaultChunkSize(): number {
|
|
38
|
+
const env = DataManager.getSettings('env');
|
|
39
|
+
return env && DataManager.isBleConnect(env)
|
|
40
|
+
? PROTOCOL_V2_BLE_FILE_CHUNK_SIZE
|
|
41
|
+
: PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function normalizeFileName(fileName: string | undefined, data: Uint8Array): string {
|
|
45
|
+
if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
|
|
46
|
+
throw invalidParameter(
|
|
47
|
+
'Parameter [fileName] may only contain letters, numbers, underscores, hyphens and an optional .bin suffix.'
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const baseName = fileName ?? `wallpaper-${bytesToHex(blake2s(data)).slice(0, 12)}`;
|
|
51
|
+
return baseName.endsWith('.bin') ? baseName : `${baseName}.bin`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpaperParams> {
|
|
55
|
+
private encoded?: { data: Uint8Array; colorFormat: Pro2WallpaperColorFormat };
|
|
56
|
+
|
|
57
|
+
private directoryReady = false;
|
|
58
|
+
|
|
59
|
+
private uploaded = false;
|
|
60
|
+
|
|
61
|
+
private path = '';
|
|
62
|
+
|
|
63
|
+
init() {
|
|
64
|
+
const { width, height, rgba, fileName, chunkSize } = this.payload;
|
|
65
|
+
if (width !== PRO2_WALLPAPER_WIDTH || height !== PRO2_WALLPAPER_HEIGHT) {
|
|
66
|
+
throw invalidParameter(
|
|
67
|
+
`Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
if (!(rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(rgba)) {
|
|
71
|
+
throw invalidParameter('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
|
|
72
|
+
}
|
|
73
|
+
if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
|
|
74
|
+
throw invalidParameter('Parameter [chunkSize] must be a positive integer.');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const rgbaBytes =
|
|
78
|
+
rgba instanceof ArrayBuffer
|
|
79
|
+
? rgba
|
|
80
|
+
: new Uint8Array(rgba.buffer, rgba.byteOffset, rgba.byteLength);
|
|
81
|
+
this.encoded = encodePro2Wallpaper({ width, height, rgba: rgbaBytes });
|
|
82
|
+
this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
|
|
83
|
+
this.params = { width, height, rgba: rgbaBytes, fileName, chunkSize };
|
|
84
|
+
this.requireProtocolV2 = true;
|
|
85
|
+
this.unlockPolicy = 'retry-on-locked';
|
|
86
|
+
this.skipForceUpdateCheck = true;
|
|
87
|
+
this.useDevicePassphraseState = false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private async ensureDirectory() {
|
|
91
|
+
if (this.directoryReady) return;
|
|
92
|
+
try {
|
|
93
|
+
await this.device.commands.typedCall('FilesystemDirMake', 'Success', {
|
|
94
|
+
path: WALLPAPER_DIRECTORY,
|
|
95
|
+
});
|
|
96
|
+
} catch (error) {
|
|
97
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
98
|
+
if (!/exist/i.test(message)) throw error;
|
|
99
|
+
}
|
|
100
|
+
this.directoryReady = true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private async upload() {
|
|
104
|
+
if (this.uploaded) return;
|
|
105
|
+
const encoded = this.encoded;
|
|
106
|
+
if (!encoded) throw invalidParameter('Wallpaper data has not been initialized.');
|
|
107
|
+
|
|
108
|
+
const maxChunkSize = getDefaultChunkSize();
|
|
109
|
+
const requestedChunkSize = this.params.chunkSize ?? maxChunkSize;
|
|
110
|
+
const chunkSize = Math.min(Math.max(64, Math.floor(requestedChunkSize)), maxChunkSize);
|
|
111
|
+
let offset = 0;
|
|
112
|
+
while (offset < encoded.data.byteLength) {
|
|
113
|
+
const chunk = encoded.data.slice(offset, Math.min(offset + chunkSize, encoded.data.byteLength));
|
|
114
|
+
const response = await this.device.commands.typedCall(
|
|
115
|
+
'FilesystemFileWrite',
|
|
116
|
+
'FilesystemFile',
|
|
117
|
+
{
|
|
118
|
+
file: {
|
|
119
|
+
path: this.path,
|
|
120
|
+
offset,
|
|
121
|
+
total_size: encoded.data.byteLength,
|
|
122
|
+
data: chunk,
|
|
123
|
+
},
|
|
124
|
+
overwrite: offset === 0,
|
|
125
|
+
append: false,
|
|
126
|
+
ui_percentage: Math.min(
|
|
127
|
+
Math.ceil(((offset + chunk.byteLength) / encoded.data.byteLength) * 100),
|
|
128
|
+
100
|
|
129
|
+
),
|
|
130
|
+
},
|
|
131
|
+
{ timeoutMs: undefined }
|
|
132
|
+
);
|
|
133
|
+
const processedByte = Number(response.message?.processed_byte);
|
|
134
|
+
offset = Number.isFinite(processedByte) && processedByte > offset
|
|
135
|
+
? processedByte
|
|
136
|
+
: offset + chunk.byteLength;
|
|
137
|
+
if (offset > encoded.data.byteLength) {
|
|
138
|
+
throw invalidParameter(`Invalid processed_byte returned by device: ${processedByte}.`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
this.uploaded = true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async run(): Promise<DeviceUploadWallpaperResponse> {
|
|
145
|
+
const encoded = this.encoded;
|
|
146
|
+
if (!encoded) throw invalidParameter('Wallpaper data has not been initialized.');
|
|
147
|
+
await this.ensureDirectory();
|
|
148
|
+
await this.upload();
|
|
149
|
+
const response = await this.device.commands.typedCall('SetWallpaper', 'Success', {
|
|
150
|
+
target: WallpaperTarget.Lock,
|
|
151
|
+
path: this.path,
|
|
152
|
+
});
|
|
153
|
+
return {
|
|
154
|
+
path: this.path,
|
|
155
|
+
size: encoded.data.byteLength,
|
|
156
|
+
colorFormat: encoded.colorFormat,
|
|
157
|
+
message: response.message?.message,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -10,7 +10,10 @@ export default class FilesystemFormat extends BaseMethod {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
async run() {
|
|
13
|
-
const res = await this.device.commands.typedCall('FilesystemFormat', 'Success', {
|
|
13
|
+
const res = await this.device.commands.typedCall('FilesystemFormat', 'Success', {
|
|
14
|
+
data: true,
|
|
15
|
+
user: true,
|
|
16
|
+
});
|
|
14
17
|
return Promise.resolve(res.message);
|
|
15
18
|
}
|
|
16
19
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseMethod } from '../BaseMethod';
|
|
2
2
|
|
|
3
|
-
export default class
|
|
3
|
+
export default class FilesystemPermissionFix extends BaseMethod {
|
|
4
4
|
init() {
|
|
5
5
|
// Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
|
|
6
6
|
this.requireProtocolV2 = true;
|
|
@@ -10,7 +10,7 @@ export default class FilesystemFixPermission extends BaseMethod {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
async run() {
|
|
13
|
-
const res = await this.device.commands.typedCall('
|
|
13
|
+
const res = await this.device.commands.typedCall('FilesystemPermissionFix', 'Success', {});
|
|
14
14
|
return Promise.resolve(res.message);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseMethod } from '../BaseMethod';
|
|
2
2
|
|
|
3
|
-
export default class
|
|
3
|
+
export default class ProtocolInfoRequest extends BaseMethod {
|
|
4
4
|
init() {
|
|
5
5
|
// Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
|
|
6
6
|
this.requireProtocolV2 = true;
|
|
@@ -10,7 +10,7 @@ export default class GetProtoVersion extends BaseMethod {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
async run() {
|
|
13
|
-
const res = await this.device.commands.typedCall('
|
|
13
|
+
const res = await this.device.commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', {});
|
|
14
14
|
return Promise.resolve(res.message);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DeviceRebootType } from '@onekeyfe/hd-transport';
|
|
2
2
|
|
|
3
3
|
import { invalidParameter, validateNonEmptyString } from '../helpers/filesystemValidation';
|
|
4
|
+
import { ProtocolV2FirmwareTargetType } from '../../protocols/protocol-v2/firmware';
|
|
4
5
|
|
|
5
6
|
import type {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
DeviceFirmwareTarget,
|
|
8
|
+
DeviceFirmwareTargetType,
|
|
9
|
+
DeviceFirmwareUpdateRecordFields,
|
|
8
10
|
TransportCallOptions,
|
|
9
11
|
} from '@onekeyfe/hd-transport';
|
|
10
12
|
|
|
11
|
-
export type RebootTypeInput =
|
|
12
|
-
| DevRebootType
|
|
13
|
-
| keyof typeof DevRebootType
|
|
14
|
-
| string
|
|
15
|
-
| number;
|
|
13
|
+
export type RebootTypeInput = DeviceRebootType | keyof typeof DeviceRebootType | string | number;
|
|
16
14
|
|
|
17
15
|
export type DeviceRebootParams = {
|
|
18
16
|
rebootType?: RebootTypeInput;
|
|
@@ -20,48 +18,58 @@ export type DeviceRebootParams = {
|
|
|
20
18
|
};
|
|
21
19
|
|
|
22
20
|
export type DeviceFirmwareTargetInput =
|
|
23
|
-
|
|
|
21
|
+
| DeviceFirmwareTarget
|
|
24
22
|
| {
|
|
25
|
-
targetId?:
|
|
26
|
-
target_id?:
|
|
23
|
+
targetId?: DeviceFirmwareTargetType | string | number;
|
|
24
|
+
target_id?: DeviceFirmwareTargetType | string | number;
|
|
27
25
|
path: string;
|
|
28
26
|
};
|
|
29
27
|
|
|
30
28
|
export type DeviceFirmwareUpdateParams = {
|
|
31
29
|
targets?: DeviceFirmwareTargetInput[];
|
|
32
|
-
targetId?:
|
|
33
|
-
target_id?:
|
|
30
|
+
targetId?: DeviceFirmwareTargetType | string | number;
|
|
31
|
+
target_id?: DeviceFirmwareTargetType | string | number;
|
|
34
32
|
path?: string;
|
|
35
33
|
};
|
|
36
34
|
|
|
37
|
-
export type
|
|
38
|
-
|
|
39
|
-
serialNo?: string;
|
|
40
|
-
cpu_info?: string;
|
|
41
|
-
cpuInfo?: string;
|
|
42
|
-
pre_firmware?: string;
|
|
43
|
-
preFirmware?: string;
|
|
35
|
+
export type DeviceFirmwareUpdateStatusGetParams = {
|
|
36
|
+
fields?: DeviceFirmwareUpdateRecordFields;
|
|
44
37
|
};
|
|
45
38
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
export type DeviceFactoryInfoSetParams = {
|
|
40
|
+
version?: number;
|
|
41
|
+
serial_number?: string;
|
|
42
|
+
burn_in_completed?: boolean;
|
|
43
|
+
factory_test_completed?: boolean;
|
|
44
|
+
manufacture_time?: {
|
|
45
|
+
year: number;
|
|
46
|
+
month: number;
|
|
47
|
+
day: number;
|
|
48
|
+
hour: number;
|
|
49
|
+
minute: number;
|
|
50
|
+
second: number;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const DEVICE_REBOOT_TYPES: Record<string, DeviceRebootType> = {
|
|
55
|
+
Normal: DeviceRebootType.Normal,
|
|
56
|
+
normal: DeviceRebootType.Normal,
|
|
57
|
+
Romloader: DeviceRebootType.Romloader,
|
|
58
|
+
romloader: DeviceRebootType.Romloader,
|
|
59
|
+
Boardloader: DeviceRebootType.Romloader,
|
|
60
|
+
boardloader: DeviceRebootType.Romloader,
|
|
61
|
+
Bootloader: DeviceRebootType.Bootloader,
|
|
62
|
+
bootloader: DeviceRebootType.Bootloader,
|
|
55
63
|
};
|
|
56
64
|
|
|
57
65
|
export const PROTOCOL_V2_FIRMWARE_UPDATE_OPTIONS: TransportCallOptions = {
|
|
58
|
-
intermediateTypes: ['
|
|
66
|
+
intermediateTypes: ['DeviceFirmwareUpdateStatus'],
|
|
59
67
|
};
|
|
60
68
|
|
|
61
69
|
export const PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES: (
|
|
62
70
|
| 'Success'
|
|
63
|
-
| '
|
|
64
|
-
)[] = ['Success', '
|
|
71
|
+
| 'DeviceFirmwareUpdateStatus'
|
|
72
|
+
)[] = ['Success', 'DeviceFirmwareUpdateStatus'];
|
|
65
73
|
|
|
66
74
|
export const getProtocolV2UnknownErrorText = (error: unknown) => {
|
|
67
75
|
if (!error) {
|
|
@@ -120,40 +128,56 @@ export const isProtocolV2DeviceDisconnectedError = (error: unknown) => {
|
|
|
120
128
|
);
|
|
121
129
|
};
|
|
122
130
|
|
|
123
|
-
export function normalizeRebootType(value: RebootTypeInput | undefined):
|
|
131
|
+
export function normalizeRebootType(value: RebootTypeInput | undefined): DeviceRebootType {
|
|
124
132
|
if (typeof value === 'number') return value;
|
|
125
133
|
if (typeof value === 'string') {
|
|
126
134
|
const numeric = Number(value);
|
|
127
135
|
if (Number.isFinite(numeric)) return numeric;
|
|
128
|
-
if (value in
|
|
136
|
+
if (value in DEVICE_REBOOT_TYPES) return DEVICE_REBOOT_TYPES[value];
|
|
129
137
|
}
|
|
130
|
-
return
|
|
138
|
+
return DeviceRebootType.Normal;
|
|
131
139
|
}
|
|
132
140
|
|
|
133
|
-
//
|
|
134
|
-
const
|
|
141
|
+
// 与 firmware-pro2 的 proto_target_to_firmware_target 安装白名单保持一致。
|
|
142
|
+
const INSTALLABLE_FIRMWARE_TARGET_IDS = new Set<number>([
|
|
143
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
|
|
144
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER,
|
|
145
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1,
|
|
146
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2,
|
|
147
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR,
|
|
148
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01,
|
|
149
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02,
|
|
150
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03,
|
|
151
|
+
ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04,
|
|
152
|
+
]);
|
|
153
|
+
const FIRMWARE_TARGET_ID_BY_NAME = new Map<string, DeviceFirmwareTargetType>(
|
|
154
|
+
Object.entries(ProtocolV2FirmwareTargetType).flatMap(([key, value]) =>
|
|
155
|
+
INSTALLABLE_FIRMWARE_TARGET_IDS.has(value) ? [[key, value as DeviceFirmwareTargetType]] : []
|
|
156
|
+
)
|
|
157
|
+
);
|
|
135
158
|
|
|
136
159
|
function normalizeTargetId(
|
|
137
|
-
value:
|
|
160
|
+
value: DeviceFirmwareTargetType | string | number | undefined,
|
|
138
161
|
name: string
|
|
139
|
-
):
|
|
162
|
+
): DeviceFirmwareTargetType {
|
|
140
163
|
if (value === undefined || value === null) {
|
|
141
164
|
throw invalidParameter(`Missing required parameter: ${name}`);
|
|
142
165
|
}
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return numeric as DevFirmwareTargetType;
|
|
166
|
+
const named = typeof value === 'string' ? FIRMWARE_TARGET_ID_BY_NAME.get(value) : undefined;
|
|
167
|
+
const numeric = named ?? (typeof value === 'number' ? value : Number(value));
|
|
168
|
+
if (Number.isSafeInteger(numeric) && INSTALLABLE_FIRMWARE_TARGET_IDS.has(numeric)) {
|
|
169
|
+
return numeric as DeviceFirmwareTargetType;
|
|
148
170
|
}
|
|
149
171
|
throw invalidParameter(
|
|
150
|
-
`Parameter [${name}] must be
|
|
151
|
-
...
|
|
172
|
+
`Parameter [${name}] must be an installable firmware target id (one of ${[
|
|
173
|
+
...INSTALLABLE_FIRMWARE_TARGET_IDS,
|
|
152
174
|
].join(', ')}).`
|
|
153
175
|
);
|
|
154
176
|
}
|
|
155
177
|
|
|
156
|
-
export function normalizeFirmwareTargets(
|
|
178
|
+
export function normalizeFirmwareTargets(
|
|
179
|
+
params: DeviceFirmwareUpdateParams
|
|
180
|
+
): DeviceFirmwareTarget[] {
|
|
157
181
|
const targets =
|
|
158
182
|
params.targets ??
|
|
159
183
|
(params.path
|
package/src/core/RequestQueue.ts
CHANGED
|
@@ -14,6 +14,8 @@ export type RequestTask = {
|
|
|
14
14
|
export default class RequestQueue {
|
|
15
15
|
private requestQueue = new Map<number, RequestTask>();
|
|
16
16
|
|
|
17
|
+
private operationRequestIds = new Map<string, number>();
|
|
18
|
+
|
|
17
19
|
private pendingCallbackTasks = new Map<string, Deferred<void>>();
|
|
18
20
|
|
|
19
21
|
// 生成唯一请求ID
|
|
@@ -30,11 +32,21 @@ export default class RequestQueue {
|
|
|
30
32
|
method.responseID = requestId;
|
|
31
33
|
}
|
|
32
34
|
const abortController = new AbortController();
|
|
35
|
+
method.abortSignal = abortController.signal;
|
|
33
36
|
const task = { id: requestId, method, abortController };
|
|
34
37
|
this.requestQueue.set(requestId, task);
|
|
38
|
+
const operationId = method.payload?.operationId;
|
|
39
|
+
if (typeof operationId === 'string' && operationId) {
|
|
40
|
+
this.operationRequestIds.set(operationId, requestId);
|
|
41
|
+
}
|
|
35
42
|
return task;
|
|
36
43
|
}
|
|
37
44
|
|
|
45
|
+
public abortOperation(operationId: string) {
|
|
46
|
+
const requestId = this.operationRequestIds.get(operationId);
|
|
47
|
+
return requestId === undefined ? false : this.abortRequest(requestId);
|
|
48
|
+
}
|
|
49
|
+
|
|
38
50
|
public getTask(requestId: number): RequestTask | undefined {
|
|
39
51
|
return this.requestQueue.get(requestId);
|
|
40
52
|
}
|
|
@@ -105,6 +117,13 @@ export default class RequestQueue {
|
|
|
105
117
|
|
|
106
118
|
// 删除请求
|
|
107
119
|
public releaseTask(requestId: number) {
|
|
120
|
+
const operationId = this.requestQueue.get(requestId)?.method.payload?.operationId;
|
|
121
|
+
if (
|
|
122
|
+
typeof operationId === 'string' &&
|
|
123
|
+
this.operationRequestIds.get(operationId) === requestId
|
|
124
|
+
) {
|
|
125
|
+
this.operationRequestIds.delete(operationId);
|
|
126
|
+
}
|
|
108
127
|
this.requestQueue.delete(requestId);
|
|
109
128
|
}
|
|
110
129
|
|
package/src/core/index.ts
CHANGED
|
@@ -56,7 +56,7 @@ import TransportManager from '../data-manager/TransportManager';
|
|
|
56
56
|
import DeviceConnector from '../device/DeviceConnector';
|
|
57
57
|
import RequestQueue from './RequestQueue';
|
|
58
58
|
import { getSynchronize } from '../utils/getSynchronize';
|
|
59
|
-
import {
|
|
59
|
+
import { runMethodWithUnlockRetry } from '../protocols/protocol-v2/unlockRetry';
|
|
60
60
|
|
|
61
61
|
import type { ConnectSettings, Features, KnownDevice } from '../types';
|
|
62
62
|
import type { CoreMessage, IFrameCallMessage, UiPromise, UiPromiseResponse } from '../events';
|
|
@@ -96,6 +96,7 @@ const parseInitOptions = (method?: BaseMethod): InitOptions => ({
|
|
|
96
96
|
deviceId: method?.payload.deviceId,
|
|
97
97
|
deriveCardano: method && hasDeriveCardano(method),
|
|
98
98
|
connectProtocol: method?.payload.connectProtocol,
|
|
99
|
+
protocolV2DeviceInfoTimeoutMs: method?.payload.protocolV2DeviceInfoTimeoutMs,
|
|
99
100
|
});
|
|
100
101
|
|
|
101
102
|
let _core: Core;
|
|
@@ -223,9 +224,15 @@ const handlePreWarmSignal = async (
|
|
|
223
224
|
message: CoreMessage,
|
|
224
225
|
method: BaseMethod
|
|
225
226
|
): Promise<any> => {
|
|
227
|
+
const createAckResponse = () => {
|
|
228
|
+
completeMethodRequestContext(method);
|
|
229
|
+
method.dispose();
|
|
230
|
+
return createResponseMessage(method.responseID, true, true);
|
|
231
|
+
};
|
|
232
|
+
|
|
226
233
|
// no connectId: can't target a device safely, skip pre-warm (ack only)
|
|
227
234
|
if (!method.connectId) {
|
|
228
|
-
return
|
|
235
|
+
return createAckResponse();
|
|
229
236
|
}
|
|
230
237
|
|
|
231
238
|
const key = method.getPreWarmKey();
|
|
@@ -238,12 +245,12 @@ const handlePreWarmSignal = async (
|
|
|
238
245
|
} catch {
|
|
239
246
|
// pre-warm is best-effort; ignore its failure for the coalesced caller
|
|
240
247
|
}
|
|
241
|
-
return
|
|
248
|
+
return createAckResponse();
|
|
242
249
|
}
|
|
243
250
|
|
|
244
251
|
const doneAt = preWarmDoneAt.get(key);
|
|
245
252
|
if (typeof doneAt === 'number' && Date.now() - doneAt <= method.preWarmTtl) {
|
|
246
|
-
return
|
|
253
|
+
return createAckResponse();
|
|
247
254
|
}
|
|
248
255
|
|
|
249
256
|
const run = onCallDevice(context, message, method);
|
|
@@ -610,7 +617,7 @@ const onCallDevice = async (
|
|
|
610
617
|
method.device?.commands?.checkDisposed();
|
|
611
618
|
|
|
612
619
|
try {
|
|
613
|
-
const response: object = await method
|
|
620
|
+
const response: object = await runMethodWithUnlockRetry(method, device);
|
|
614
621
|
messageResponse = createResponseMessage(method.responseID, true, response);
|
|
615
622
|
requestQueue.resolveRequest(method.responseID, messageResponse);
|
|
616
623
|
completeMethodRequestContext(method);
|
|
@@ -732,6 +739,15 @@ function initDevice(method: BaseMethod) {
|
|
|
732
739
|
|
|
733
740
|
if (method.connectId) {
|
|
734
741
|
device = _deviceList.getDevice(method.connectId);
|
|
742
|
+
if (!device && method.name === 'firmwareUpdateV4' && allDevices.length === 1) {
|
|
743
|
+
const [singleDevice] = allDevices;
|
|
744
|
+
if (singleDevice.isBootloader()) {
|
|
745
|
+
Log.debug(
|
|
746
|
+
'firmwareUpdateV4 uses the only bootloader device when connectId changed after reboot'
|
|
747
|
+
);
|
|
748
|
+
device = singleDevice;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
735
751
|
} else if (allDevices.length === 1) {
|
|
736
752
|
[device] = allDevices;
|
|
737
753
|
} else if (allDevices.length > 1) {
|
|
@@ -1326,6 +1342,10 @@ export default class Core extends EventEmitter {
|
|
|
1326
1342
|
Log.debug(`[Core] Created SDK instance: ${this.sdkInstanceId}`);
|
|
1327
1343
|
}
|
|
1328
1344
|
|
|
1345
|
+
cancelOperation(operationId: string) {
|
|
1346
|
+
this.requestQueue.abortOperation(operationId);
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1329
1349
|
private getCoreContext() {
|
|
1330
1350
|
return {
|
|
1331
1351
|
sdkInstanceId: this.sdkInstanceId,
|
|
@@ -1394,6 +1414,10 @@ export default class Core extends EventEmitter {
|
|
|
1394
1414
|
cancel(this.getCoreContext(), message.payload.connectId);
|
|
1395
1415
|
break;
|
|
1396
1416
|
}
|
|
1417
|
+
case IFRAME.CANCEL_OPERATION: {
|
|
1418
|
+
this.cancelOperation(message.payload.operationId);
|
|
1419
|
+
break;
|
|
1420
|
+
}
|
|
1397
1421
|
case IFRAME.CALLBACK: {
|
|
1398
1422
|
Log.log('callback message: ', message);
|
|
1399
1423
|
postMessage(message);
|
|
@@ -1439,7 +1463,6 @@ export const init = async (
|
|
|
1439
1463
|
try {
|
|
1440
1464
|
try {
|
|
1441
1465
|
await DataManager.load(settings);
|
|
1442
|
-
setProtocolV2DeviceInfoMock(settings.protocolV2DeviceInfoMockEnabled ?? false);
|
|
1443
1466
|
initTransport(Transport, plugin);
|
|
1444
1467
|
} catch {
|
|
1445
1468
|
Log.error('DataManager.load error');
|