@onekeyfe/hd-core 1.2.0-alpha.95 → 1.2.0-alpha.97
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 +84 -404
- package/__tests__/firmware-update/device-update-bootloader.test.ts +2 -6
- package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -9
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +112 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +70 -131
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +1 -53
- package/__tests__/protocol-v2-resources.test.ts +232 -148
- package/__tests__/protocol-v2.test.ts +517 -1106
- package/dist/api/CheckAllFirmwareRelease.d.ts +3 -2
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBLEFirmwareRelease.d.ts +2 -3
- package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBootloaderRelease.d.ts +1 -2
- package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
- package/dist/api/CheckFirmwareRelease.d.ts +2 -3
- package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +0 -1
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +8 -6
- 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/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +1 -48
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +1 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +3 -4
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/index.d.ts +111 -103
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +849 -1301
- package/dist/protocols/protocol-v2/resources.d.ts +28 -10
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +8 -20
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkBLEFirmwareRelease.d.ts +13 -2
- package/dist/types/api/checkBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkBootloaderRelease.d.ts +6 -2
- package/dist/types/api/checkBootloaderRelease.d.ts.map +1 -1
- package/dist/types/api/checkFirmwareRelease.d.ts +13 -2
- 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 +11 -3
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/settings.d.ts +36 -35
- package/dist/types/settings.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +80 -108
- package/src/api/CheckBLEFirmwareRelease.ts +5 -37
- package/src/api/CheckBootloaderRelease.ts +3 -35
- package/src/api/CheckFirmwareRelease.ts +7 -35
- package/src/api/FirmwareUpdateV2.ts +3 -15
- package/src/api/FirmwareUpdateV3.ts +6 -13
- package/src/api/FirmwareUpdateV4.ts +407 -824
- package/src/api/UploadPortfolio.ts +0 -18
- package/src/api/device/DeviceUpdateBootloader.ts +5 -26
- package/src/api/firmware/FirmwareHostBinding.ts +3 -16
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +2 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +88 -226
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +3 -10
- package/src/data-manager/DataManager.ts +19 -35
- package/src/index.ts +0 -10
- package/src/protocols/protocol-v2/resources.ts +341 -157
- package/src/types/api/checkAllFirmwareRelease.ts +12 -27
- package/src/types/api/checkBLEFirmwareRelease.ts +13 -4
- package/src/types/api/checkBootloaderRelease.ts +6 -2
- package/src/types/api/checkFirmwareRelease.ts +13 -2
- package/src/types/api/checkFirmwareTypeAvailable.ts +2 -2
- package/src/types/api/export.ts +1 -6
- package/src/types/api/firmwareUpdate.ts +16 -10
- package/src/types/settings.ts +61 -35
- package/src/utils/deviceFeaturesUtils.ts +2 -2
- package/__tests__/check-firmware-release-protocol-v2.test.ts +0 -199
- package/__tests__/firmware-memory-host.test.ts +0 -112
- package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +0 -448
- package/dist/api/firmware/FirmwareMemoryHost.d.ts +0 -22
- package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +0 -1
- package/dist/api/firmware/protocolV2Release.d.ts +0 -33
- package/dist/api/firmware/protocolV2Release.d.ts.map +0 -1
- package/src/api/firmware/FirmwareMemoryHost.ts +0 -142
- package/src/api/firmware/protocolV2Release.ts +0 -168
|
@@ -5,6 +5,7 @@ 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';
|
|
8
9
|
|
|
9
10
|
import type { CoreApi } from '../src/types/api';
|
|
10
11
|
import type { DeviceStateVersions, IFirmwareReleaseInfo } from '../src/types';
|
|
@@ -25,11 +26,6 @@ const currentVersions: DeviceStateVersions = {
|
|
|
25
26
|
se04: '1.0.0',
|
|
26
27
|
};
|
|
27
28
|
|
|
28
|
-
const validComponentIntegrity = {
|
|
29
|
-
expectedSize: 1024,
|
|
30
|
-
fingerprint: '1'.repeat(64),
|
|
31
|
-
};
|
|
32
|
-
|
|
33
29
|
const release: IFirmwareReleaseInfo = {
|
|
34
30
|
required: true,
|
|
35
31
|
version: [2, 0, 0],
|
|
@@ -45,25 +41,21 @@ const release: IFirmwareReleaseInfo = {
|
|
|
45
41
|
target: 'BOOTLOADER',
|
|
46
42
|
url: 'https://example.com/bootloader.bin',
|
|
47
43
|
version: [1, 1, 0],
|
|
48
|
-
...validComponentIntegrity,
|
|
49
44
|
},
|
|
50
45
|
applicationP1: {
|
|
51
46
|
target: 'APPLICATION_P1',
|
|
52
47
|
url: 'https://example.com/application-p1.bin',
|
|
53
48
|
version: [2, 0, 0],
|
|
54
|
-
...validComponentIntegrity,
|
|
55
49
|
},
|
|
56
50
|
se02: {
|
|
57
51
|
target: 'SE02',
|
|
58
52
|
url: 'https://example.com/se02.bin',
|
|
59
53
|
version: [2, 0, 0],
|
|
60
|
-
...validComponentIntegrity,
|
|
61
54
|
},
|
|
62
55
|
se03: {
|
|
63
56
|
target: 'SE03',
|
|
64
57
|
url: 'https://example.com/se03.bin',
|
|
65
58
|
version: [1, 0, 0],
|
|
66
|
-
...validComponentIntegrity,
|
|
67
59
|
},
|
|
68
60
|
romloader: {
|
|
69
61
|
target: 'ROMLOADER',
|
|
@@ -71,12 +63,77 @@ const release: IFirmwareReleaseInfo = {
|
|
|
71
63
|
version: [2, 0, 0],
|
|
72
64
|
},
|
|
73
65
|
},
|
|
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
|
-
|
|
76
|
+
const stableResources = ['images', 'animation', 'wallpaper', 'translations', 'roobert', 'noto'].map(
|
|
77
|
+
(type, index) => ({
|
|
78
|
+
type,
|
|
79
|
+
url: `https://example.com/${type}.okpkg`,
|
|
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
|
+
});
|
|
80
137
|
};
|
|
81
138
|
|
|
82
139
|
describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
@@ -153,6 +210,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
153
210
|
test('detects same-version package hotfixes by P1 and P2 payload hash', () => {
|
|
154
211
|
const packageSet: IFirmwareReleaseInfo = {
|
|
155
212
|
...release,
|
|
213
|
+
resourceBundles: undefined,
|
|
156
214
|
installOrder: ['applicationP1', 'applicationP2'],
|
|
157
215
|
components: {
|
|
158
216
|
applicationP1: {
|
|
@@ -203,6 +261,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
203
261
|
const packageSet: IFirmwareReleaseInfo = {
|
|
204
262
|
...release,
|
|
205
263
|
required: false,
|
|
264
|
+
resourceBundles: undefined,
|
|
206
265
|
installOrder: ['applicationP1'],
|
|
207
266
|
components: {
|
|
208
267
|
applicationP1: {
|
|
@@ -233,6 +292,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
233
292
|
const packageSet: IFirmwareReleaseInfo = {
|
|
234
293
|
...release,
|
|
235
294
|
required: false,
|
|
295
|
+
resourceBundles: undefined,
|
|
236
296
|
installOrder: ['applicationP1'],
|
|
237
297
|
components: {
|
|
238
298
|
applicationP1: {
|
|
@@ -263,6 +323,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
263
323
|
test('updates both application packages when normal mode only reports P1', () => {
|
|
264
324
|
const packageSet: IFirmwareReleaseInfo = {
|
|
265
325
|
...release,
|
|
326
|
+
resourceBundles: undefined,
|
|
266
327
|
installOrder: ['applicationP1', 'applicationP2'],
|
|
267
328
|
components: {
|
|
268
329
|
applicationP1: {
|
|
@@ -309,7 +370,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
309
370
|
status: { mode: 'normal' },
|
|
310
371
|
versions: currentVersions,
|
|
311
372
|
});
|
|
312
|
-
const typedCall =
|
|
373
|
+
const typedCall = createFilesystemTypedCall(true);
|
|
313
374
|
method.device = {
|
|
314
375
|
isProtocolV2: () => true,
|
|
315
376
|
features: {
|
|
@@ -320,24 +381,14 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
320
381
|
getCommands: () => ({ typedCall }),
|
|
321
382
|
} as unknown as CheckAllFirmwareRelease['device'];
|
|
322
383
|
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
323
|
-
jest.spyOn(DataManager, '
|
|
384
|
+
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
|
|
324
385
|
|
|
325
386
|
await expect(method.run()).resolves.toMatchObject({
|
|
326
387
|
protocol: 'V2',
|
|
327
388
|
deviceType: 'pro2',
|
|
328
389
|
status: 'required',
|
|
329
390
|
resourceStatus: 'unknown',
|
|
330
|
-
resourceArchive: resourceSource,
|
|
331
391
|
targetsToUpdate: ['boot', 'app_v1'],
|
|
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
|
-
],
|
|
339
|
-
targetsToUpdate: ['boot', 'app_v1'],
|
|
340
|
-
},
|
|
341
392
|
firmware: {
|
|
342
393
|
status: 'required',
|
|
343
394
|
},
|
|
@@ -349,337 +400,11 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
349
400
|
expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
350
401
|
});
|
|
351
402
|
|
|
352
|
-
test('preserves platform and forced firmware targets in the Protocol V2 prepared plan', async () => {
|
|
353
|
-
const method = new CheckAllFirmwareRelease({
|
|
354
|
-
id: 1,
|
|
355
|
-
payload: {
|
|
356
|
-
method: 'checkAllFirmwareRelease',
|
|
357
|
-
firmwareType: EFirmwareType.Universal,
|
|
358
|
-
platform: 'native',
|
|
359
|
-
forceUpdateTargets: ['firmware'],
|
|
360
|
-
},
|
|
361
|
-
});
|
|
362
|
-
method.init();
|
|
363
|
-
method.device = {
|
|
364
|
-
isProtocolV2: () => true,
|
|
365
|
-
features: {
|
|
366
|
-
deviceType: 'pro2',
|
|
367
|
-
serialNo: 'pro2-device-id',
|
|
368
|
-
firmwareVersion: '1.0.0',
|
|
369
|
-
},
|
|
370
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
371
|
-
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
372
|
-
status: { mode: 'normal' },
|
|
373
|
-
versions: currentVersions,
|
|
374
|
-
}),
|
|
375
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
376
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
377
|
-
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
378
|
-
|
|
379
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
380
|
-
targetsToUpdate: ['boot', 'app_v1', 'se02', 'se03'],
|
|
381
|
-
firmwareUpdatePlan: {
|
|
382
|
-
executor: 'v4',
|
|
383
|
-
deviceIdentity: 'pro2-device-id',
|
|
384
|
-
platform: 'native',
|
|
385
|
-
artifacts: [
|
|
386
|
-
{ artifactId: 'component:boot', target: 'boot' },
|
|
387
|
-
{ artifactId: 'component:app_v1', target: 'app_v1' },
|
|
388
|
-
{ artifactId: 'component:se02', target: 'se02' },
|
|
389
|
-
{ artifactId: 'component:se03', target: 'se03' },
|
|
390
|
-
],
|
|
391
|
-
targetsToUpdate: ['boot', 'app_v1', 'se02', 'se03'],
|
|
392
|
-
},
|
|
393
|
-
});
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
test('includes exact Protocol V2 developer force targets in the prepared plan', async () => {
|
|
397
|
-
const currentRelease: IFirmwareReleaseInfo = {
|
|
398
|
-
...release,
|
|
399
|
-
required: false,
|
|
400
|
-
version: [1, 0, 0],
|
|
401
|
-
installOrder: ['applicationP1', 'coprocessor'],
|
|
402
|
-
components: {
|
|
403
|
-
applicationP1: {
|
|
404
|
-
target: 'APPLICATION_P1',
|
|
405
|
-
url: 'https://example.com/application-p1.okpkg',
|
|
406
|
-
version: [1, 0, 0],
|
|
407
|
-
...validComponentIntegrity,
|
|
408
|
-
},
|
|
409
|
-
coprocessor: {
|
|
410
|
-
target: 'COPROCESSOR',
|
|
411
|
-
url: 'https://example.com/coprocessor.okpkg',
|
|
412
|
-
version: [1, 0, 0],
|
|
413
|
-
...validComponentIntegrity,
|
|
414
|
-
},
|
|
415
|
-
},
|
|
416
|
-
};
|
|
417
|
-
const method = new CheckAllFirmwareRelease({
|
|
418
|
-
id: 1,
|
|
419
|
-
payload: {
|
|
420
|
-
method: 'checkAllFirmwareRelease',
|
|
421
|
-
platform: 'desktop',
|
|
422
|
-
protocolV2ForceUpdateTargets: ['app_v1', 'coprocessor'],
|
|
423
|
-
},
|
|
424
|
-
});
|
|
425
|
-
method.init();
|
|
426
|
-
method.device = {
|
|
427
|
-
isProtocolV2: () => true,
|
|
428
|
-
features: {
|
|
429
|
-
deviceType: 'pro2',
|
|
430
|
-
serialNo: 'pro2-device-id',
|
|
431
|
-
firmwareVersion: '1.0.0',
|
|
432
|
-
},
|
|
433
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
434
|
-
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
435
|
-
status: { mode: 'normal' },
|
|
436
|
-
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
437
|
-
}),
|
|
438
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
439
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
440
|
-
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
441
|
-
|
|
442
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
443
|
-
targetsToUpdate: ['app_v1', 'coprocessor'],
|
|
444
|
-
firmwareUpdatePlan: {
|
|
445
|
-
executor: 'v4',
|
|
446
|
-
platform: 'desktop',
|
|
447
|
-
artifacts: [
|
|
448
|
-
{ artifactId: 'component:app_v1', target: 'app_v1' },
|
|
449
|
-
{ artifactId: 'component:coprocessor', target: 'coprocessor' },
|
|
450
|
-
],
|
|
451
|
-
targetsToUpdate: ['app_v1', 'coprocessor'],
|
|
452
|
-
},
|
|
453
|
-
});
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
test('builds a Desktop V4 prepared update without device identity', async () => {
|
|
457
|
-
const currentRelease: IFirmwareReleaseInfo = {
|
|
458
|
-
...release,
|
|
459
|
-
required: false,
|
|
460
|
-
version: [1, 0, 0],
|
|
461
|
-
installOrder: ['applicationP1'],
|
|
462
|
-
components: {
|
|
463
|
-
applicationP1: {
|
|
464
|
-
target: 'APPLICATION_P1',
|
|
465
|
-
url: 'https://example.com/application-p1.okpkg',
|
|
466
|
-
version: [1, 0, 0],
|
|
467
|
-
...validComponentIntegrity,
|
|
468
|
-
},
|
|
469
|
-
},
|
|
470
|
-
};
|
|
471
|
-
const method = new CheckAllFirmwareRelease({
|
|
472
|
-
id: 1,
|
|
473
|
-
payload: {
|
|
474
|
-
method: 'checkAllFirmwareRelease',
|
|
475
|
-
platform: 'desktop',
|
|
476
|
-
protocolV2ForceUpdateTargets: ['app_v1'],
|
|
477
|
-
},
|
|
478
|
-
});
|
|
479
|
-
method.init();
|
|
480
|
-
method.device = {
|
|
481
|
-
isProtocolV2: () => true,
|
|
482
|
-
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
483
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
484
|
-
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
485
|
-
status: { mode: 'normal' },
|
|
486
|
-
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
487
|
-
}),
|
|
488
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
489
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
490
|
-
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
491
|
-
|
|
492
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
493
|
-
firmwareUpdatePlan: {
|
|
494
|
-
executor: 'v4',
|
|
495
|
-
deviceIdentity: 'unavailable',
|
|
496
|
-
},
|
|
497
|
-
});
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
test('rejects Neo-only unsupported exact secure-element targets', async () => {
|
|
501
|
-
const neoRelease: IFirmwareReleaseInfo = {
|
|
502
|
-
...release,
|
|
503
|
-
required: false,
|
|
504
|
-
installOrder: ['se03'],
|
|
505
|
-
components: {
|
|
506
|
-
se03: {
|
|
507
|
-
target: 'SE03',
|
|
508
|
-
url: 'https://example.com/se03.okpkg',
|
|
509
|
-
version: [1, 0, 0],
|
|
510
|
-
},
|
|
511
|
-
},
|
|
512
|
-
};
|
|
513
|
-
const method = new CheckAllFirmwareRelease({
|
|
514
|
-
id: 1,
|
|
515
|
-
payload: {
|
|
516
|
-
method: 'checkAllFirmwareRelease',
|
|
517
|
-
protocolV2ForceUpdateTargets: ['se03'],
|
|
518
|
-
},
|
|
519
|
-
});
|
|
520
|
-
method.init();
|
|
521
|
-
method.device = {
|
|
522
|
-
isProtocolV2: () => true,
|
|
523
|
-
features: { deviceType: 'neo', firmwareVersion: '1.0.0' },
|
|
524
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
525
|
-
identity: { deviceType: 'neo', firmwareType: EFirmwareType.Universal },
|
|
526
|
-
status: { mode: 'normal' },
|
|
527
|
-
versions: currentVersions,
|
|
528
|
-
}),
|
|
529
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
530
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(neoRelease);
|
|
531
|
-
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
532
|
-
|
|
533
|
-
await expect(method.run()).rejects.toMatchObject({
|
|
534
|
-
params: { firmwareUpdateCode: 'FirmwarePlanInvalid' },
|
|
535
|
-
});
|
|
536
|
-
});
|
|
537
|
-
|
|
538
|
-
test('builds a V4 plan for Neo and excludes unsupported secure elements when forced', async () => {
|
|
539
|
-
const neoRelease: IFirmwareReleaseInfo = {
|
|
540
|
-
...release,
|
|
541
|
-
installOrder: ['se01', 'se02', 'se03', 'se04'],
|
|
542
|
-
components: {
|
|
543
|
-
se01: {
|
|
544
|
-
target: 'SE01',
|
|
545
|
-
url: 'https://example.com/se01.bin',
|
|
546
|
-
version: [1, 0, 0],
|
|
547
|
-
...validComponentIntegrity,
|
|
548
|
-
},
|
|
549
|
-
se02: {
|
|
550
|
-
target: 'SE02',
|
|
551
|
-
url: 'https://example.com/se02.bin',
|
|
552
|
-
version: [2, 0, 0],
|
|
553
|
-
...validComponentIntegrity,
|
|
554
|
-
},
|
|
555
|
-
se03: { target: 'SE03', url: 'https://example.com/se03.bin', version: [1, 0, 0] },
|
|
556
|
-
se04: { target: 'SE04', url: 'https://example.com/se04.bin', version: [1, 0, 0] },
|
|
557
|
-
},
|
|
558
|
-
};
|
|
559
|
-
const method = new CheckAllFirmwareRelease({
|
|
560
|
-
id: 1,
|
|
561
|
-
payload: {
|
|
562
|
-
method: 'checkAllFirmwareRelease',
|
|
563
|
-
platform: 'native',
|
|
564
|
-
forceUpdateTargets: ['firmware'],
|
|
565
|
-
},
|
|
566
|
-
});
|
|
567
|
-
method.init();
|
|
568
|
-
method.device = {
|
|
569
|
-
isProtocolV2: () => true,
|
|
570
|
-
features: {
|
|
571
|
-
deviceType: 'neo',
|
|
572
|
-
serialNo: 'neo-device-id',
|
|
573
|
-
firmwareVersion: '1.0.0',
|
|
574
|
-
},
|
|
575
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
576
|
-
identity: { deviceType: 'neo', firmwareType: EFirmwareType.Universal },
|
|
577
|
-
status: { mode: 'normal' },
|
|
578
|
-
versions: currentVersions,
|
|
579
|
-
}),
|
|
580
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
581
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(neoRelease);
|
|
582
|
-
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
583
|
-
|
|
584
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
585
|
-
targetsToUpdate: ['se01', 'se02'],
|
|
586
|
-
firmwareUpdatePlan: {
|
|
587
|
-
executor: 'v4',
|
|
588
|
-
deviceModel: 'neo',
|
|
589
|
-
platform: 'native',
|
|
590
|
-
targetsToUpdate: ['se01', 'se02'],
|
|
591
|
-
},
|
|
592
|
-
});
|
|
593
|
-
});
|
|
594
|
-
|
|
595
|
-
test('rejects a forced Protocol V2 resource target without a configured archive', async () => {
|
|
596
|
-
const method = new CheckAllFirmwareRelease({
|
|
597
|
-
id: 1,
|
|
598
|
-
payload: {
|
|
599
|
-
method: 'checkAllFirmwareRelease',
|
|
600
|
-
forceUpdateTargets: ['resource'],
|
|
601
|
-
},
|
|
602
|
-
});
|
|
603
|
-
method.init();
|
|
604
|
-
method.device = {
|
|
605
|
-
isProtocolV2: () => true,
|
|
606
|
-
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
607
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
608
|
-
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
609
|
-
status: { mode: 'normal' },
|
|
610
|
-
versions: currentVersions,
|
|
611
|
-
}),
|
|
612
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
613
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
614
|
-
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(undefined);
|
|
615
|
-
|
|
616
|
-
await expect(method.run()).rejects.toMatchObject({
|
|
617
|
-
params: { firmwareUpdateCode: 'FirmwarePlanInvalid' },
|
|
618
|
-
});
|
|
619
|
-
});
|
|
620
|
-
|
|
621
|
-
test('adds a Protocol V2 resource target only when explicitly forced', async () => {
|
|
622
|
-
const currentRelease: IFirmwareReleaseInfo = {
|
|
623
|
-
...release,
|
|
624
|
-
required: false,
|
|
625
|
-
installOrder: ['applicationP1'],
|
|
626
|
-
components: {
|
|
627
|
-
applicationP1: {
|
|
628
|
-
target: 'APPLICATION_P1',
|
|
629
|
-
url: 'https://example.com/application-p1.okpkg',
|
|
630
|
-
version: [1, 0, 0],
|
|
631
|
-
},
|
|
632
|
-
},
|
|
633
|
-
};
|
|
634
|
-
const method = new CheckAllFirmwareRelease({
|
|
635
|
-
id: 1,
|
|
636
|
-
payload: {
|
|
637
|
-
method: 'checkAllFirmwareRelease',
|
|
638
|
-
platform: 'desktop',
|
|
639
|
-
protocolV2ForceUpdateTargets: ['resource'],
|
|
640
|
-
},
|
|
641
|
-
});
|
|
642
|
-
method.init();
|
|
643
|
-
method.device = {
|
|
644
|
-
isProtocolV2: () => true,
|
|
645
|
-
features: {
|
|
646
|
-
deviceType: 'pro2',
|
|
647
|
-
serialNo: 'pro2-device-id',
|
|
648
|
-
firmwareVersion: '1.0.0',
|
|
649
|
-
},
|
|
650
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
651
|
-
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
652
|
-
status: { mode: 'normal' },
|
|
653
|
-
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
654
|
-
}),
|
|
655
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
656
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
657
|
-
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
658
|
-
|
|
659
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
660
|
-
status: 'valid',
|
|
661
|
-
hasUpgrade: true,
|
|
662
|
-
targetsToUpdate: ['resource'],
|
|
663
|
-
firmwareUpdatePlan: {
|
|
664
|
-
executor: 'v4',
|
|
665
|
-
platform: 'desktop',
|
|
666
|
-
artifacts: [
|
|
667
|
-
{
|
|
668
|
-
artifactId: 'resource:archive',
|
|
669
|
-
target: 'resource',
|
|
670
|
-
role: 'resourceBundle',
|
|
671
|
-
container: 'zip',
|
|
672
|
-
},
|
|
673
|
-
],
|
|
674
|
-
targetsToUpdate: ['resource'],
|
|
675
|
-
},
|
|
676
|
-
});
|
|
677
|
-
});
|
|
678
|
-
|
|
679
403
|
test('requests and compares firmware hashes only when explicitly enabled', async () => {
|
|
680
404
|
const packageSet: IFirmwareReleaseInfo = {
|
|
681
405
|
...release,
|
|
682
406
|
required: false,
|
|
407
|
+
resourceBundles: undefined,
|
|
683
408
|
installOrder: ['applicationP1'],
|
|
684
409
|
components: {
|
|
685
410
|
applicationP1: {
|
|
@@ -712,7 +437,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
712
437
|
getCommands: () => ({ typedCall: jest.fn() }),
|
|
713
438
|
} as unknown as CheckAllFirmwareRelease['device'];
|
|
714
439
|
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(packageSet);
|
|
715
|
-
jest.spyOn(DataManager, '
|
|
440
|
+
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(undefined);
|
|
716
441
|
|
|
717
442
|
await expect(method.run()).resolves.toMatchObject({
|
|
718
443
|
status: 'outdated',
|
|
@@ -724,7 +449,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
724
449
|
});
|
|
725
450
|
|
|
726
451
|
test.each(['bootloader', 'romloader'] as const)(
|
|
727
|
-
'
|
|
452
|
+
'uses filesystem inventory in %s mode instead of forcing all resources',
|
|
728
453
|
async mode => {
|
|
729
454
|
const method = new CheckAllFirmwareRelease({
|
|
730
455
|
id: 1,
|
|
@@ -734,7 +459,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
734
459
|
},
|
|
735
460
|
});
|
|
736
461
|
method.init();
|
|
737
|
-
const typedCall =
|
|
462
|
+
const typedCall = createFilesystemTypedCall();
|
|
738
463
|
method.device = {
|
|
739
464
|
isProtocolV2: () => true,
|
|
740
465
|
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
@@ -746,61 +471,18 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
746
471
|
getCommands: () => ({ typedCall }),
|
|
747
472
|
} as unknown as CheckAllFirmwareRelease['device'];
|
|
748
473
|
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
749
|
-
jest.spyOn(DataManager, '
|
|
474
|
+
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
|
|
750
475
|
|
|
751
476
|
await expect(method.run()).resolves.toMatchObject({
|
|
752
477
|
protocol: 'V2',
|
|
753
|
-
resourceStatus: '
|
|
754
|
-
resourceArchive: resourceSource,
|
|
478
|
+
resourceStatus: 'valid',
|
|
755
479
|
targetsToUpdate: ['boot', 'app_v1'],
|
|
756
480
|
});
|
|
757
|
-
expect(typedCall
|
|
481
|
+
expect(typedCall.mock.calls.some(call => call[0] === 'ResourceInventoryGet')).toBe(false);
|
|
482
|
+
expect(typedCall.mock.calls.some(call => call[0] === 'FilesystemFileRead')).toBe(true);
|
|
758
483
|
}
|
|
759
484
|
);
|
|
760
485
|
|
|
761
|
-
test('exposes resource archive availability without reporting an unconfirmed update', async () => {
|
|
762
|
-
const currentRelease: IFirmwareReleaseInfo = {
|
|
763
|
-
...release,
|
|
764
|
-
required: false,
|
|
765
|
-
installOrder: ['applicationP1'],
|
|
766
|
-
components: {
|
|
767
|
-
applicationP1: {
|
|
768
|
-
target: 'APPLICATION_P1',
|
|
769
|
-
url: 'https://example.com/application-p1.okpkg',
|
|
770
|
-
version: [1, 0, 0],
|
|
771
|
-
},
|
|
772
|
-
},
|
|
773
|
-
};
|
|
774
|
-
const method = new CheckAllFirmwareRelease({
|
|
775
|
-
id: 1,
|
|
776
|
-
payload: {
|
|
777
|
-
method: 'checkAllFirmwareRelease',
|
|
778
|
-
firmwareType: EFirmwareType.Universal,
|
|
779
|
-
},
|
|
780
|
-
});
|
|
781
|
-
method.init();
|
|
782
|
-
method.device = {
|
|
783
|
-
isProtocolV2: () => true,
|
|
784
|
-
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
785
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
786
|
-
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
787
|
-
status: { mode: 'normal' },
|
|
788
|
-
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
789
|
-
}),
|
|
790
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
791
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(currentRelease);
|
|
792
|
-
jest.spyOn(DataManager, 'getProtocolV2ResourceSource').mockReturnValue(resourceSource);
|
|
793
|
-
|
|
794
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
795
|
-
status: 'valid',
|
|
796
|
-
hasUpgrade: false,
|
|
797
|
-
resourceStatus: 'unknown',
|
|
798
|
-
resourceArchive: resourceSource,
|
|
799
|
-
targetsToUpdate: [],
|
|
800
|
-
firmwareUpdatePlan: undefined,
|
|
801
|
-
});
|
|
802
|
-
});
|
|
803
|
-
|
|
804
486
|
test('continues forwarding the existing public method', async () => {
|
|
805
487
|
const call = jest.fn().mockResolvedValue({ success: true, payload: {} });
|
|
806
488
|
const api = createCoreApi(call as CoreApi['call']) as CoreApi;
|
|
@@ -808,7 +490,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
808
490
|
await api.checkAllFirmwareRelease('pro2-connect-id', {
|
|
809
491
|
checkFirmwareHash: true,
|
|
810
492
|
firmwareType: EFirmwareType.Universal,
|
|
811
|
-
protocolV2ForceUpdateTargets: ['app_v1'],
|
|
812
493
|
retryCount: 0,
|
|
813
494
|
});
|
|
814
495
|
|
|
@@ -816,7 +497,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
816
497
|
connectId: 'pro2-connect-id',
|
|
817
498
|
checkFirmwareHash: true,
|
|
818
499
|
firmwareType: EFirmwareType.Universal,
|
|
819
|
-
protocolV2ForceUpdateTargets: ['app_v1'],
|
|
820
500
|
retryCount: 0,
|
|
821
501
|
method: 'checkAllFirmwareRelease',
|
|
822
502
|
});
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
jest.mock('../../src/api/firmware/FirmwareUpdatePreparedPlan', () => ({
|
|
10
10
|
assertFirmwareUpdatePreparedPlanBinding: jest.fn(),
|
|
11
11
|
assertFirmwareUpdatePreparedPlanDeviceIdentity: jest.fn(),
|
|
12
|
-
validateFirmwareUpdatePreparedPlan: jest.fn((preparedPlan: unknown) => preparedPlan),
|
|
13
12
|
}));
|
|
14
13
|
|
|
15
14
|
jest.mock('../../src/data-manager', () => ({
|
|
@@ -37,17 +36,14 @@ const createMethod = () => {
|
|
|
37
36
|
read: jest.fn(),
|
|
38
37
|
close,
|
|
39
38
|
};
|
|
40
|
-
const hostBindingGeneration = registerFirmwareUpdateHostBinding({
|
|
41
|
-
artifactReader,
|
|
42
|
-
preparedPlanDigest: 'a'.repeat(64),
|
|
43
|
-
});
|
|
39
|
+
const hostBindingGeneration = registerFirmwareUpdateHostBinding({ artifactReader });
|
|
44
40
|
const method = new DeviceUpdateBootloader({
|
|
45
41
|
id: 1,
|
|
46
42
|
payload: {
|
|
47
43
|
method: 'deviceUpdateBootloader',
|
|
48
44
|
artifact,
|
|
49
45
|
hostBindingGeneration,
|
|
50
|
-
preparedPlan: {
|
|
46
|
+
preparedPlan: {},
|
|
51
47
|
},
|
|
52
48
|
});
|
|
53
49
|
(method as any).device = {
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
} from '../../src/api/firmware/FirmwareHostBinding';
|
|
7
7
|
|
|
8
8
|
const createBinding = () => ({
|
|
9
|
-
preparedPlanDigest: 'a'.repeat(64),
|
|
10
9
|
artifactReader: {
|
|
11
10
|
open: jest.fn(() => Promise.resolve({ readerId: 'reader-1', size: 4 })),
|
|
12
11
|
read: jest.fn(() =>
|
|
@@ -68,12 +67,4 @@ describe('firmware host binding generation', () => {
|
|
|
68
67
|
readerId: 'stale-reader',
|
|
69
68
|
});
|
|
70
69
|
});
|
|
71
|
-
|
|
72
|
-
test('rejects a prepared plan from another host generation before opening artifacts', () => {
|
|
73
|
-
const generation = registerFirmwareUpdateHostBinding(createBinding());
|
|
74
|
-
|
|
75
|
-
expect(() => resolveFirmwareUpdateHostBinding(generation, 'b'.repeat(64))).toThrow(
|
|
76
|
-
'does not match the prepared plan'
|
|
77
|
-
);
|
|
78
|
-
});
|
|
79
70
|
});
|