@onekeyfe/hd-core 1.2.0-alpha.79 → 1.2.0-alpha.80
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__/check-all-firmware-release-protocol-v2.test.ts +51 -5
- package/__tests__/check-firmware-release-protocol-v2.test.ts +164 -0
- package/__tests__/protocol-v2-resources.test.ts +24 -8
- package/__tests__/protocol-v2.test.ts +195 -49
- package/dist/api/CheckAllFirmwareRelease.d.ts +2 -3
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBLEFirmwareRelease.d.ts +2 -1
- package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBootloaderRelease.d.ts +3 -2
- package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
- package/dist/api/CheckFirmwareRelease.d.ts +2 -1
- package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/firmware/protocolV2Release.d.ts +33 -0
- package/dist/api/firmware/protocolV2Release.d.ts.map +1 -0
- package/dist/index.d.ts +35 -49
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +340 -183
- package/dist/protocols/protocol-v2/resources.d.ts +0 -4
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +20 -9
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkBLEFirmwareRelease.d.ts +2 -13
- package/dist/types/api/checkBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkBootloaderRelease.d.ts +2 -6
- package/dist/types/api/checkBootloaderRelease.d.ts.map +1 -1
- package/dist/types/api/checkFirmwareRelease.d.ts +2 -13
- package/dist/types/api/checkFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkFirmwareTypeAvailable.d.ts +2 -2
- package/dist/types/api/checkFirmwareTypeAvailable.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +1 -1
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +1 -1
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/settings.d.ts +3 -1
- package/dist/types/settings.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +49 -49
- package/src/api/CheckBLEFirmwareRelease.ts +41 -3
- package/src/api/CheckBootloaderRelease.ts +40 -1
- package/src/api/CheckFirmwareRelease.ts +37 -3
- package/src/api/FirmwareUpdateV4.ts +35 -15
- package/src/api/firmware/protocolV2Release.ts +166 -0
- package/src/index.ts +0 -1
- package/src/protocols/protocol-v2/resources.ts +19 -25
- package/src/types/api/checkAllFirmwareRelease.ts +27 -13
- package/src/types/api/checkBLEFirmwareRelease.ts +4 -13
- package/src/types/api/checkBootloaderRelease.ts +2 -6
- package/src/types/api/checkFirmwareRelease.ts +2 -13
- package/src/types/api/checkFirmwareTypeAvailable.ts +2 -2
- package/src/types/api/export.ts +6 -1
- package/src/types/api/firmwareUpdate.ts +2 -3
- package/src/types/settings.ts +3 -1
|
@@ -73,7 +73,9 @@ const release: IFirmwareReleaseInfo = {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
const resourceSource = {
|
|
76
|
-
|
|
76
|
+
archiveUrl: 'https://example.com/pro2-resource/pro2-resource.zip',
|
|
77
|
+
archiveSha256: 'a'.repeat(64),
|
|
78
|
+
archiveSize: 16_815_479,
|
|
77
79
|
};
|
|
78
80
|
|
|
79
81
|
describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
@@ -328,8 +330,9 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
328
330
|
deviceType: 'pro2',
|
|
329
331
|
status: 'required',
|
|
330
332
|
resourceStatus: 'unknown',
|
|
331
|
-
|
|
332
|
-
|
|
333
|
+
resourceArchive: resourceSource,
|
|
334
|
+
resourcePreparationRequired: true,
|
|
335
|
+
targetsToUpdate: ['boot', 'app_v1', 'resource'],
|
|
333
336
|
firmware: {
|
|
334
337
|
status: 'required',
|
|
335
338
|
},
|
|
@@ -417,13 +420,56 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
417
420
|
await expect(method.run()).resolves.toMatchObject({
|
|
418
421
|
protocol: 'V2',
|
|
419
422
|
resourceStatus: 'unknown',
|
|
420
|
-
|
|
421
|
-
|
|
423
|
+
resourceArchive: resourceSource,
|
|
424
|
+
resourcePreparationRequired: true,
|
|
425
|
+
targetsToUpdate: ['boot', 'app_v1', 'resource'],
|
|
422
426
|
});
|
|
423
427
|
expect(typedCall).not.toHaveBeenCalled();
|
|
424
428
|
}
|
|
425
429
|
);
|
|
426
430
|
|
|
431
|
+
test('requires manifest preparation when only Protocol V2 resources may have changed', async () => {
|
|
432
|
+
const currentRelease: IFirmwareReleaseInfo = {
|
|
433
|
+
...release,
|
|
434
|
+
required: false,
|
|
435
|
+
installOrder: ['applicationP1'],
|
|
436
|
+
components: {
|
|
437
|
+
applicationP1: {
|
|
438
|
+
target: 'APPLICATION_P1',
|
|
439
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
440
|
+
version: [1, 0, 0],
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
};
|
|
444
|
+
const method = new CheckAllFirmwareRelease({
|
|
445
|
+
id: 1,
|
|
446
|
+
payload: {
|
|
447
|
+
method: 'checkAllFirmwareRelease',
|
|
448
|
+
firmwareType: EFirmwareType.Universal,
|
|
449
|
+
},
|
|
450
|
+
});
|
|
451
|
+
method.init();
|
|
452
|
+
method.device = {
|
|
453
|
+
isProtocolV2: () => true,
|
|
454
|
+
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
455
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
456
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
457
|
+
status: { mode: 'normal' },
|
|
458
|
+
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
459
|
+
}),
|
|
460
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
461
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
462
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
463
|
+
|
|
464
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
465
|
+
status: 'unknown',
|
|
466
|
+
hasUpgrade: true,
|
|
467
|
+
resourceStatus: 'unknown',
|
|
468
|
+
resourcePreparationRequired: true,
|
|
469
|
+
targetsToUpdate: ['resource'],
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
|
|
427
473
|
test('continues forwarding the existing public method', async () => {
|
|
428
474
|
const call = jest.fn().mockResolvedValue({ success: true, payload: {} });
|
|
429
475
|
const api = createCoreApi(call as CoreApi['call']) as CoreApi;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { EFirmwareType } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import CheckAllFirmwareRelease from '../src/api/CheckAllFirmwareRelease';
|
|
4
|
+
import CheckBLEFirmwareRelease from '../src/api/CheckBLEFirmwareRelease';
|
|
5
|
+
import CheckBootloaderRelease from '../src/api/CheckBootloaderRelease';
|
|
6
|
+
import CheckFirmwareRelease from '../src/api/CheckFirmwareRelease';
|
|
7
|
+
import { DataManager } from '../src/data-manager';
|
|
8
|
+
|
|
9
|
+
import type { IFirmwareReleaseInfo } from '../src/types';
|
|
10
|
+
|
|
11
|
+
jest.mock('../src/data/config', () => ({
|
|
12
|
+
DEFAULT_DOMAIN: 'https://example.com/',
|
|
13
|
+
getSDKVersion: () => '0.0.0-test',
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
const release: IFirmwareReleaseInfo = {
|
|
17
|
+
required: false,
|
|
18
|
+
version: [2, 0, 0],
|
|
19
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
20
|
+
fingerprint: 'release-fingerprint',
|
|
21
|
+
changelog: {
|
|
22
|
+
'zh-CN': '更新',
|
|
23
|
+
'en-US': 'Update',
|
|
24
|
+
},
|
|
25
|
+
installOrder: ['bootloader', 'applicationP1', 'coprocessor'],
|
|
26
|
+
components: {
|
|
27
|
+
bootloader: {
|
|
28
|
+
target: 'BOOTLOADER',
|
|
29
|
+
url: 'https://example.com/bootloader.okpkg',
|
|
30
|
+
version: [2, 0, 0],
|
|
31
|
+
},
|
|
32
|
+
applicationP1: {
|
|
33
|
+
target: 'APPLICATION_P1',
|
|
34
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
35
|
+
version: [2, 0, 0],
|
|
36
|
+
},
|
|
37
|
+
coprocessor: {
|
|
38
|
+
target: 'COPROCESSOR',
|
|
39
|
+
url: 'https://example.com/coprocessor.okpkg',
|
|
40
|
+
version: [2, 0, 0],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const createDevice = (deviceType: 'pro2' | 'neo') => ({
|
|
46
|
+
isProtocolV2: () => true,
|
|
47
|
+
features: {
|
|
48
|
+
deviceType,
|
|
49
|
+
firmwareVersion: '1.0.0',
|
|
50
|
+
},
|
|
51
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
52
|
+
identity: {
|
|
53
|
+
deviceType,
|
|
54
|
+
firmwareType: EFirmwareType.Universal,
|
|
55
|
+
},
|
|
56
|
+
status: { mode: 'normal' },
|
|
57
|
+
versions: {
|
|
58
|
+
firmware: '1.0.0',
|
|
59
|
+
applicationP1: '1.0.0',
|
|
60
|
+
bootloader: '1.0.0',
|
|
61
|
+
board: '1.0.0',
|
|
62
|
+
ble: '1.0.0',
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe.each(['pro2', 'neo'] as const)('Protocol V2 release checks for %s', deviceType => {
|
|
68
|
+
afterEach(() => {
|
|
69
|
+
jest.restoreAllMocks();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('supports firmware, BLE, bootloader, and aggregate release checks', async () => {
|
|
73
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
74
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue({
|
|
75
|
+
archiveUrl: `https://example.com/${deviceType}/pro2-resource.zip`,
|
|
76
|
+
archiveSha256: 'a'.repeat(64),
|
|
77
|
+
archiveSize: 16_815_479,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const firmwareMethod = new CheckFirmwareRelease({
|
|
81
|
+
id: 1,
|
|
82
|
+
payload: { method: 'checkFirmwareRelease' },
|
|
83
|
+
});
|
|
84
|
+
firmwareMethod.init();
|
|
85
|
+
firmwareMethod.device = createDevice(deviceType) as unknown as CheckFirmwareRelease['device'];
|
|
86
|
+
|
|
87
|
+
const bleMethod = new CheckBLEFirmwareRelease({
|
|
88
|
+
id: 2,
|
|
89
|
+
payload: { method: 'checkBLEFirmwareRelease' },
|
|
90
|
+
});
|
|
91
|
+
bleMethod.init();
|
|
92
|
+
bleMethod.device = createDevice(deviceType) as unknown as CheckBLEFirmwareRelease['device'];
|
|
93
|
+
|
|
94
|
+
const bootloaderMethod = new CheckBootloaderRelease({
|
|
95
|
+
id: 3,
|
|
96
|
+
payload: { method: 'checkBootloaderRelease' },
|
|
97
|
+
});
|
|
98
|
+
bootloaderMethod.init();
|
|
99
|
+
bootloaderMethod.device = createDevice(
|
|
100
|
+
deviceType
|
|
101
|
+
) as unknown as CheckBootloaderRelease['device'];
|
|
102
|
+
|
|
103
|
+
const allMethod = new CheckAllFirmwareRelease({
|
|
104
|
+
id: 4,
|
|
105
|
+
payload: { method: 'checkAllFirmwareRelease' },
|
|
106
|
+
});
|
|
107
|
+
allMethod.init();
|
|
108
|
+
allMethod.device = createDevice(deviceType) as unknown as CheckAllFirmwareRelease['device'];
|
|
109
|
+
|
|
110
|
+
await expect(firmwareMethod.run()).resolves.toMatchObject({
|
|
111
|
+
status: 'outdated',
|
|
112
|
+
shouldUpdate: true,
|
|
113
|
+
release,
|
|
114
|
+
});
|
|
115
|
+
await expect(bleMethod.run()).resolves.toMatchObject({
|
|
116
|
+
status: 'outdated',
|
|
117
|
+
shouldUpdate: true,
|
|
118
|
+
release: {
|
|
119
|
+
protocol: 'V2',
|
|
120
|
+
configKey: 'coprocessor',
|
|
121
|
+
componentTarget: 'COPROCESSOR',
|
|
122
|
+
target: 'COPROCESSOR',
|
|
123
|
+
url: 'https://example.com/coprocessor.okpkg',
|
|
124
|
+
version: [2, 0, 0],
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
await expect(bootloaderMethod.run()).resolves.toMatchObject({
|
|
128
|
+
status: 'outdated',
|
|
129
|
+
shouldUpdate: true,
|
|
130
|
+
release: {
|
|
131
|
+
protocol: 'V2',
|
|
132
|
+
configKey: 'bootloader',
|
|
133
|
+
componentTarget: 'BOOTLOADER',
|
|
134
|
+
target: 'BOOTLOADER',
|
|
135
|
+
url: 'https://example.com/bootloader.okpkg',
|
|
136
|
+
version: [2, 0, 0],
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
await expect(allMethod.run()).resolves.toMatchObject({
|
|
140
|
+
protocol: 'V2',
|
|
141
|
+
deviceType,
|
|
142
|
+
status: 'outdated',
|
|
143
|
+
hasUpgrade: true,
|
|
144
|
+
resourcePreparationRequired: true,
|
|
145
|
+
targetsToUpdate: ['boot', 'app_v1', 'coprocessor', 'resource'],
|
|
146
|
+
firmware: { status: 'outdated', shouldUpdate: true },
|
|
147
|
+
ble: {
|
|
148
|
+
status: 'outdated',
|
|
149
|
+
shouldUpdate: true,
|
|
150
|
+
release: { componentTarget: 'COPROCESSOR' },
|
|
151
|
+
},
|
|
152
|
+
bootloader: {
|
|
153
|
+
status: 'outdated',
|
|
154
|
+
shouldUpdate: true,
|
|
155
|
+
release: { componentTarget: 'BOOTLOADER' },
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
expect(firmwareMethod.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
160
|
+
expect(bleMethod.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
161
|
+
expect(bootloaderMethod.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
162
|
+
expect(allMethod.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
@@ -22,7 +22,9 @@ const bytesToHex = (bytes: Uint8Array) =>
|
|
|
22
22
|
Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');
|
|
23
23
|
|
|
24
24
|
const resourceSource = {
|
|
25
|
-
|
|
25
|
+
archiveUrl: 'https://example.com/resource/pro2-resource.zip',
|
|
26
|
+
archiveSha256: 'a'.repeat(64),
|
|
27
|
+
archiveSize: 16_815_479,
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
const manifestFiles = [
|
|
@@ -122,8 +124,23 @@ describe('Pro2 resource configuration', () => {
|
|
|
122
124
|
test('rejects missing source and malformed manifest paths', () => {
|
|
123
125
|
expect(() => parseProtocolV2Resources({})).toThrow('source is required');
|
|
124
126
|
expect(() =>
|
|
125
|
-
parseProtocolV2Resources({
|
|
127
|
+
parseProtocolV2Resources({
|
|
128
|
+
source: {
|
|
129
|
+
...resourceSource,
|
|
130
|
+
archiveUrl: 'http://example.com/pro2-resource.zip',
|
|
131
|
+
},
|
|
132
|
+
})
|
|
126
133
|
).toThrow('must use HTTPS');
|
|
134
|
+
expect(() =>
|
|
135
|
+
parseProtocolV2Resources({
|
|
136
|
+
source: { ...resourceSource, archiveSha256: 'invalid' },
|
|
137
|
+
})
|
|
138
|
+
).toThrow('SHA-256');
|
|
139
|
+
expect(() =>
|
|
140
|
+
parseProtocolV2Resources({
|
|
141
|
+
source: { ...resourceSource, archiveSize: 0 },
|
|
142
|
+
})
|
|
143
|
+
).toThrow('positive integer');
|
|
127
144
|
expect(() =>
|
|
128
145
|
parseProtocolV2ResourceManifest({
|
|
129
146
|
...resourceManifest,
|
|
@@ -141,12 +158,11 @@ describe('Pro2 resource configuration', () => {
|
|
|
141
158
|
archivePath: file.archive_path,
|
|
142
159
|
binary: file.binary,
|
|
143
160
|
})),
|
|
144
|
-
targetsToUpdate: ['
|
|
161
|
+
targetsToUpdate: ['resource'],
|
|
145
162
|
});
|
|
146
|
-
expect(prepared.map(file => file.devicePath)).toEqual(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
]);
|
|
163
|
+
expect(prepared.map(file => file.devicePath)).toEqual(
|
|
164
|
+
manifestFiles.map(file => file.device_path)
|
|
165
|
+
);
|
|
150
166
|
expect(() =>
|
|
151
167
|
prepareProtocolV2ResourceFiles({
|
|
152
168
|
manifest: resourceManifest,
|
|
@@ -171,7 +187,7 @@ describe('Pro2 resource configuration', () => {
|
|
|
171
187
|
);
|
|
172
188
|
});
|
|
173
189
|
|
|
174
|
-
test('applies a validated pre-release config and exposes its
|
|
190
|
+
test('applies a validated pre-release config and exposes its archive source', async () => {
|
|
175
191
|
const configFetcher = jest.fn().mockResolvedValue(createRemoteConfig());
|
|
176
192
|
|
|
177
193
|
await expect(DataManager.load(createSettings(configFetcher))).resolves.toBe(true);
|
|
@@ -114,6 +114,26 @@ jest.mock('../src/data/config', () => ({
|
|
|
114
114
|
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
|
|
115
115
|
}));
|
|
116
116
|
|
|
117
|
+
const createProtocolV2OkppBinary = ({
|
|
118
|
+
version = [1, 2, 3],
|
|
119
|
+
payloadHashByte = 0x11,
|
|
120
|
+
headerHashByte = 0x22,
|
|
121
|
+
}: {
|
|
122
|
+
version?: [number, number, number];
|
|
123
|
+
payloadHashByte?: number;
|
|
124
|
+
headerHashByte?: number;
|
|
125
|
+
} = {}) => {
|
|
126
|
+
const bytes = new Uint8Array(0x52a0);
|
|
127
|
+
bytes.set([0x4f, 0x4b, 0x50, 0x50], 0);
|
|
128
|
+
bytes.set([0x52, 0x45, 0x53, 0x43], 0x08);
|
|
129
|
+
const view = new DataView(bytes.buffer);
|
|
130
|
+
view.setUint32(0x0c, 0x52a0, true);
|
|
131
|
+
view.setUint32(0x10, version[0] * 0x10000 + version[1] * 0x100 + version[2], true);
|
|
132
|
+
bytes.fill(payloadHashByte, 0x200, 0x240);
|
|
133
|
+
bytes.fill(headerHashByte, 0x240, 0x280);
|
|
134
|
+
return bytes.buffer;
|
|
135
|
+
};
|
|
136
|
+
|
|
117
137
|
const createWalletSessionTypedCall = (
|
|
118
138
|
implementation = jest.fn(),
|
|
119
139
|
status: Partial<DeviceStatus> = { passphrase_enabled: true }
|
|
@@ -5554,6 +5574,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5554
5574
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest
|
|
5555
5575
|
.fn()
|
|
5556
5576
|
.mockResolvedValue(undefined);
|
|
5577
|
+
(method as any).isProtocolV2ResourceBundleUpToDate = jest.fn().mockResolvedValue(false);
|
|
5557
5578
|
|
|
5558
5579
|
await (method as any).executeProtocolV2Update({
|
|
5559
5580
|
resourceBundles: [
|
|
@@ -5561,6 +5582,9 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5561
5582
|
name: 'images.okpkg',
|
|
5562
5583
|
binary: new Uint8Array([1, 2]).buffer,
|
|
5563
5584
|
devicePath: 'vol0:/bundles/images/images.okpkg',
|
|
5585
|
+
version: [1, 2, 3],
|
|
5586
|
+
payloadHash: '11'.repeat(64),
|
|
5587
|
+
headerHash: '22'.repeat(64),
|
|
5564
5588
|
},
|
|
5565
5589
|
],
|
|
5566
5590
|
bootloaderBinary: null,
|
|
@@ -5585,6 +5609,13 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5585
5609
|
2,
|
|
5586
5610
|
expect.objectContaining({ processedSize: 0, totalSize: 1 })
|
|
5587
5611
|
);
|
|
5612
|
+
expect((method as any).isProtocolV2ResourceBundleUpToDate).toHaveBeenCalledWith(
|
|
5613
|
+
expect.objectContaining({
|
|
5614
|
+
version: [1, 2, 3],
|
|
5615
|
+
payloadHash: '11'.repeat(64),
|
|
5616
|
+
headerHash: '22'.repeat(64),
|
|
5617
|
+
})
|
|
5618
|
+
);
|
|
5588
5619
|
});
|
|
5589
5620
|
|
|
5590
5621
|
test('installs and verifies bootloader before syncing manifest resources', () => {
|
|
@@ -6111,58 +6142,118 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6111
6142
|
});
|
|
6112
6143
|
});
|
|
6113
6144
|
|
|
6114
|
-
test
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6145
|
+
test('treats manual resource files as authoritative payload for resource', async () => {
|
|
6146
|
+
const resourceBundle = createProtocolV2OkppBinary();
|
|
6147
|
+
const method = new FirmwareUpdateV4({
|
|
6148
|
+
id: 1,
|
|
6149
|
+
payload: {
|
|
6150
|
+
method: 'firmwareUpdateV4',
|
|
6151
|
+
platform: 'web',
|
|
6152
|
+
targetsToUpdate: ['resource'],
|
|
6153
|
+
resourceFiles: [
|
|
6154
|
+
{
|
|
6155
|
+
binary: resourceBundle,
|
|
6156
|
+
devicePath: ' VOL0:/resource/images/images.okpkg ',
|
|
6157
|
+
},
|
|
6158
|
+
],
|
|
6159
|
+
},
|
|
6160
|
+
});
|
|
6161
|
+
method.init();
|
|
6162
|
+
(method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
|
|
6163
|
+
(method as any).device = stubDevice({
|
|
6164
|
+
originalDescriptor: { protocolType: 'V2' },
|
|
6165
|
+
features: { deviceType: 'pro2', firmwareVersion: '0.0.0', capabilities: [] },
|
|
6166
|
+
});
|
|
6167
|
+
(method as any).prepareRemoteProtocolV2Binaries = jest.fn();
|
|
6168
|
+
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(true);
|
|
6169
|
+
(method as any).executeProtocolV2Update = jest.fn().mockResolvedValue(undefined);
|
|
6170
|
+
(method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
|
|
6171
|
+
(method as any).waitForProtocolV2FinalFeatures = jest.fn().mockResolvedValue({
|
|
6172
|
+
bootloaderVersion: '1.0.0',
|
|
6173
|
+
bleVersion: '0.0.0',
|
|
6174
|
+
firmwareVersion: '1.0.0',
|
|
6175
|
+
});
|
|
6176
|
+
method.postTipMessage = jest.fn();
|
|
6177
|
+
|
|
6178
|
+
await method.run();
|
|
6179
|
+
|
|
6180
|
+
expect(forceReloadDataSpy).not.toHaveBeenCalled();
|
|
6181
|
+
expect((method as any).prepareRemoteProtocolV2Binaries).not.toHaveBeenCalled();
|
|
6182
|
+
expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith(
|
|
6183
|
+
expect.objectContaining({
|
|
6184
|
+
resourceBundles: [
|
|
6185
|
+
{
|
|
6186
|
+
name: 'images.okpkg',
|
|
6187
|
+
binary: resourceBundle,
|
|
6188
|
+
devicePath: 'vol0:/resource/images/images.okpkg',
|
|
6189
|
+
version: [1, 2, 3],
|
|
6190
|
+
payloadHash: '11'.repeat(64),
|
|
6191
|
+
headerHash: '22'.repeat(64),
|
|
6192
|
+
},
|
|
6193
|
+
],
|
|
6194
|
+
})
|
|
6195
|
+
);
|
|
6196
|
+
});
|
|
6197
|
+
|
|
6198
|
+
test('combines prepared firmware components with explicit manifest resource files', async () => {
|
|
6199
|
+
const resourceBundle = createProtocolV2OkppBinary();
|
|
6200
|
+
const method = new FirmwareUpdateV4({
|
|
6201
|
+
id: 1,
|
|
6202
|
+
payload: {
|
|
6203
|
+
method: 'firmwareUpdateV4',
|
|
6204
|
+
platform: 'web',
|
|
6205
|
+
},
|
|
6206
|
+
});
|
|
6207
|
+
method.init();
|
|
6208
|
+
(method as any).params = {
|
|
6209
|
+
targetsToUpdate: ['app_v1', 'resource'],
|
|
6210
|
+
resourceFiles: [
|
|
6211
|
+
{
|
|
6212
|
+
binary: resourceBundle,
|
|
6213
|
+
devicePath: 'vol0:/bundles/images/images.okpkg',
|
|
6130
6214
|
},
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6215
|
+
],
|
|
6216
|
+
};
|
|
6217
|
+
const firmwareSource = { size: 10 };
|
|
6218
|
+
const resourceSource = { size: resourceBundle.byteLength };
|
|
6219
|
+
(method as any).prepareProtocolV2InstallSources = jest.fn().mockResolvedValue([
|
|
6220
|
+
{
|
|
6221
|
+
fileName: 'application_p1.bin',
|
|
6222
|
+
source: firmwareSource,
|
|
6223
|
+
targetId: 4,
|
|
6224
|
+
kind: 'firmware',
|
|
6225
|
+
},
|
|
6226
|
+
]);
|
|
6227
|
+
(method as any).prepareProtocolV2ResourceSources = jest.fn();
|
|
6228
|
+
(method as any).openProtocolV2MemorySource = jest.fn().mockResolvedValue(resourceSource);
|
|
6229
|
+
(method as any).executeProtocolV2SourceUpdate = jest.fn().mockResolvedValue(undefined);
|
|
6230
|
+
(method as any).closeProtocolV2PreparedSources = jest.fn().mockResolvedValue(undefined);
|
|
6231
|
+
method.postTipMessage = jest.fn();
|
|
6148
6232
|
|
|
6149
|
-
|
|
6233
|
+
await (method as any).runProtocolV2PreparedArtifacts({ deviceType: 'pro2' }, 'universal');
|
|
6150
6234
|
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
|
|
6235
|
+
expect((method as any).prepareProtocolV2ResourceSources).not.toHaveBeenCalled();
|
|
6236
|
+
expect((method as any).executeProtocolV2SourceUpdate).toHaveBeenCalledWith({
|
|
6237
|
+
installSources: [
|
|
6238
|
+
{
|
|
6239
|
+
fileName: 'application_p1.bin',
|
|
6240
|
+
source: firmwareSource,
|
|
6241
|
+
targetId: 4,
|
|
6242
|
+
kind: 'firmware',
|
|
6243
|
+
},
|
|
6244
|
+
],
|
|
6245
|
+
resourceSources: [
|
|
6246
|
+
{
|
|
6247
|
+
name: 'images.okpkg',
|
|
6248
|
+
source: resourceSource,
|
|
6249
|
+
devicePath: 'vol0:/bundles/images/images.okpkg',
|
|
6250
|
+
version: [1, 2, 3],
|
|
6251
|
+
payloadHash: '11'.repeat(64),
|
|
6252
|
+
headerHash: '22'.repeat(64),
|
|
6253
|
+
},
|
|
6254
|
+
],
|
|
6255
|
+
});
|
|
6256
|
+
});
|
|
6166
6257
|
|
|
6167
6258
|
test('rejects manual RESC bundle paths before bootloader entry', async () => {
|
|
6168
6259
|
const method = new FirmwareUpdateV4({
|
|
@@ -7086,6 +7177,61 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
7086
7177
|
expect(Math.max(...readChunkLengths)).toBe(900);
|
|
7087
7178
|
});
|
|
7088
7179
|
|
|
7180
|
+
test('skips resource transfer when installed okpkg hashes match the downloaded package', async () => {
|
|
7181
|
+
const method = new FirmwareUpdateV4({
|
|
7182
|
+
id: 1,
|
|
7183
|
+
payload: {
|
|
7184
|
+
method: 'firmwareUpdateV4',
|
|
7185
|
+
platform: 'web',
|
|
7186
|
+
},
|
|
7187
|
+
});
|
|
7188
|
+
method.init();
|
|
7189
|
+
const installedBinary = new Uint8Array(createProtocolV2OkppBinary());
|
|
7190
|
+
const typedCall = jest.fn((requestType: string, _responseType: string, request: any) => {
|
|
7191
|
+
if (requestType === 'FilesystemPathInfoQuery') {
|
|
7192
|
+
return Promise.resolve({
|
|
7193
|
+
message: { exist: true, directory: false, size: installedBinary.byteLength },
|
|
7194
|
+
});
|
|
7195
|
+
}
|
|
7196
|
+
if (requestType === 'FilesystemFileRead') {
|
|
7197
|
+
return Promise.resolve({
|
|
7198
|
+
message: {
|
|
7199
|
+
data: installedBinary.slice(
|
|
7200
|
+
Number(request.file.offset),
|
|
7201
|
+
Number(request.file.offset) + Number(request.chunk_len)
|
|
7202
|
+
),
|
|
7203
|
+
},
|
|
7204
|
+
});
|
|
7205
|
+
}
|
|
7206
|
+
throw new Error(`Unexpected request: ${requestType}`);
|
|
7207
|
+
});
|
|
7208
|
+
(method as any).device = stubDevice({
|
|
7209
|
+
getCommands: () => ({ typedCall }),
|
|
7210
|
+
});
|
|
7211
|
+
method.postTipMessage = jest.fn();
|
|
7212
|
+
method.postProgressMessage = jest.fn();
|
|
7213
|
+
(method as any).protocolV2SourceUpdateProcess = jest.fn();
|
|
7214
|
+
|
|
7215
|
+
await (method as any).executeProtocolV2TransferPhase({
|
|
7216
|
+
installSources: [],
|
|
7217
|
+
resourceSources: [
|
|
7218
|
+
{
|
|
7219
|
+
name: 'images.okpkg',
|
|
7220
|
+
source: { size: installedBinary.byteLength },
|
|
7221
|
+
devicePath: 'vol0:/bundles/images/images.okpkg',
|
|
7222
|
+
version: [1, 2, 3],
|
|
7223
|
+
payloadHash: '11'.repeat(64),
|
|
7224
|
+
headerHash: '22'.repeat(64),
|
|
7225
|
+
},
|
|
7226
|
+
],
|
|
7227
|
+
});
|
|
7228
|
+
|
|
7229
|
+
expect(typedCall).toHaveBeenCalledWith('FilesystemPathInfoQuery', 'FilesystemPathInfo', {
|
|
7230
|
+
path: 'vol0:/bundles/images/images.okpkg',
|
|
7231
|
+
});
|
|
7232
|
+
expect((method as any).protocolV2SourceUpdateProcess).not.toHaveBeenCalled();
|
|
7233
|
+
});
|
|
7234
|
+
|
|
7089
7235
|
test('rejects a manually supplied resource file when its manifest hash does not match', () => {
|
|
7090
7236
|
const method = new FirmwareUpdateV4({
|
|
7091
7237
|
id: 1,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { EFirmwareType } from '@onekeyfe/hd-shared';
|
|
2
1
|
import { BaseMethod } from './BaseMethod';
|
|
2
|
+
import type { EFirmwareType } from '@onekeyfe/hd-shared';
|
|
3
3
|
import type { AllFirmwareRelease, ProtocolV2FirmwareComponentRelease, ProtocolV2FirmwareReleaseStatus } from '../types/api/checkAllFirmwareRelease';
|
|
4
4
|
import type { FirmwareUpdateV4Target } from '../types/api/firmwareUpdate';
|
|
5
5
|
import type { DeviceFeaturesVerify, DeviceStateVersions, IFirmwareReleaseInfo } from '../types';
|
|
6
|
-
type ProtocolV2FirmwareReleasePlan = {
|
|
6
|
+
export type ProtocolV2FirmwareReleasePlan = {
|
|
7
7
|
firmwareType: EFirmwareType;
|
|
8
8
|
status: ProtocolV2FirmwareReleaseStatus;
|
|
9
9
|
hasUpgrade: boolean;
|
|
@@ -28,5 +28,4 @@ export default class CheckAllFirmwareRelease extends BaseMethod {
|
|
|
28
28
|
run(): Promise<AllFirmwareRelease | null>;
|
|
29
29
|
private runProtocolV2;
|
|
30
30
|
}
|
|
31
|
-
export {};
|
|
32
31
|
//# sourceMappingURL=CheckAllFirmwareRelease.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckAllFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckAllFirmwareRelease.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CheckAllFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckAllFirmwareRelease.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA8B1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EACV,kBAAkB,EAElB,kCAAkC,EAClC,+BAA+B,EAChC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,UAAU,CAAC;AAgIlB,MAAM,MAAM,6BAA6B,GAAG;IAC1C,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,+BAA+B,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,mBAAmB,CAAC;IACrC,UAAU,EAAE,kCAAkC,EAAE,CAAC;IACjD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,mBAAwB,EACxB,iBAAyB,EACzB,mBAAwB,EACxB,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE;IACD,eAAe,EAAE,mBAAmB,CAAC;IACrC,mBAAmB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,YAAY,EAAE,aAAa,CAAC;IAC5B,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC7B,GAAG,6BAA6B,CAiFhC;AAID,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,qBAAqB;IAIrB,IAAI;IAME,GAAG;YAuFK,aAAa;CA+D5B"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BaseMethod } from './BaseMethod';
|
|
2
2
|
export default class CheckBLEFirmwareRelease extends BaseMethod {
|
|
3
|
+
getSupportedProtocols(): readonly ["V1", "V2"];
|
|
3
4
|
init(): void;
|
|
4
|
-
run(): Promise<
|
|
5
|
+
run(): Promise<import("..").FirmwareReleaseCheckResult | {
|
|
5
6
|
status: import("..").IDeviceBLEFirmwareStatus;
|
|
6
7
|
changelog: {
|
|
7
8
|
"zh-CN": string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckBLEFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckBLEFirmwareRelease.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CheckBLEFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckBLEFirmwareRelease.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAY1C,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,qBAAqB;IAIrB,IAAI;IAUE,GAAG;;;;;;;;;CA+BV"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BaseMethod } from './BaseMethod';
|
|
2
2
|
export default class CheckBootloaderRelease extends BaseMethod {
|
|
3
|
+
getSupportedProtocols(): readonly ["V1", "V2"];
|
|
3
4
|
init(): void;
|
|
4
|
-
run(): Promise<{
|
|
5
|
+
run(): Promise<import("..").FirmwareReleaseCheckResult | {
|
|
5
6
|
status: string;
|
|
6
7
|
changelog: ({
|
|
7
8
|
"zh-CN": string;
|
|
@@ -10,6 +11,6 @@ export default class CheckBootloaderRelease extends BaseMethod {
|
|
|
10
11
|
release: import("..").IFirmwareReleaseInfo | undefined;
|
|
11
12
|
bootloaderMode: boolean;
|
|
12
13
|
shouldUpdate: boolean;
|
|
13
|
-
}
|
|
14
|
+
}>;
|
|
14
15
|
}
|
|
15
16
|
//# sourceMappingURL=CheckBootloaderRelease.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckBootloaderRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckBootloaderRelease.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CheckBootloaderRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckBootloaderRelease.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAc1C,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,UAAU;IAC5D,qBAAqB;IAIrB,IAAI;IAME,GAAG;;;;;;;;;;CA0CV"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BaseMethod } from './BaseMethod';
|
|
2
2
|
export default class CheckFirmwareRelease extends BaseMethod {
|
|
3
|
+
getSupportedProtocols(): readonly ["V1", "V2"];
|
|
3
4
|
init(): void;
|
|
4
|
-
run(): Promise<
|
|
5
|
+
run(): Promise<import("..").FirmwareReleaseCheckResult | {
|
|
5
6
|
status: import("..").IDeviceFirmwareStatus;
|
|
6
7
|
changelog: {
|
|
7
8
|
"zh-CN": string;
|