@onekeyfe/hd-core 1.2.0-alpha.97 → 1.2.0-alpha.98
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 +404 -84
- package/__tests__/check-firmware-release-protocol-v2.test.ts +199 -0
- package/__tests__/firmware-memory-host.test.ts +112 -0
- package/__tests__/firmware-update/device-update-bootloader.test.ts +13 -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-plan.test.ts +232 -70
- 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-resources.test.ts +148 -232
- package/__tests__/protocol-v2.test.ts +1236 -516
- 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 +8 -8
- 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/FirmwareUpdatePlan.d.ts +48 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +6 -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 +1633 -967
- 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 +108 -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 +108 -73
- package/src/api/FirmwareUpdateV3.ts +101 -56
- package/src/api/FirmwareUpdateV4.ts +885 -403
- package/src/api/UploadPortfolio.ts +18 -0
- package/src/api/device/DeviceUpdateBootloader.ts +37 -11
- package/src/api/firmware/FirmwareHostBinding.ts +16 -3
- package/src/api/firmware/FirmwareMemoryHost.ts +142 -0
- package/src/api/firmware/FirmwarePreparedResourceArchive.ts +207 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +282 -122
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +27 -3
- 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
|
@@ -29,10 +29,12 @@ import { DataManager } from '../data-manager';
|
|
|
29
29
|
import { DEVICE } from '../events';
|
|
30
30
|
import { type FirmwareByteSource, openFirmwareByteSource } from './firmware/FirmwareArtifactSource';
|
|
31
31
|
import { resolveFirmwareUpdateHostBinding } from './firmware/FirmwareHostBinding';
|
|
32
|
+
import { readVerifiedPreparedResourceArchive } from './firmware/FirmwarePreparedResourceArchive';
|
|
32
33
|
import {
|
|
33
34
|
assertFirmwareUpdatePreparedPlanBinding,
|
|
34
35
|
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
35
|
-
|
|
36
|
+
getFirmwareUpdatePreparedRawArtifact,
|
|
37
|
+
validateFirmwareUpdatePreparedPlan,
|
|
36
38
|
} from './firmware/FirmwareUpdatePreparedPlan';
|
|
37
39
|
|
|
38
40
|
import type { Features, KnownDevice } from '../types';
|
|
@@ -46,6 +48,7 @@ import type { FirmwareUpdatePreparedPlan } from '../types/api/firmwareUpdatePrep
|
|
|
46
48
|
type Params = {
|
|
47
49
|
binary?: ArrayBuffer;
|
|
48
50
|
artifact?: FirmwareArtifactReference;
|
|
51
|
+
hostBindingGeneration?: number;
|
|
49
52
|
resourceEntries?: Array<{
|
|
50
53
|
entryName: string;
|
|
51
54
|
artifact: FirmwareArtifactReference;
|
|
@@ -159,15 +162,17 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
159
162
|
{ name: 'firmwareType', type: 'string' },
|
|
160
163
|
]);
|
|
161
164
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
payload.binary !== undefined &&
|
|
165
|
-
'artifact' in payload &&
|
|
166
|
-
payload.artifact !== undefined
|
|
167
|
-
) {
|
|
165
|
+
const hasPreparedPlan = payload.preparedPlan !== undefined;
|
|
166
|
+
if (hasPreparedPlan && (payload.binary !== undefined || payload.version !== undefined)) {
|
|
168
167
|
throw ERRORS.TypedError(
|
|
169
168
|
HardwareErrorCode.CallMethodInvalidParameter,
|
|
170
|
-
'
|
|
169
|
+
'Prepared firmware plans cannot be combined with legacy firmware inputs'
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
if (!hasPreparedPlan && payload.artifact !== undefined) {
|
|
173
|
+
throw ERRORS.TypedError(
|
|
174
|
+
HardwareErrorCode.CallMethodInvalidParameter,
|
|
175
|
+
'Firmware artifacts require a prepared plan'
|
|
171
176
|
);
|
|
172
177
|
}
|
|
173
178
|
|
|
@@ -184,7 +189,7 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
184
189
|
isUpdateBootloader: payload.isUpdateBootloader,
|
|
185
190
|
};
|
|
186
191
|
|
|
187
|
-
if ('version' in payload) {
|
|
192
|
+
if (!hasPreparedPlan && 'version' in payload) {
|
|
188
193
|
this.params = {
|
|
189
194
|
...this.params,
|
|
190
195
|
version: payload.version,
|
|
@@ -192,16 +197,25 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
192
197
|
};
|
|
193
198
|
}
|
|
194
199
|
|
|
195
|
-
if ('binary' in payload) {
|
|
200
|
+
if (!hasPreparedPlan && 'binary' in payload) {
|
|
196
201
|
this.params = {
|
|
197
202
|
...this.params,
|
|
198
203
|
binary: payload.binary,
|
|
199
204
|
};
|
|
200
205
|
}
|
|
201
206
|
|
|
202
|
-
if (
|
|
203
|
-
const
|
|
207
|
+
if (hasPreparedPlan) {
|
|
208
|
+
const preparedPlan = validateFirmwareUpdatePreparedPlan(payload.preparedPlan);
|
|
209
|
+
const hostBinding = resolveFirmwareUpdateHostBinding(
|
|
210
|
+
payload.hostBindingGeneration,
|
|
211
|
+
preparedPlan.preparedPlanDigest
|
|
212
|
+
);
|
|
204
213
|
const target = payload.isUpdateBootloader ? 'bootloader' : payload.updateType;
|
|
214
|
+
const plannedArtifact = getFirmwareUpdatePreparedRawArtifact({
|
|
215
|
+
preparedPlan,
|
|
216
|
+
target,
|
|
217
|
+
role: target,
|
|
218
|
+
}).artifact;
|
|
205
219
|
const resourceBindings = (payload.resourceEntries ?? []).map(
|
|
206
220
|
(entry: { entryName: string; artifact: FirmwareArtifactReference }) => ({
|
|
207
221
|
target: 'resource' as const,
|
|
@@ -210,18 +224,21 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
210
224
|
})
|
|
211
225
|
);
|
|
212
226
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
213
|
-
preparedPlan
|
|
227
|
+
preparedPlan,
|
|
214
228
|
executor: 'v2',
|
|
215
229
|
platform: payload.platform,
|
|
216
|
-
scopeTargets: [
|
|
217
|
-
|
|
230
|
+
scopeTargets: [
|
|
231
|
+
target,
|
|
232
|
+
...(target === 'firmware' && resourceBindings.length ? (['resource'] as const) : []),
|
|
233
|
+
],
|
|
234
|
+
bindings: [{ target, artifact: payload.artifact ?? plannedArtifact }, ...resourceBindings],
|
|
218
235
|
});
|
|
219
236
|
this.params = {
|
|
220
237
|
...this.params,
|
|
221
|
-
preparedPlan
|
|
222
|
-
artifact:
|
|
223
|
-
resourceEntries: payload.resourceEntries,
|
|
238
|
+
preparedPlan,
|
|
239
|
+
artifact: plannedArtifact,
|
|
224
240
|
artifactReader: hostBinding.artifactReader,
|
|
241
|
+
firmwareType: preparedPlan.firmwareType,
|
|
225
242
|
};
|
|
226
243
|
}
|
|
227
244
|
}
|
|
@@ -531,6 +548,18 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
531
548
|
}
|
|
532
549
|
};
|
|
533
550
|
|
|
551
|
+
const preparedResourceRequested =
|
|
552
|
+
!params.isUpdateBootloader &&
|
|
553
|
+
params.updateType === 'firmware' &&
|
|
554
|
+
(params.preparedPlan?.targetsToUpdate.includes('resource') ?? false);
|
|
555
|
+
if (preparedResourceRequested && device.isBootloader()) {
|
|
556
|
+
throw ERRORS.TypedError(
|
|
557
|
+
HardwareErrorCode.RuntimeError,
|
|
558
|
+
'Prepared firmware resources require the device application mode',
|
|
559
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared', artifactName: 'resource' }
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
|
|
534
563
|
if (!device.isBootloader() && features) {
|
|
535
564
|
const serialNo = device.getCurrentSerialNo();
|
|
536
565
|
// should go to bootloader mode manually
|
|
@@ -541,72 +570,78 @@ export default class FirmwareUpdateV2 extends BaseMethod<Params> {
|
|
|
541
570
|
// All network-backed input must be ready before the first device mutation.
|
|
542
571
|
await acquireFirmwareSource();
|
|
543
572
|
|
|
544
|
-
//
|
|
545
|
-
if (
|
|
573
|
+
// PreparedPlan 资源只依赖获批 ZIP;live release 仅保留给非 prepared 旧流程。
|
|
574
|
+
if (preparedResourceRequested) {
|
|
575
|
+
if (!this.isSupportResourceUpdate(params.updateType)) {
|
|
576
|
+
throw ERRORS.TypedError(
|
|
577
|
+
HardwareErrorCode.RuntimeError,
|
|
578
|
+
'Prepared firmware resources are not supported by this device',
|
|
579
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared', artifactName: 'resource' }
|
|
580
|
+
);
|
|
581
|
+
}
|
|
546
582
|
this.postTipMessage('CheckLatestUiResource');
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
583
|
+
this.postTipMessage('DownloadLatestUiResource');
|
|
584
|
+
const verifiedEntries = await readVerifiedPreparedResourceArchive({
|
|
585
|
+
preparedPlan: params.preparedPlan as FirmwareUpdatePreparedPlan,
|
|
586
|
+
reader: params.artifactReader,
|
|
551
587
|
});
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
source: FirmwareByteSource;
|
|
558
|
-
}> = [];
|
|
559
|
-
try {
|
|
560
|
-
for (const entry of params.resourceEntries) {
|
|
561
|
-
const resourceName = getFirmwareUpdateResourceName(entry.entryName);
|
|
562
|
-
const source = await openFirmwareByteSource({
|
|
563
|
-
artifact: entry.artifact,
|
|
564
|
-
reader: params.artifactReader,
|
|
565
|
-
});
|
|
566
|
-
if (!source) {
|
|
567
|
-
throw new Error('Firmware resource entry is not prepared');
|
|
568
|
-
}
|
|
569
|
-
sources.push({ entryName: resourceName, source });
|
|
570
|
-
}
|
|
571
|
-
await updateResourcesFromSources(
|
|
572
|
-
this.device.getCommands().typedCall.bind(this.device.getCommands()),
|
|
573
|
-
this.postMessage,
|
|
574
|
-
device,
|
|
575
|
-
sources.map(entry => ({
|
|
576
|
-
entryName: entry.entryName,
|
|
577
|
-
source: entry.source,
|
|
578
|
-
}))
|
|
579
|
-
);
|
|
580
|
-
} finally {
|
|
581
|
-
await Promise.all(
|
|
582
|
-
sources.map(entry => entry.source.close().catch(() => undefined))
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
this.postTipMessage('DownloadLatestUiResourceSuccess');
|
|
586
|
-
} else {
|
|
587
|
-
if (
|
|
588
|
-
params.artifactReader ||
|
|
589
|
-
DataManager.getSettings('firmwareManifestMode') === 'external-only'
|
|
590
|
-
) {
|
|
588
|
+
const sources: Array<{ entryName: string; source: FirmwareByteSource }> = [];
|
|
589
|
+
try {
|
|
590
|
+
for (const entry of verifiedEntries) {
|
|
591
|
+
const source = await openFirmwareByteSource({ binary: entry.binary });
|
|
592
|
+
if (!source) {
|
|
591
593
|
throw ERRORS.TypedError(
|
|
592
594
|
HardwareErrorCode.RuntimeError,
|
|
593
|
-
|
|
595
|
+
`Firmware resource entry ${entry.entryName} is empty`,
|
|
594
596
|
{
|
|
595
|
-
firmwareUpdateCode: '
|
|
597
|
+
firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch',
|
|
596
598
|
artifactName: 'resource',
|
|
597
599
|
}
|
|
598
600
|
);
|
|
599
601
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
602
|
+
sources.push({ entryName: entry.entryName, source });
|
|
603
|
+
}
|
|
604
|
+
await updateResourcesFromSources(
|
|
605
|
+
this.device.getCommands().typedCall.bind(this.device.getCommands()),
|
|
606
|
+
this.postMessage,
|
|
607
|
+
device,
|
|
608
|
+
sources
|
|
609
|
+
);
|
|
610
|
+
} finally {
|
|
611
|
+
await Promise.all(sources.map(entry => entry.source.close().catch(() => undefined)));
|
|
612
|
+
}
|
|
613
|
+
this.postTipMessage('DownloadLatestUiResourceSuccess');
|
|
614
|
+
} else if (this.isSupportResourceUpdate(params.updateType)) {
|
|
615
|
+
this.postTipMessage('CheckLatestUiResource');
|
|
616
|
+
const resourceUrl = DataManager.getSysResourcesLatestRelease({
|
|
617
|
+
features,
|
|
618
|
+
forcedUpdateRes: params.forcedUpdateRes,
|
|
619
|
+
firmwareType,
|
|
620
|
+
});
|
|
621
|
+
if (resourceUrl) {
|
|
622
|
+
this.postTipMessage('DownloadLatestUiResource');
|
|
623
|
+
if (
|
|
624
|
+
params.artifactReader ||
|
|
625
|
+
DataManager.getSettings('firmwareManifestMode') === 'external-only'
|
|
626
|
+
) {
|
|
627
|
+
throw ERRORS.TypedError(
|
|
628
|
+
HardwareErrorCode.RuntimeError,
|
|
629
|
+
'Firmware resource must be prepared by the external firmware host',
|
|
630
|
+
{
|
|
631
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
632
|
+
artifactName: 'resource',
|
|
633
|
+
}
|
|
608
634
|
);
|
|
609
635
|
}
|
|
636
|
+
const resourceBinary: ArrayBuffer | Buffer = (await getSysResourceBinary(resourceUrl))
|
|
637
|
+
.binary;
|
|
638
|
+
this.postTipMessage('DownloadLatestUiResourceSuccess');
|
|
639
|
+
await updateResources(
|
|
640
|
+
this.device.getCommands().typedCall.bind(this.device.getCommands()),
|
|
641
|
+
this.postMessage,
|
|
642
|
+
device,
|
|
643
|
+
resourceBinary
|
|
644
|
+
);
|
|
610
645
|
}
|
|
611
646
|
}
|
|
612
647
|
|
|
@@ -21,10 +21,12 @@ import { DEVICE } from '../events';
|
|
|
21
21
|
import { buildProtocolV1FeaturesPayload } from '../deviceProfile';
|
|
22
22
|
import { openFirmwareByteSource } from './firmware/FirmwareArtifactSource';
|
|
23
23
|
import { resolveFirmwareUpdateHostBinding } from './firmware/FirmwareHostBinding';
|
|
24
|
+
import { readVerifiedPreparedResourceArchive } from './firmware/FirmwarePreparedResourceArchive';
|
|
24
25
|
import {
|
|
25
26
|
assertFirmwareUpdatePreparedPlanBinding,
|
|
26
27
|
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
27
|
-
|
|
28
|
+
getFirmwareUpdatePreparedRawArtifact,
|
|
29
|
+
validateFirmwareUpdatePreparedPlan,
|
|
28
30
|
} from './firmware/FirmwareUpdatePreparedPlan';
|
|
29
31
|
|
|
30
32
|
import type {
|
|
@@ -77,54 +79,97 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
77
79
|
{ name: 'firmwareType', type: 'string' },
|
|
78
80
|
{ name: 'platform', type: 'string' },
|
|
79
81
|
]);
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
const hasPreparedPlan = payload.preparedPlan !== undefined;
|
|
83
|
+
if (!hasPreparedPlan && payload.artifacts !== undefined) {
|
|
84
|
+
throw ERRORS.TypedError(
|
|
85
|
+
HardwareErrorCode.CallMethodInvalidParameter,
|
|
86
|
+
'Firmware artifacts require a prepared plan'
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
const preparedPlan = hasPreparedPlan
|
|
90
|
+
? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
|
|
91
|
+
: undefined;
|
|
92
|
+
const hasLegacyInputs = [
|
|
93
|
+
payload.bleVersion,
|
|
94
|
+
payload.bleBinary,
|
|
95
|
+
payload.firmwareVersion,
|
|
96
|
+
payload.firmwareBinary,
|
|
97
|
+
payload.resourceBinary,
|
|
98
|
+
payload.bootloaderVersion,
|
|
99
|
+
payload.bootloaderBinary,
|
|
100
|
+
].some(input => input !== undefined);
|
|
101
|
+
if (preparedPlan && hasLegacyInputs) {
|
|
102
|
+
throw ERRORS.TypedError(
|
|
103
|
+
HardwareErrorCode.CallMethodInvalidParameter,
|
|
104
|
+
'Prepared firmware plans cannot be combined with legacy firmware inputs'
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
const artifactReader = preparedPlan
|
|
108
|
+
? resolveFirmwareUpdateHostBinding(
|
|
109
|
+
payload.hostBindingGeneration,
|
|
110
|
+
preparedPlan.preparedPlanDigest
|
|
111
|
+
).artifactReader
|
|
112
|
+
: payload.artifactReader;
|
|
113
|
+
const preparedArtifacts: NonNullable<FirmwareUpdateV3Params['artifacts']> = {};
|
|
114
|
+
if (preparedPlan) {
|
|
115
|
+
const componentTargets = ['bootloader', 'firmware', 'ble'] as const;
|
|
116
|
+
const supportedTargets = new Set<string>([...componentTargets, 'resource']);
|
|
117
|
+
const unsupportedTarget = preparedPlan.targetsToUpdate.find(
|
|
118
|
+
target => !supportedTargets.has(target)
|
|
119
|
+
);
|
|
120
|
+
if (unsupportedTarget) {
|
|
121
|
+
throw ERRORS.TypedError(
|
|
122
|
+
HardwareErrorCode.RuntimeError,
|
|
123
|
+
`Firmware prepared plan target ${unsupportedTarget} is not supported by V3`,
|
|
124
|
+
{ firmwareUpdateCode: 'FirmwarePreparedPlanInvalid' }
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
for (const target of componentTargets) {
|
|
128
|
+
if (preparedPlan.targetsToUpdate.includes(target)) {
|
|
129
|
+
preparedArtifacts[target] = getFirmwareUpdatePreparedRawArtifact({
|
|
130
|
+
preparedPlan,
|
|
131
|
+
target,
|
|
132
|
+
role: target,
|
|
133
|
+
}).artifact;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const resourceBindings = (payload.artifacts?.resourceEntries ?? []).map(
|
|
137
|
+
(entry: { entryName: string; artifact: FirmwareArtifactReference }) => ({
|
|
138
|
+
target: 'resource' as const,
|
|
139
|
+
entryName: entry.entryName,
|
|
140
|
+
artifact: entry.artifact,
|
|
141
|
+
})
|
|
142
|
+
);
|
|
85
143
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
86
|
-
preparedPlan
|
|
144
|
+
preparedPlan,
|
|
87
145
|
executor: 'v3',
|
|
88
146
|
platform: payload.platform,
|
|
89
|
-
scopeTargets: [
|
|
147
|
+
scopeTargets: [
|
|
148
|
+
'bootloader',
|
|
149
|
+
'firmware',
|
|
150
|
+
'ble',
|
|
151
|
+
...(resourceBindings.length ? (['resource'] as const) : []),
|
|
152
|
+
],
|
|
90
153
|
bindings: [
|
|
91
|
-
...(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
105
|
-
]
|
|
106
|
-
: []),
|
|
107
|
-
...(payload.artifacts?.ble
|
|
108
|
-
? [
|
|
109
|
-
{
|
|
110
|
-
target: 'ble' as const,
|
|
111
|
-
artifact: payload.artifacts.ble,
|
|
112
|
-
},
|
|
113
|
-
]
|
|
114
|
-
: []),
|
|
115
|
-
...(payload.artifacts?.resourceEntries ?? []).map(
|
|
116
|
-
(entry: { entryName: string; artifact: FirmwareArtifactReference }) => ({
|
|
117
|
-
target: 'resource' as const,
|
|
118
|
-
entryName: entry.entryName,
|
|
119
|
-
artifact: entry.artifact,
|
|
120
|
-
})
|
|
121
|
-
),
|
|
154
|
+
...componentTargets.flatMap(target => {
|
|
155
|
+
const plannedArtifact = preparedArtifacts[target];
|
|
156
|
+
const suppliedArtifact = payload.artifacts?.[target];
|
|
157
|
+
return plannedArtifact || suppliedArtifact
|
|
158
|
+
? [
|
|
159
|
+
{
|
|
160
|
+
target,
|
|
161
|
+
artifact: suppliedArtifact ?? (plannedArtifact as FirmwareArtifactReference),
|
|
162
|
+
},
|
|
163
|
+
]
|
|
164
|
+
: [];
|
|
165
|
+
}),
|
|
166
|
+
...resourceBindings,
|
|
122
167
|
],
|
|
123
168
|
});
|
|
124
169
|
}
|
|
125
170
|
|
|
126
171
|
this.params = {
|
|
127
|
-
preparedPlan
|
|
172
|
+
preparedPlan,
|
|
128
173
|
bleBinary: payload.bleBinary,
|
|
129
174
|
firmwareBinary: payload.firmwareBinary,
|
|
130
175
|
forcedUpdateRes: payload.forcedUpdateRes,
|
|
@@ -133,10 +178,10 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
133
178
|
bootloaderBinary: payload.bootloaderBinary,
|
|
134
179
|
firmwareVersion: payload.firmwareVersion,
|
|
135
180
|
resourceBinary: payload.resourceBinary,
|
|
136
|
-
firmwareType: payload.firmwareType,
|
|
181
|
+
firmwareType: preparedPlan?.firmwareType ?? payload.firmwareType,
|
|
137
182
|
platform: payload.platform,
|
|
138
|
-
artifactReader
|
|
139
|
-
artifacts:
|
|
183
|
+
artifactReader,
|
|
184
|
+
artifacts: preparedPlan ? preparedArtifacts : undefined,
|
|
140
185
|
};
|
|
141
186
|
}
|
|
142
187
|
|
|
@@ -263,25 +308,25 @@ export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
263
308
|
}
|
|
264
309
|
|
|
265
310
|
private async prepareResourceInput(firmwareType: EFirmwareType) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
if (preparedEntries?.length) {
|
|
311
|
+
if (this.params.preparedPlan?.targetsToUpdate.includes('resource')) {
|
|
312
|
+
const verifiedEntries = await readVerifiedPreparedResourceArchive({
|
|
313
|
+
preparedPlan: this.params.preparedPlan,
|
|
314
|
+
reader: this.params.artifactReader,
|
|
315
|
+
});
|
|
274
316
|
const resourceEntries: Array<{ entryName: string; source: FirmwareByteSource }> = [];
|
|
275
|
-
for (const entry of
|
|
276
|
-
const
|
|
277
|
-
const source = await this.openArtifactSource(undefined, entry.artifact);
|
|
317
|
+
for (const entry of verifiedEntries) {
|
|
318
|
+
const source = await this.openArtifactSource(entry.binary, undefined);
|
|
278
319
|
if (!source) {
|
|
279
320
|
throw ERRORS.TypedError(
|
|
280
321
|
HardwareErrorCode.RuntimeError,
|
|
281
|
-
`Firmware resource entry ${entry.entryName} is
|
|
322
|
+
`Firmware resource entry ${entry.entryName} is empty`,
|
|
323
|
+
{
|
|
324
|
+
firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch',
|
|
325
|
+
artifactName: 'resource',
|
|
326
|
+
}
|
|
282
327
|
);
|
|
283
328
|
}
|
|
284
|
-
resourceEntries.push({ entryName:
|
|
329
|
+
resourceEntries.push({ entryName: entry.entryName, source });
|
|
285
330
|
}
|
|
286
331
|
return {
|
|
287
332
|
resourceBinary: null,
|