@onekeyfe/hd-core 1.2.0-alpha.97 → 1.2.0-alpha.99
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 +411 -86
- package/__tests__/check-firmware-release-protocol-v2.test.ts +199 -0
- package/__tests__/firmware-memory-host.test.ts +126 -0
- package/__tests__/firmware-update/device-update-bootloader.test.ts +14 -2
- package/__tests__/firmware-update/firmware-host-binding.test.ts +9 -0
- package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +573 -0
- package/__tests__/firmware-update/firmware-prepared-resource-archive.test.ts +150 -0
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +65 -2
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +80 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +293 -71
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +53 -1
- package/__tests__/firmware-update/firmware-update-prepared-resource-executors.test.ts +326 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +2 -2
- package/__tests__/protocol-v2-firmware-targets.test.ts +16 -0
- package/__tests__/protocol-v2-resources.test.ts +148 -232
- package/__tests__/protocol-v2.test.ts +1326 -510
- package/dist/api/CheckAllFirmwareRelease.d.ts +2 -3
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBLEFirmwareRelease.d.ts +3 -2
- package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBootloaderRelease.d.ts +2 -1
- package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
- package/dist/api/CheckFirmwareRelease.d.ts +3 -2
- package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +1 -0
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +11 -9
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareHostBinding.d.ts +1 -1
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareMemoryHost.d.ts +22 -0
- package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +1 -0
- package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts +11 -0
- package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +48 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +7 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +0 -1
- package/dist/api/firmware/getBinary.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/data-manager/DataManager.d.ts +4 -3
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/index.d.ts +108 -114
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1825 -1006
- package/dist/protocols/protocol-v2/resources.d.ts +10 -28
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +20 -8
- 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/deviceUpdateBootloader.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 +4 -12
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdatePlan.d.ts +2 -2
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -1
- package/dist/types/settings.d.ts +35 -36
- package/dist/types/settings.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +113 -80
- package/src/api/CheckBLEFirmwareRelease.ts +37 -5
- package/src/api/CheckBootloaderRelease.ts +35 -3
- package/src/api/CheckFirmwareRelease.ts +35 -7
- package/src/api/FirmwareUpdateV2.ts +231 -138
- package/src/api/FirmwareUpdateV3.ts +101 -56
- package/src/api/FirmwareUpdateV4.ts +936 -408
- package/src/api/UploadPortfolio.ts +18 -0
- package/src/api/device/DeviceUpdateBootloader.ts +37 -11
- package/src/api/firmware/FirmwareHostBinding.ts +26 -3
- package/src/api/firmware/FirmwareMemoryHost.ts +143 -0
- package/src/api/firmware/FirmwarePreparedResourceArchive.ts +207 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +122 -73
- package/src/api/firmware/FirmwareUpdatePlan.ts +295 -122
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +49 -12
- package/src/api/firmware/protocolV2Release.ts +168 -0
- package/src/data-manager/DataManager.ts +35 -19
- package/src/index.ts +10 -0
- package/src/protocols/protocol-v2/resources.ts +157 -341
- package/src/types/api/checkAllFirmwareRelease.ts +27 -12
- 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/deviceUpdateBootloader.ts +1 -0
- package/src/types/api/export.ts +6 -1
- package/src/types/api/firmwareUpdate.ts +12 -17
- package/src/types/api/firmwareUpdatePlan.ts +2 -2
- package/src/types/settings.ts +35 -61
- package/src/utils/deviceFeaturesUtils.ts +2 -2
|
@@ -5,7 +5,6 @@ import CheckAllFirmwareRelease, {
|
|
|
5
5
|
} from '../src/api/CheckAllFirmwareRelease';
|
|
6
6
|
import { DataManager } from '../src/data-manager';
|
|
7
7
|
import { createCoreApi } from '../src/inject';
|
|
8
|
-
import { PROTOCOL_V2_RESOURCE_DEVICE_PATHS } from '../src/protocols/protocol-v2/resources';
|
|
9
8
|
|
|
10
9
|
import type { CoreApi } from '../src/types/api';
|
|
11
10
|
import type { DeviceStateVersions, IFirmwareReleaseInfo } from '../src/types';
|
|
@@ -26,6 +25,11 @@ const currentVersions: DeviceStateVersions = {
|
|
|
26
25
|
se04: '1.0.0',
|
|
27
26
|
};
|
|
28
27
|
|
|
28
|
+
const validComponentIntegrity = {
|
|
29
|
+
expectedSize: 1024,
|
|
30
|
+
fingerprint: '1'.repeat(64),
|
|
31
|
+
};
|
|
32
|
+
|
|
29
33
|
const release: IFirmwareReleaseInfo = {
|
|
30
34
|
required: true,
|
|
31
35
|
version: [2, 0, 0],
|
|
@@ -41,21 +45,25 @@ const release: IFirmwareReleaseInfo = {
|
|
|
41
45
|
target: 'BOOTLOADER',
|
|
42
46
|
url: 'https://example.com/bootloader.bin',
|
|
43
47
|
version: [1, 1, 0],
|
|
48
|
+
...validComponentIntegrity,
|
|
44
49
|
},
|
|
45
50
|
applicationP1: {
|
|
46
51
|
target: 'APPLICATION_P1',
|
|
47
52
|
url: 'https://example.com/application-p1.bin',
|
|
48
53
|
version: [2, 0, 0],
|
|
54
|
+
...validComponentIntegrity,
|
|
49
55
|
},
|
|
50
56
|
se02: {
|
|
51
57
|
target: 'SE02',
|
|
52
58
|
url: 'https://example.com/se02.bin',
|
|
53
59
|
version: [2, 0, 0],
|
|
60
|
+
...validComponentIntegrity,
|
|
54
61
|
},
|
|
55
62
|
se03: {
|
|
56
63
|
target: 'SE03',
|
|
57
64
|
url: 'https://example.com/se03.bin',
|
|
58
65
|
version: [1, 0, 0],
|
|
66
|
+
...validComponentIntegrity,
|
|
59
67
|
},
|
|
60
68
|
romloader: {
|
|
61
69
|
target: 'ROMLOADER',
|
|
@@ -63,77 +71,12 @@ const release: IFirmwareReleaseInfo = {
|
|
|
63
71
|
version: [2, 0, 0],
|
|
64
72
|
},
|
|
65
73
|
},
|
|
66
|
-
resourceBundles: [
|
|
67
|
-
{
|
|
68
|
-
name: 'images',
|
|
69
|
-
url: 'https://example.com/images.okpkg',
|
|
70
|
-
devicePath: 'vol0:/bundles/images/images.okpkg',
|
|
71
|
-
version: [1, 0, 0],
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
size: 0x52a0 + index + 1,
|
|
81
|
-
fileHash: 'a'.repeat(64),
|
|
82
|
-
headerHash: index.toString(16).padStart(128, '0'),
|
|
83
|
-
})
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
const createFilesystemTypedCall = (missingAll = false) => {
|
|
87
|
-
const resourceByPath = new Map(
|
|
88
|
-
stableResources.map(resource => [
|
|
89
|
-
PROTOCOL_V2_RESOURCE_DEVICE_PATHS[
|
|
90
|
-
resource.type as keyof typeof PROTOCOL_V2_RESOURCE_DEVICE_PATHS
|
|
91
|
-
],
|
|
92
|
-
resource,
|
|
93
|
-
])
|
|
94
|
-
);
|
|
95
|
-
return jest.fn((requestType: string, _responseType: string, payload: Record<string, any>) => {
|
|
96
|
-
if (requestType === 'ResourceInventoryGet') {
|
|
97
|
-
throw new Error('ResourceInventoryGet is unavailable on released firmware');
|
|
98
|
-
}
|
|
99
|
-
if (requestType === 'FilesystemPathInfoQuery') {
|
|
100
|
-
const resource = resourceByPath.get(payload.path);
|
|
101
|
-
return {
|
|
102
|
-
message: {
|
|
103
|
-
exist: Boolean(resource) && !missingAll,
|
|
104
|
-
directory: false,
|
|
105
|
-
size: missingAll ? 0 : resource?.size,
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
if (requestType === 'FilesystemFileRead') {
|
|
110
|
-
const resource = resourceByPath.get(payload.file.path);
|
|
111
|
-
if (!resource || missingAll) throw new Error('missing resource');
|
|
112
|
-
const header = new Uint8Array(0x52a0);
|
|
113
|
-
const view = new DataView(header.buffer);
|
|
114
|
-
'OKPP'.split('').forEach((char, index) => {
|
|
115
|
-
header[index] = char.charCodeAt(0);
|
|
116
|
-
});
|
|
117
|
-
'RESC'.split('').forEach((char, index) => {
|
|
118
|
-
header[0x08 + index] = char.charCodeAt(0);
|
|
119
|
-
});
|
|
120
|
-
view.setUint32(0x0c, header.byteLength, true);
|
|
121
|
-
for (let index = 0; index < resource.headerHash.length / 2; index++) {
|
|
122
|
-
header[0x240 + index] = Number.parseInt(
|
|
123
|
-
resource.headerHash.slice(index * 2, index * 2 + 2),
|
|
124
|
-
16
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
const offset = Number(payload.file.offset);
|
|
128
|
-
const chunkLength = Number(payload.chunk_len);
|
|
129
|
-
return {
|
|
130
|
-
message: {
|
|
131
|
-
data: header.slice(offset, offset + chunkLength),
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
throw new Error(`Unexpected request: ${requestType}`);
|
|
136
|
-
});
|
|
76
|
+
const resourceSource = {
|
|
77
|
+
archiveUrl: 'https://example.com/pro2-resource/pro2-resource.zip',
|
|
78
|
+
archiveSha256: 'a'.repeat(64),
|
|
79
|
+
archiveSize: 16_815_479,
|
|
137
80
|
};
|
|
138
81
|
|
|
139
82
|
describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
@@ -210,7 +153,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
210
153
|
test('detects same-version package hotfixes by P1 and P2 payload hash', () => {
|
|
211
154
|
const packageSet: IFirmwareReleaseInfo = {
|
|
212
155
|
...release,
|
|
213
|
-
resourceBundles: undefined,
|
|
214
156
|
installOrder: ['applicationP1', 'applicationP2'],
|
|
215
157
|
components: {
|
|
216
158
|
applicationP1: {
|
|
@@ -261,7 +203,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
261
203
|
const packageSet: IFirmwareReleaseInfo = {
|
|
262
204
|
...release,
|
|
263
205
|
required: false,
|
|
264
|
-
resourceBundles: undefined,
|
|
265
206
|
installOrder: ['applicationP1'],
|
|
266
207
|
components: {
|
|
267
208
|
applicationP1: {
|
|
@@ -292,7 +233,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
292
233
|
const packageSet: IFirmwareReleaseInfo = {
|
|
293
234
|
...release,
|
|
294
235
|
required: false,
|
|
295
|
-
resourceBundles: undefined,
|
|
296
236
|
installOrder: ['applicationP1'],
|
|
297
237
|
components: {
|
|
298
238
|
applicationP1: {
|
|
@@ -323,7 +263,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
323
263
|
test('updates both application packages when normal mode only reports P1', () => {
|
|
324
264
|
const packageSet: IFirmwareReleaseInfo = {
|
|
325
265
|
...release,
|
|
326
|
-
resourceBundles: undefined,
|
|
327
266
|
installOrder: ['applicationP1', 'applicationP2'],
|
|
328
267
|
components: {
|
|
329
268
|
applicationP1: {
|
|
@@ -370,7 +309,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
370
309
|
status: { mode: 'normal' },
|
|
371
310
|
versions: currentVersions,
|
|
372
311
|
});
|
|
373
|
-
const typedCall =
|
|
312
|
+
const typedCall = jest.fn();
|
|
374
313
|
method.device = {
|
|
375
314
|
isProtocolV2: () => true,
|
|
376
315
|
features: {
|
|
@@ -381,14 +320,25 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
381
320
|
getCommands: () => ({ typedCall }),
|
|
382
321
|
} as unknown as CheckAllFirmwareRelease['device'];
|
|
383
322
|
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
384
|
-
jest.spyOn(DataManager, '
|
|
323
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
385
324
|
|
|
386
325
|
await expect(method.run()).resolves.toMatchObject({
|
|
387
326
|
protocol: 'V2',
|
|
388
327
|
deviceType: 'pro2',
|
|
389
328
|
status: 'required',
|
|
390
329
|
resourceStatus: 'unknown',
|
|
391
|
-
|
|
330
|
+
resourceArchive: resourceSource,
|
|
331
|
+
targetsToUpdate: ['boot', 'app_v1', 'resource'],
|
|
332
|
+
firmwareUpdatePlan: {
|
|
333
|
+
executor: 'v4',
|
|
334
|
+
platform: 'web',
|
|
335
|
+
artifacts: [
|
|
336
|
+
{ artifactId: 'component:boot', target: 'boot' },
|
|
337
|
+
{ artifactId: 'component:app_v1', target: 'app_v1' },
|
|
338
|
+
{ artifactId: 'resource:archive', target: 'resource' },
|
|
339
|
+
],
|
|
340
|
+
targetsToUpdate: ['boot', 'app_v1', 'resource'],
|
|
341
|
+
},
|
|
392
342
|
firmware: {
|
|
393
343
|
status: 'required',
|
|
394
344
|
},
|
|
@@ -400,11 +350,341 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
400
350
|
expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
401
351
|
});
|
|
402
352
|
|
|
353
|
+
test('preserves platform and forced firmware targets in the Protocol V2 prepared plan', async () => {
|
|
354
|
+
const method = new CheckAllFirmwareRelease({
|
|
355
|
+
id: 1,
|
|
356
|
+
payload: {
|
|
357
|
+
method: 'checkAllFirmwareRelease',
|
|
358
|
+
firmwareType: EFirmwareType.Universal,
|
|
359
|
+
platform: 'native',
|
|
360
|
+
forceUpdateTargets: ['firmware'],
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
method.init();
|
|
364
|
+
method.device = {
|
|
365
|
+
isProtocolV2: () => true,
|
|
366
|
+
features: {
|
|
367
|
+
deviceType: 'pro2',
|
|
368
|
+
serialNo: 'pro2-device-id',
|
|
369
|
+
firmwareVersion: '1.0.0',
|
|
370
|
+
},
|
|
371
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
372
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
373
|
+
status: { mode: 'normal' },
|
|
374
|
+
versions: currentVersions,
|
|
375
|
+
}),
|
|
376
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
377
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
378
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
379
|
+
|
|
380
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
381
|
+
targetsToUpdate: ['boot', 'app_v1', 'se02', 'se03', 'resource'],
|
|
382
|
+
firmwareUpdatePlan: {
|
|
383
|
+
executor: 'v4',
|
|
384
|
+
deviceIdentity: 'pro2-device-id',
|
|
385
|
+
platform: 'native',
|
|
386
|
+
artifacts: [
|
|
387
|
+
{ artifactId: 'component:boot', target: 'boot' },
|
|
388
|
+
{ artifactId: 'component:app_v1', target: 'app_v1' },
|
|
389
|
+
{ artifactId: 'component:se02', target: 'se02' },
|
|
390
|
+
{ artifactId: 'component:se03', target: 'se03' },
|
|
391
|
+
{ artifactId: 'resource:archive', target: 'resource' },
|
|
392
|
+
],
|
|
393
|
+
targetsToUpdate: ['boot', 'app_v1', 'se02', 'se03', 'resource'],
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
test('includes exact Protocol V2 developer force targets in the prepared plan', async () => {
|
|
399
|
+
const currentRelease: IFirmwareReleaseInfo = {
|
|
400
|
+
...release,
|
|
401
|
+
required: false,
|
|
402
|
+
version: [1, 0, 0],
|
|
403
|
+
installOrder: ['applicationP1', 'coprocessor'],
|
|
404
|
+
components: {
|
|
405
|
+
applicationP1: {
|
|
406
|
+
target: 'APPLICATION_P1',
|
|
407
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
408
|
+
version: [1, 0, 0],
|
|
409
|
+
...validComponentIntegrity,
|
|
410
|
+
},
|
|
411
|
+
coprocessor: {
|
|
412
|
+
target: 'COPROCESSOR',
|
|
413
|
+
url: 'https://example.com/coprocessor.okpkg',
|
|
414
|
+
version: [1, 0, 0],
|
|
415
|
+
...validComponentIntegrity,
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
};
|
|
419
|
+
const method = new CheckAllFirmwareRelease({
|
|
420
|
+
id: 1,
|
|
421
|
+
payload: {
|
|
422
|
+
method: 'checkAllFirmwareRelease',
|
|
423
|
+
platform: 'desktop',
|
|
424
|
+
protocolV2ForceUpdateTargets: ['app_v1', 'coprocessor'],
|
|
425
|
+
},
|
|
426
|
+
});
|
|
427
|
+
method.init();
|
|
428
|
+
method.device = {
|
|
429
|
+
isProtocolV2: () => true,
|
|
430
|
+
features: {
|
|
431
|
+
deviceType: 'pro2',
|
|
432
|
+
serialNo: 'pro2-device-id',
|
|
433
|
+
firmwareVersion: '1.0.0',
|
|
434
|
+
},
|
|
435
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
436
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
437
|
+
status: { mode: 'normal' },
|
|
438
|
+
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
439
|
+
}),
|
|
440
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
441
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
442
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
443
|
+
|
|
444
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
445
|
+
targetsToUpdate: ['app_v1', 'coprocessor'],
|
|
446
|
+
firmwareUpdatePlan: {
|
|
447
|
+
executor: 'v4',
|
|
448
|
+
platform: 'desktop',
|
|
449
|
+
artifacts: [
|
|
450
|
+
{ artifactId: 'component:app_v1', target: 'app_v1' },
|
|
451
|
+
{ artifactId: 'component:coprocessor', target: 'coprocessor' },
|
|
452
|
+
],
|
|
453
|
+
targetsToUpdate: ['app_v1', 'coprocessor'],
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
test('builds a Desktop V4 prepared update without device identity', async () => {
|
|
459
|
+
const currentRelease: IFirmwareReleaseInfo = {
|
|
460
|
+
...release,
|
|
461
|
+
required: false,
|
|
462
|
+
version: [1, 0, 0],
|
|
463
|
+
installOrder: ['applicationP1'],
|
|
464
|
+
components: {
|
|
465
|
+
applicationP1: {
|
|
466
|
+
target: 'APPLICATION_P1',
|
|
467
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
468
|
+
version: [1, 0, 0],
|
|
469
|
+
...validComponentIntegrity,
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
};
|
|
473
|
+
const method = new CheckAllFirmwareRelease({
|
|
474
|
+
id: 1,
|
|
475
|
+
payload: {
|
|
476
|
+
method: 'checkAllFirmwareRelease',
|
|
477
|
+
platform: 'desktop',
|
|
478
|
+
protocolV2ForceUpdateTargets: ['app_v1'],
|
|
479
|
+
},
|
|
480
|
+
});
|
|
481
|
+
method.init();
|
|
482
|
+
method.device = {
|
|
483
|
+
isProtocolV2: () => true,
|
|
484
|
+
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
485
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
486
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
487
|
+
status: { mode: 'normal' },
|
|
488
|
+
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
489
|
+
}),
|
|
490
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
491
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
492
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
493
|
+
|
|
494
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
495
|
+
firmwareUpdatePlan: {
|
|
496
|
+
executor: 'v4',
|
|
497
|
+
deviceIdentity: 'unavailable',
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
test('rejects Neo-only unsupported exact secure-element targets', async () => {
|
|
503
|
+
const neoRelease: IFirmwareReleaseInfo = {
|
|
504
|
+
...release,
|
|
505
|
+
required: false,
|
|
506
|
+
installOrder: ['se03'],
|
|
507
|
+
components: {
|
|
508
|
+
se03: {
|
|
509
|
+
target: 'SE03',
|
|
510
|
+
url: 'https://example.com/se03.okpkg',
|
|
511
|
+
version: [1, 0, 0],
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
};
|
|
515
|
+
const method = new CheckAllFirmwareRelease({
|
|
516
|
+
id: 1,
|
|
517
|
+
payload: {
|
|
518
|
+
method: 'checkAllFirmwareRelease',
|
|
519
|
+
protocolV2ForceUpdateTargets: ['se03'],
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
method.init();
|
|
523
|
+
method.device = {
|
|
524
|
+
isProtocolV2: () => true,
|
|
525
|
+
features: { deviceType: 'neo', firmwareVersion: '1.0.0' },
|
|
526
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
527
|
+
identity: { deviceType: 'neo', firmwareType: EFirmwareType.Universal },
|
|
528
|
+
status: { mode: 'normal' },
|
|
529
|
+
versions: currentVersions,
|
|
530
|
+
}),
|
|
531
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
532
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(neoRelease);
|
|
533
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
534
|
+
|
|
535
|
+
await expect(method.run()).rejects.toMatchObject({
|
|
536
|
+
params: { firmwareUpdateCode: 'FirmwarePlanInvalid' },
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
test('builds a V4 plan for Neo and excludes unsupported secure elements when forced', async () => {
|
|
541
|
+
const neoRelease: IFirmwareReleaseInfo = {
|
|
542
|
+
...release,
|
|
543
|
+
installOrder: ['se01', 'se02', 'se03', 'se04'],
|
|
544
|
+
components: {
|
|
545
|
+
se01: {
|
|
546
|
+
target: 'SE01',
|
|
547
|
+
url: 'https://example.com/se01.bin',
|
|
548
|
+
version: [1, 0, 0],
|
|
549
|
+
...validComponentIntegrity,
|
|
550
|
+
},
|
|
551
|
+
se02: {
|
|
552
|
+
target: 'SE02',
|
|
553
|
+
url: 'https://example.com/se02.bin',
|
|
554
|
+
version: [2, 0, 0],
|
|
555
|
+
...validComponentIntegrity,
|
|
556
|
+
},
|
|
557
|
+
se03: { target: 'SE03', url: 'https://example.com/se03.bin', version: [1, 0, 0] },
|
|
558
|
+
se04: { target: 'SE04', url: 'https://example.com/se04.bin', version: [1, 0, 0] },
|
|
559
|
+
},
|
|
560
|
+
};
|
|
561
|
+
const method = new CheckAllFirmwareRelease({
|
|
562
|
+
id: 1,
|
|
563
|
+
payload: {
|
|
564
|
+
method: 'checkAllFirmwareRelease',
|
|
565
|
+
platform: 'native',
|
|
566
|
+
forceUpdateTargets: ['firmware'],
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
method.init();
|
|
570
|
+
method.device = {
|
|
571
|
+
isProtocolV2: () => true,
|
|
572
|
+
features: {
|
|
573
|
+
deviceType: 'neo',
|
|
574
|
+
serialNo: 'neo-device-id',
|
|
575
|
+
firmwareVersion: '1.0.0',
|
|
576
|
+
},
|
|
577
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
578
|
+
identity: { deviceType: 'neo', firmwareType: EFirmwareType.Universal },
|
|
579
|
+
status: { mode: 'normal' },
|
|
580
|
+
versions: currentVersions,
|
|
581
|
+
}),
|
|
582
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
583
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(neoRelease);
|
|
584
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
585
|
+
|
|
586
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
587
|
+
targetsToUpdate: ['se01', 'se02', 'resource'],
|
|
588
|
+
firmwareUpdatePlan: {
|
|
589
|
+
executor: 'v4',
|
|
590
|
+
deviceModel: 'neo',
|
|
591
|
+
platform: 'native',
|
|
592
|
+
targetsToUpdate: ['se01', 'se02', 'resource'],
|
|
593
|
+
},
|
|
594
|
+
});
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
test('rejects a forced Protocol V2 resource target without a configured archive', async () => {
|
|
598
|
+
const method = new CheckAllFirmwareRelease({
|
|
599
|
+
id: 1,
|
|
600
|
+
payload: {
|
|
601
|
+
method: 'checkAllFirmwareRelease',
|
|
602
|
+
forceUpdateTargets: ['resource'],
|
|
603
|
+
},
|
|
604
|
+
});
|
|
605
|
+
method.init();
|
|
606
|
+
method.device = {
|
|
607
|
+
isProtocolV2: () => true,
|
|
608
|
+
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
609
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
610
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
611
|
+
status: { mode: 'normal' },
|
|
612
|
+
versions: currentVersions,
|
|
613
|
+
}),
|
|
614
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
615
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
616
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(undefined);
|
|
617
|
+
|
|
618
|
+
await expect(method.run()).rejects.toMatchObject({
|
|
619
|
+
params: { firmwareUpdateCode: 'FirmwarePlanInvalid' },
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test.each(['resource', 'boot_resources'] as const)(
|
|
624
|
+
'allows an explicitly forced Protocol V2 resource-only target through %s',
|
|
625
|
+
async forceTarget => {
|
|
626
|
+
const currentRelease: IFirmwareReleaseInfo = {
|
|
627
|
+
...release,
|
|
628
|
+
required: false,
|
|
629
|
+
installOrder: ['applicationP1'],
|
|
630
|
+
components: {
|
|
631
|
+
applicationP1: {
|
|
632
|
+
target: 'APPLICATION_P1',
|
|
633
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
634
|
+
version: [1, 0, 0],
|
|
635
|
+
},
|
|
636
|
+
},
|
|
637
|
+
};
|
|
638
|
+
const method = new CheckAllFirmwareRelease({
|
|
639
|
+
id: 1,
|
|
640
|
+
payload: {
|
|
641
|
+
method: 'checkAllFirmwareRelease',
|
|
642
|
+
platform: 'desktop',
|
|
643
|
+
protocolV2ForceUpdateTargets: [forceTarget],
|
|
644
|
+
},
|
|
645
|
+
});
|
|
646
|
+
method.init();
|
|
647
|
+
method.device = {
|
|
648
|
+
isProtocolV2: () => true,
|
|
649
|
+
features: {
|
|
650
|
+
deviceType: 'pro2',
|
|
651
|
+
serialNo: 'pro2-device-id',
|
|
652
|
+
firmwareVersion: '1.0.0',
|
|
653
|
+
},
|
|
654
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
655
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
656
|
+
status: { mode: 'normal' },
|
|
657
|
+
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
658
|
+
}),
|
|
659
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
660
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
661
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
662
|
+
|
|
663
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
664
|
+
status: 'valid',
|
|
665
|
+
hasUpgrade: true,
|
|
666
|
+
targetsToUpdate: ['resource'],
|
|
667
|
+
firmwareUpdatePlan: {
|
|
668
|
+
executor: 'v4',
|
|
669
|
+
platform: 'desktop',
|
|
670
|
+
artifacts: [
|
|
671
|
+
{
|
|
672
|
+
artifactId: 'resource:archive',
|
|
673
|
+
target: 'resource',
|
|
674
|
+
role: 'resourceBundle',
|
|
675
|
+
container: 'zip',
|
|
676
|
+
},
|
|
677
|
+
],
|
|
678
|
+
targetsToUpdate: ['resource'],
|
|
679
|
+
},
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
);
|
|
683
|
+
|
|
403
684
|
test('requests and compares firmware hashes only when explicitly enabled', async () => {
|
|
404
685
|
const packageSet: IFirmwareReleaseInfo = {
|
|
405
686
|
...release,
|
|
406
687
|
required: false,
|
|
407
|
-
resourceBundles: undefined,
|
|
408
688
|
installOrder: ['applicationP1'],
|
|
409
689
|
components: {
|
|
410
690
|
applicationP1: {
|
|
@@ -437,7 +717,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
437
717
|
getCommands: () => ({ typedCall: jest.fn() }),
|
|
438
718
|
} as unknown as CheckAllFirmwareRelease['device'];
|
|
439
719
|
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(packageSet);
|
|
440
|
-
jest.spyOn(DataManager, '
|
|
720
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(undefined);
|
|
441
721
|
|
|
442
722
|
await expect(method.run()).resolves.toMatchObject({
|
|
443
723
|
status: 'outdated',
|
|
@@ -449,7 +729,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
449
729
|
});
|
|
450
730
|
|
|
451
731
|
test.each(['bootloader', 'romloader'] as const)(
|
|
452
|
-
'
|
|
732
|
+
'does not read vol0 resource inventory in %s mode',
|
|
453
733
|
async mode => {
|
|
454
734
|
const method = new CheckAllFirmwareRelease({
|
|
455
735
|
id: 1,
|
|
@@ -459,7 +739,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
459
739
|
},
|
|
460
740
|
});
|
|
461
741
|
method.init();
|
|
462
|
-
const typedCall =
|
|
742
|
+
const typedCall = jest.fn();
|
|
463
743
|
method.device = {
|
|
464
744
|
isProtocolV2: () => true,
|
|
465
745
|
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
@@ -471,18 +751,61 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
471
751
|
getCommands: () => ({ typedCall }),
|
|
472
752
|
} as unknown as CheckAllFirmwareRelease['device'];
|
|
473
753
|
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
474
|
-
jest.spyOn(DataManager, '
|
|
754
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
475
755
|
|
|
476
756
|
await expect(method.run()).resolves.toMatchObject({
|
|
477
757
|
protocol: 'V2',
|
|
478
|
-
resourceStatus: '
|
|
479
|
-
|
|
758
|
+
resourceStatus: 'unknown',
|
|
759
|
+
resourceArchive: resourceSource,
|
|
760
|
+
targetsToUpdate: ['boot', 'app_v1', 'resource'],
|
|
480
761
|
});
|
|
481
|
-
expect(typedCall.
|
|
482
|
-
expect(typedCall.mock.calls.some(call => call[0] === 'FilesystemFileRead')).toBe(true);
|
|
762
|
+
expect(typedCall).not.toHaveBeenCalled();
|
|
483
763
|
}
|
|
484
764
|
);
|
|
485
765
|
|
|
766
|
+
test('exposes resource archive availability without reporting an unconfirmed update', async () => {
|
|
767
|
+
const currentRelease: IFirmwareReleaseInfo = {
|
|
768
|
+
...release,
|
|
769
|
+
required: false,
|
|
770
|
+
installOrder: ['applicationP1'],
|
|
771
|
+
components: {
|
|
772
|
+
applicationP1: {
|
|
773
|
+
target: 'APPLICATION_P1',
|
|
774
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
775
|
+
version: [1, 0, 0],
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
};
|
|
779
|
+
const method = new CheckAllFirmwareRelease({
|
|
780
|
+
id: 1,
|
|
781
|
+
payload: {
|
|
782
|
+
method: 'checkAllFirmwareRelease',
|
|
783
|
+
firmwareType: EFirmwareType.Universal,
|
|
784
|
+
},
|
|
785
|
+
});
|
|
786
|
+
method.init();
|
|
787
|
+
method.device = {
|
|
788
|
+
isProtocolV2: () => true,
|
|
789
|
+
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
790
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
791
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
792
|
+
status: { mode: 'normal' },
|
|
793
|
+
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
794
|
+
}),
|
|
795
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
796
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
797
|
+
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
798
|
+
|
|
799
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
800
|
+
status: 'valid',
|
|
801
|
+
hasUpgrade: false,
|
|
802
|
+
resourceStatus: 'unknown',
|
|
803
|
+
resourceArchive: resourceSource,
|
|
804
|
+
targetsToUpdate: [],
|
|
805
|
+
firmwareUpdatePlan: undefined,
|
|
806
|
+
});
|
|
807
|
+
});
|
|
808
|
+
|
|
486
809
|
test('continues forwarding the existing public method', async () => {
|
|
487
810
|
const call = jest.fn().mockResolvedValue({ success: true, payload: {} });
|
|
488
811
|
const api = createCoreApi(call as CoreApi['call']) as CoreApi;
|
|
@@ -490,6 +813,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
490
813
|
await api.checkAllFirmwareRelease('pro2-connect-id', {
|
|
491
814
|
checkFirmwareHash: true,
|
|
492
815
|
firmwareType: EFirmwareType.Universal,
|
|
816
|
+
protocolV2ForceUpdateTargets: ['app_v1'],
|
|
493
817
|
retryCount: 0,
|
|
494
818
|
});
|
|
495
819
|
|
|
@@ -497,6 +821,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
497
821
|
connectId: 'pro2-connect-id',
|
|
498
822
|
checkFirmwareHash: true,
|
|
499
823
|
firmwareType: EFirmwareType.Universal,
|
|
824
|
+
protocolV2ForceUpdateTargets: ['app_v1'],
|
|
500
825
|
retryCount: 0,
|
|
501
826
|
method: 'checkAllFirmwareRelease',
|
|
502
827
|
});
|