@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
package/dist/index.js
CHANGED
|
@@ -522,10 +522,6 @@ const PROTOCOL_V2_TARGETS = {
|
|
|
522
522
|
SE03: 'se03',
|
|
523
523
|
SE04: 'se04',
|
|
524
524
|
};
|
|
525
|
-
const PROTOCOL_V2_FIRMWARE_UPDATE_TARGETS = new Set([
|
|
526
|
-
...Object.values(PROTOCOL_V2_TARGETS),
|
|
527
|
-
'resource',
|
|
528
|
-
]);
|
|
529
525
|
const asRecord = (value) => value && typeof value === 'object' && !Array.isArray(value)
|
|
530
526
|
? value
|
|
531
527
|
: undefined;
|
|
@@ -613,18 +609,6 @@ const validateFirmwareUpdatePlanForceTargets = (value) => {
|
|
|
613
609
|
}
|
|
614
610
|
return [...value];
|
|
615
611
|
};
|
|
616
|
-
const validateProtocolV2FirmwareUpdateTargets = (value) => {
|
|
617
|
-
if (value === undefined) {
|
|
618
|
-
return [];
|
|
619
|
-
}
|
|
620
|
-
if (!Array.isArray(value) ||
|
|
621
|
-
value.length > PROTOCOL_V2_FIRMWARE_UPDATE_TARGETS.size ||
|
|
622
|
-
value.some(target => !PROTOCOL_V2_FIRMWARE_UPDATE_TARGETS.has(target)) ||
|
|
623
|
-
new Set(value).size !== value.length) {
|
|
624
|
-
return planError('Protocol V2 firmware update targets are invalid');
|
|
625
|
-
}
|
|
626
|
-
return [...value];
|
|
627
|
-
};
|
|
628
612
|
const assertExactKeys = (value, required, optional = []) => {
|
|
629
613
|
const allowed = new Set([...required, ...optional]);
|
|
630
614
|
if (required.some(key => !Object.prototype.hasOwnProperty.call(value, key)) ||
|
|
@@ -754,7 +738,7 @@ const assertFirmwareUpdatePlan = (value) => {
|
|
|
754
738
|
plan.targetsToUpdate.some(target => legacyOnlyTargets.has(target))) ||
|
|
755
739
|
(plan.artifacts.length > 0 &&
|
|
756
740
|
(plan.platform === 'native' || plan.platform === 'desktop') &&
|
|
757
|
-
plan.executor
|
|
741
|
+
plan.executor !== 'v2' &&
|
|
758
742
|
plan.deviceIdentity === 'unavailable')) {
|
|
759
743
|
return planError('Firmware update plan executor contract is invalid');
|
|
760
744
|
}
|
|
@@ -789,7 +773,7 @@ const selectResourceUrl = ({ release, features, platform, }) => {
|
|
|
789
773
|
};
|
|
790
774
|
const getExecutor = (features) => {
|
|
791
775
|
const deviceType = getDeviceType(features);
|
|
792
|
-
if (deviceType === hdShared.EDeviceType.Pro2
|
|
776
|
+
if (deviceType === hdShared.EDeviceType.Pro2) {
|
|
793
777
|
return 'v4';
|
|
794
778
|
}
|
|
795
779
|
if (deviceType === hdShared.EDeviceType.Pro &&
|
|
@@ -798,7 +782,7 @@ const getExecutor = (features) => {
|
|
|
798
782
|
}
|
|
799
783
|
return 'v2';
|
|
800
784
|
};
|
|
801
|
-
const buildProtocolV2Artifacts = (release, { includeComponents = true,
|
|
785
|
+
const buildProtocolV2Artifacts = (release, { includeComponents = true, includeResources = true, } = {}) => {
|
|
802
786
|
var _a;
|
|
803
787
|
const components = asRecord(release.components);
|
|
804
788
|
if (includeComponents && !components) {
|
|
@@ -810,42 +794,49 @@ const buildProtocolV2Artifacts = (release, { includeComponents = true, component
|
|
|
810
794
|
const componentKeys = includeComponents && components
|
|
811
795
|
? [...installOrder, ...Object.keys(components).filter(key => !installOrder.includes(key))]
|
|
812
796
|
: [];
|
|
813
|
-
const selectedComponentKeys = selectedComponentTargets
|
|
814
|
-
? componentKeys.filter(key => {
|
|
815
|
-
var _a;
|
|
816
|
-
const component = asRecord(components === null || components === void 0 ? void 0 : components[key]);
|
|
817
|
-
const targetName = (_a = asString(component === null || component === void 0 ? void 0 : component.target)) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
818
|
-
const target = targetName ? PROTOCOL_V2_TARGETS[targetName] : undefined;
|
|
819
|
-
return !!target && selectedComponentTargets.has(target);
|
|
820
|
-
})
|
|
821
|
-
: componentKeys;
|
|
822
797
|
const artifacts = [];
|
|
823
798
|
const targets = [];
|
|
824
|
-
const
|
|
825
|
-
for (const key of
|
|
799
|
+
const componentTargets = new Set();
|
|
800
|
+
for (const key of componentKeys) {
|
|
826
801
|
const component = asRecord(components === null || components === void 0 ? void 0 : components[key]);
|
|
827
802
|
const targetName = (_a = asString(component === null || component === void 0 ? void 0 : component.target)) === null || _a === void 0 ? void 0 : _a.toUpperCase();
|
|
828
|
-
const target = targetName ? PROTOCOL_V2_TARGETS[targetName] : undefined;
|
|
829
803
|
if (targetName === 'ROMLOADER') {
|
|
830
804
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 ROMLOADER requires its dedicated loader flow', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
831
805
|
}
|
|
806
|
+
const target = targetName ? PROTOCOL_V2_TARGETS[targetName] : undefined;
|
|
832
807
|
if (!component || !target) {
|
|
833
808
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 component ${key} has an unsupported target`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
834
809
|
}
|
|
835
|
-
if (
|
|
810
|
+
if (componentTargets.has(target)) {
|
|
836
811
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 component ${key} duplicates target ${target}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
837
812
|
}
|
|
838
|
-
|
|
839
|
-
|
|
813
|
+
componentTargets.add(target);
|
|
814
|
+
artifacts.push(Object.assign(Object.assign({ artifactId: `component:${target}`, role: 'component', target, url: assertArtifactUrl(component.url, `Protocol V2 component ${key}`), container: 'raw', logicalName: key }, asIntegrity({
|
|
840
815
|
size: component.expectedSize,
|
|
841
816
|
sha256: component.fingerprint,
|
|
842
|
-
});
|
|
843
|
-
if (integrity.expectedSize === undefined || integrity.expectedSha256 === undefined) {
|
|
844
|
-
planError(`Protocol V2 component ${key} integrity metadata is invalid`);
|
|
845
|
-
}
|
|
846
|
-
artifacts.push(Object.assign(Object.assign({ artifactId: `component:${target}`, role: 'component', target, url: assertArtifactUrl(component.url, `Protocol V2 component ${key}`), container: 'raw', logicalName: key }, integrity), (asVersion(component.version) ? { targetVersion: asVersion(component.version) } : {})));
|
|
817
|
+
})), (asVersion(component.version) ? { targetVersion: asVersion(component.version) } : {})));
|
|
847
818
|
targets.push(target);
|
|
848
819
|
}
|
|
820
|
+
const bundles = includeResources && Array.isArray(release.resourceBundles) ? release.resourceBundles : [];
|
|
821
|
+
const resourceBundleNames = new Set();
|
|
822
|
+
for (const value of bundles) {
|
|
823
|
+
const bundle = asRecord(value);
|
|
824
|
+
const name = asString(bundle === null || bundle === void 0 ? void 0 : bundle.name);
|
|
825
|
+
if (!bundle || !name) {
|
|
826
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource bundle is invalid', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
827
|
+
}
|
|
828
|
+
if (resourceBundleNames.has(name)) {
|
|
829
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource bundle duplicates name ${name}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
830
|
+
}
|
|
831
|
+
resourceBundleNames.add(name);
|
|
832
|
+
artifacts.push(Object.assign({ artifactId: `resourceBundle:${name}`, role: 'resourceBundle', target: 'resource', url: assertArtifactUrl(bundle.url, `Protocol V2 resource bundle ${name}`), container: 'raw', logicalName: name }, asIntegrity({
|
|
833
|
+
size: bundle.expectedSize,
|
|
834
|
+
sha256: bundle.fingerprint,
|
|
835
|
+
})));
|
|
836
|
+
}
|
|
837
|
+
if (bundles.length > 0) {
|
|
838
|
+
targets.push('resource');
|
|
839
|
+
}
|
|
849
840
|
return { artifacts, targets: [...new Set(targets)] };
|
|
850
841
|
};
|
|
851
842
|
const isForcedTargetRepresented = ({ executor, forcedTarget, artifacts, targetsToUpdate, }) => {
|
|
@@ -874,95 +865,6 @@ const assertForcedTargetsRepresented = ({ executor, forcedTargets, artifacts, ta
|
|
|
874
865
|
}
|
|
875
866
|
}
|
|
876
867
|
};
|
|
877
|
-
const finalizeFirmwareUpdatePlan = ({ features, firmwareType, platform, artifacts, targetsToUpdate, }) => {
|
|
878
|
-
const executor = getExecutor(features);
|
|
879
|
-
const bootloaderMode = resolveDeviceBootloaderMode(features);
|
|
880
|
-
const reportedIdentity = getDeviceUUID(features);
|
|
881
|
-
const deviceIdentity = reportedIdentity === 'unavailable' ? '' : reportedIdentity;
|
|
882
|
-
const allowsUnavailableIdentity = (bootloaderMode && executor === 'v2') || executor === 'v4';
|
|
883
|
-
if (artifacts.length > 0 &&
|
|
884
|
-
(platform === 'native' || platform === 'desktop') &&
|
|
885
|
-
!deviceIdentity &&
|
|
886
|
-
!allowsUnavailableIdentity) {
|
|
887
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Prepared firmware update requires a stable device identity', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
888
|
-
}
|
|
889
|
-
const planWithoutDigest = {
|
|
890
|
-
schemaVersion: 2,
|
|
891
|
-
executor,
|
|
892
|
-
deviceIdentity: deviceIdentity || 'unavailable',
|
|
893
|
-
deviceModel: String(getDeviceType(features)),
|
|
894
|
-
firmwareType,
|
|
895
|
-
platform,
|
|
896
|
-
artifacts,
|
|
897
|
-
targetsToUpdate,
|
|
898
|
-
};
|
|
899
|
-
return assertFirmwareUpdatePlan(Object.assign(Object.assign({}, planWithoutDigest), { planDigest: digestFirmwareUpdatePlan(planWithoutDigest) }));
|
|
900
|
-
};
|
|
901
|
-
const buildProtocolV2LocalFirmwareUpdatePlan = ({ features, firmwareType, platform, artifacts, }) => {
|
|
902
|
-
if (artifacts.length === 0) {
|
|
903
|
-
return planError('Protocol V2 local firmware plan has no artifacts');
|
|
904
|
-
}
|
|
905
|
-
const plan = finalizeFirmwareUpdatePlan({
|
|
906
|
-
features,
|
|
907
|
-
firmwareType,
|
|
908
|
-
platform,
|
|
909
|
-
artifacts: artifacts.map(artifact => (Object.assign(Object.assign({}, artifact), { role: artifact.target === 'resource' ? 'resourceBundle' : 'component', url: `https://local-firmware.invalid/${encodeURIComponent(artifact.artifactId)}` }))),
|
|
910
|
-
targetsToUpdate: artifacts.map(artifact => artifact.target),
|
|
911
|
-
});
|
|
912
|
-
if (plan.executor !== 'v4') {
|
|
913
|
-
return planError('Protocol V2 local firmware plan requires executor v4');
|
|
914
|
-
}
|
|
915
|
-
return plan;
|
|
916
|
-
};
|
|
917
|
-
const buildProtocolV2FirmwareUpdatePlan = ({ features, firmwareType, platform, release, targetsToUpdate, forceUpdateTargets, resourceArchive, }) => {
|
|
918
|
-
const validatedForceTargets = validateFirmwareUpdatePlanForceTargets(forceUpdateTargets);
|
|
919
|
-
if (validatedForceTargets.some(target => target === 'ble' || target === 'bootloader')) {
|
|
920
|
-
planError('Protocol V2 does not support forced BLE or legacy bootloader targets');
|
|
921
|
-
}
|
|
922
|
-
const requestedComponentTargets = new Set(targetsToUpdate.filter(target => target !== 'resource'));
|
|
923
|
-
if (getDeviceType(features) === hdShared.EDeviceType.Neo &&
|
|
924
|
-
(requestedComponentTargets.has('se03') || requestedComponentTargets.has('se04'))) {
|
|
925
|
-
planError('Neo does not support Protocol V2 targets se03 or se04');
|
|
926
|
-
}
|
|
927
|
-
const protocolV2 = buildProtocolV2Artifacts(release !== null && release !== void 0 ? release : {}, {
|
|
928
|
-
includeComponents: requestedComponentTargets.size > 0,
|
|
929
|
-
componentTargets: requestedComponentTargets,
|
|
930
|
-
});
|
|
931
|
-
const resourceRequested = targetsToUpdate.includes('resource');
|
|
932
|
-
if (resourceRequested) {
|
|
933
|
-
const archive = resourceArchive;
|
|
934
|
-
if (!archive) {
|
|
935
|
-
return planError('Protocol V2 resource target has no resource archive');
|
|
936
|
-
}
|
|
937
|
-
const integrity = asIntegrity({
|
|
938
|
-
size: archive.archiveSize,
|
|
939
|
-
sha256: archive.archiveSha256,
|
|
940
|
-
});
|
|
941
|
-
if (integrity.expectedSize === undefined || integrity.expectedSha256 === undefined) {
|
|
942
|
-
planError('Protocol V2 resource archive integrity metadata is invalid');
|
|
943
|
-
}
|
|
944
|
-
protocolV2.artifacts.push(Object.assign({ artifactId: 'resource:archive', role: 'resourceBundle', target: 'resource', url: assertArtifactUrl(archive.archiveUrl, 'Protocol V2 resource archive'), container: 'zip', logicalName: 'protocol-v2-resource-archive' }, integrity));
|
|
945
|
-
protocolV2.targets.push('resource');
|
|
946
|
-
}
|
|
947
|
-
const representedTargets = new Set(protocolV2.targets);
|
|
948
|
-
const missingTarget = Array.from(requestedComponentTargets).find(target => !representedTargets.has(target));
|
|
949
|
-
if (missingTarget) {
|
|
950
|
-
planError(`Protocol V2 release does not contain requested target ${missingTarget}`);
|
|
951
|
-
}
|
|
952
|
-
if (validatedForceTargets.includes('firmware') && protocolV2.targets.length === 0) {
|
|
953
|
-
planError('Forced firmware update target firmware is not represented by the plan');
|
|
954
|
-
}
|
|
955
|
-
if (validatedForceTargets.includes('resource') && !resourceArchive) {
|
|
956
|
-
planError('Forced firmware update target resource has no Protocol V2 resource archive');
|
|
957
|
-
}
|
|
958
|
-
return finalizeFirmwareUpdatePlan({
|
|
959
|
-
features,
|
|
960
|
-
firmwareType,
|
|
961
|
-
platform,
|
|
962
|
-
artifacts: protocolV2.artifacts,
|
|
963
|
-
targetsToUpdate: protocolV2.targets,
|
|
964
|
-
});
|
|
965
|
-
};
|
|
966
868
|
const buildFirmwareUpdatePlan = ({ features, firmwareType, platform, firmware, ble, bootloader, forceUpdateTargets, }) => {
|
|
967
869
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
968
870
|
const executor = getExecutor(features);
|
|
@@ -984,6 +886,7 @@ const buildFirmwareUpdatePlan = ({ features, firmwareType, platform, firmware, b
|
|
|
984
886
|
if (executor === 'v4' && (shouldUpdateFirmware || shouldUpdateResource)) {
|
|
985
887
|
const protocolV2 = buildProtocolV2Artifacts(firmwareRelease !== null && firmwareRelease !== void 0 ? firmwareRelease : {}, {
|
|
986
888
|
includeComponents: shouldUpdateFirmware,
|
|
889
|
+
includeResources: shouldUpdateResource,
|
|
987
890
|
});
|
|
988
891
|
artifacts = protocolV2.artifacts;
|
|
989
892
|
targetsToUpdate = protocolV2.targets;
|
|
@@ -1048,13 +951,25 @@ const buildFirmwareUpdatePlan = ({ features, firmwareType, platform, firmware, b
|
|
|
1048
951
|
artifacts,
|
|
1049
952
|
targetsToUpdate,
|
|
1050
953
|
});
|
|
1051
|
-
|
|
1052
|
-
|
|
954
|
+
const reportedIdentity = getDeviceUUID(features);
|
|
955
|
+
const deviceIdentity = reportedIdentity === 'unavailable' ? '' : reportedIdentity;
|
|
956
|
+
if (artifacts.length > 0 &&
|
|
957
|
+
(platform === 'native' || platform === 'desktop') &&
|
|
958
|
+
!deviceIdentity &&
|
|
959
|
+
!(bootloaderMode && executor === 'v2')) {
|
|
960
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Prepared firmware update requires a stable device identity', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
961
|
+
}
|
|
962
|
+
const planWithoutDigest = {
|
|
963
|
+
schemaVersion: 2,
|
|
964
|
+
executor,
|
|
965
|
+
deviceIdentity: deviceIdentity || 'unavailable',
|
|
966
|
+
deviceModel: String(getDeviceType(features)),
|
|
1053
967
|
firmwareType,
|
|
1054
968
|
platform,
|
|
1055
969
|
artifacts,
|
|
1056
970
|
targetsToUpdate,
|
|
1057
|
-
}
|
|
971
|
+
};
|
|
972
|
+
return assertFirmwareUpdatePlan(Object.assign(Object.assign({}, planWithoutDigest), { planDigest: digestFirmwareUpdatePlan(planWithoutDigest) }));
|
|
1058
973
|
};
|
|
1059
974
|
|
|
1060
975
|
const preparedPlanError = (message) => {
|
|
@@ -1175,7 +1090,7 @@ const prepareFirmwareUpdatePlan = ({ plan: value, leaseRef, artifacts, }) => {
|
|
|
1175
1090
|
return Object.assign(Object.assign({}, planWithoutDigest), { preparedPlanDigest: digestPreparedPlan(planWithoutDigest) });
|
|
1176
1091
|
};
|
|
1177
1092
|
const validateFirmwareUpdatePreparedPlan = (value) => {
|
|
1178
|
-
var _a, _b, _c
|
|
1093
|
+
var _a, _b, _c;
|
|
1179
1094
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
1180
1095
|
return preparedPlanError('Firmware prepared plan must be an object');
|
|
1181
1096
|
}
|
|
@@ -1255,13 +1170,7 @@ const validateFirmwareUpdatePreparedPlan = (value) => {
|
|
|
1255
1170
|
artifactIds.add(artifact.artifactId);
|
|
1256
1171
|
artifactTargets.add(artifact.target);
|
|
1257
1172
|
assertFirmwareArtifactReference(artifact.artifact);
|
|
1258
|
-
|
|
1259
|
-
assertPreparedEntry(entry);
|
|
1260
|
-
return getFirmwareUpdateResourceName(entry.entryName).toLowerCase();
|
|
1261
|
-
})) !== null && _d !== void 0 ? _d : [];
|
|
1262
|
-
if (new Set(materializedEntryNames).size !== materializedEntryNames.length) {
|
|
1263
|
-
return preparedPlanError('Firmware prepared plan contains duplicate entry names');
|
|
1264
|
-
}
|
|
1173
|
+
(_c = artifact.materializedEntries) === null || _c === void 0 ? void 0 : _c.forEach(assertPreparedEntry);
|
|
1265
1174
|
}
|
|
1266
1175
|
if (preparedPlan.targetsToUpdate.some(target => !FIRMWARE_UPDATE_PLAN_TARGETS.has(target)) ||
|
|
1267
1176
|
new Set(preparedPlan.targetsToUpdate).size !== preparedPlan.targetsToUpdate.length ||
|
|
@@ -1295,7 +1204,7 @@ const assertFirmwareUpdatePreparedPlanDeviceIdentity = ({ preparedPlan: value, d
|
|
|
1295
1204
|
}
|
|
1296
1205
|
const pinnedIdentity = degradedPlanIdentityPins.get(preparedPlan.leaseRef);
|
|
1297
1206
|
if (!deviceIdentity) {
|
|
1298
|
-
if (
|
|
1207
|
+
if (bootloaderMode !== true) {
|
|
1299
1208
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
1300
1209
|
}
|
|
1301
1210
|
return preparedPlan;
|
|
@@ -1368,8 +1277,6 @@ class FirmwareHostBindingRegistry {
|
|
|
1368
1277
|
register(binding) {
|
|
1369
1278
|
var _a;
|
|
1370
1279
|
if (!binding ||
|
|
1371
|
-
typeof binding.preparedPlanDigest !== 'string' ||
|
|
1372
|
-
!/^[0-9a-f]{64}$/i.test(binding.preparedPlanDigest) ||
|
|
1373
1280
|
typeof ((_a = binding.artifactReader) === null || _a === void 0 ? void 0 : _a.open) !== 'function' ||
|
|
1374
1281
|
typeof binding.artifactReader.read !== 'function' ||
|
|
1375
1282
|
typeof binding.artifactReader.close !== 'function') {
|
|
@@ -1390,7 +1297,7 @@ class FirmwareHostBindingRegistry {
|
|
|
1390
1297
|
getGeneration() {
|
|
1391
1298
|
return this.generation;
|
|
1392
1299
|
}
|
|
1393
|
-
resolve(generation
|
|
1300
|
+
resolve(generation) {
|
|
1394
1301
|
if (!Number.isSafeInteger(generation) ||
|
|
1395
1302
|
generation <= 0 ||
|
|
1396
1303
|
generation !== this.generation ||
|
|
@@ -1398,17 +1305,12 @@ class FirmwareHostBindingRegistry {
|
|
|
1398
1305
|
return bindingError(`Firmware host binding generation ${generation} is stale`);
|
|
1399
1306
|
}
|
|
1400
1307
|
const { binding } = this;
|
|
1401
|
-
if (preparedPlanDigest !== undefined &&
|
|
1402
|
-
binding.preparedPlanDigest.toLowerCase() !== preparedPlanDigest.toLowerCase()) {
|
|
1403
|
-
return bindingError(`Firmware host binding generation ${generation} does not match the prepared plan`);
|
|
1404
|
-
}
|
|
1405
1308
|
const assertCurrent = () => {
|
|
1406
1309
|
if (generation !== this.generation || binding !== this.binding) {
|
|
1407
1310
|
bindingError(`Firmware host binding generation ${generation} is stale`);
|
|
1408
1311
|
}
|
|
1409
1312
|
};
|
|
1410
1313
|
return {
|
|
1411
|
-
preparedPlanDigest: binding.preparedPlanDigest,
|
|
1412
1314
|
artifactReader: {
|
|
1413
1315
|
open: (input) => __awaiter(this, void 0, void 0, function* () {
|
|
1414
1316
|
assertCurrent();
|
|
@@ -1441,7 +1343,7 @@ const firmwareHostBindingRegistry = new FirmwareHostBindingRegistry();
|
|
|
1441
1343
|
const registerFirmwareUpdateHostBinding = (binding) => firmwareHostBindingRegistry.register(binding);
|
|
1442
1344
|
const unregisterFirmwareUpdateHostBinding = (generation) => firmwareHostBindingRegistry.unregister(generation);
|
|
1443
1345
|
const getFirmwareUpdateHostBindingGeneration = () => firmwareHostBindingRegistry.getGeneration();
|
|
1444
|
-
const resolveFirmwareUpdateHostBinding = (generation
|
|
1346
|
+
const resolveFirmwareUpdateHostBinding = (generation) => firmwareHostBindingRegistry.resolve(generation !== null && generation !== void 0 ? generation : Number.NaN);
|
|
1445
1347
|
|
|
1446
1348
|
const callbackManager = new Map();
|
|
1447
1349
|
const generateCallbackId = () => `callback_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
@@ -40602,8 +40504,143 @@ const findLatestRelease = (releases) => {
|
|
|
40602
40504
|
return leastRelease;
|
|
40603
40505
|
};
|
|
40604
40506
|
|
|
40605
|
-
const
|
|
40507
|
+
const PROTOCOL_V2_RESOURCE_TYPES = [
|
|
40508
|
+
'images',
|
|
40509
|
+
'animation',
|
|
40510
|
+
'wallpaper',
|
|
40511
|
+
'translations',
|
|
40512
|
+
'roobert',
|
|
40513
|
+
'noto',
|
|
40514
|
+
'firmware_logo',
|
|
40515
|
+
];
|
|
40516
|
+
const PROTOCOL_V2_RESOURCE_DEVICE_PATHS = {
|
|
40517
|
+
images: 'vol0:/bundles/images/images.okpkg',
|
|
40518
|
+
animation: 'vol0:/bundles/images/animation.okpkg',
|
|
40519
|
+
wallpaper: 'vol0:/bundles/images/wallpaper.okpkg',
|
|
40520
|
+
translations: 'vol0:/bundles/translations/translations.okpkg',
|
|
40521
|
+
roobert: 'vol0:/bundles/font/roobert.okpkg',
|
|
40522
|
+
noto: 'vol0:/bundles/font/noto.okpkg',
|
|
40523
|
+
firmware_logo: 'vol0:/bundles/firmware_logo.okpkg',
|
|
40524
|
+
};
|
|
40525
|
+
const RESOURCE_TYPE_SET = new Set(PROTOCOL_V2_RESOURCE_TYPES);
|
|
40606
40526
|
const SHA256_HEX_LENGTH = 64;
|
|
40527
|
+
const SHA3_512_HEX_LENGTH = 128;
|
|
40528
|
+
const PROTOCOL_V2_OKPP_HEADER_SIZE$1 = 0x52a0;
|
|
40529
|
+
const PROTOCOL_V2_OKPP_TYPE_OFFSET = 0x08;
|
|
40530
|
+
const PROTOCOL_V2_OKPP_HEADER_LENGTH_OFFSET = 0x0c;
|
|
40531
|
+
const PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET$1 = 0x240;
|
|
40532
|
+
const PROTOCOL_V2_OKPP_HASH_SIZE$1 = 64;
|
|
40533
|
+
const PROTOCOL_V2_RESOURCE_IDENTITY_READ_SIZE = PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET$1 + PROTOCOL_V2_OKPP_HASH_SIZE$1;
|
|
40534
|
+
const PROTOCOL_V2_MIN_FILE_READ_CHUNK_SIZE = 64;
|
|
40535
|
+
const PROTOCOL_V2_RESOURCE_INVENTORY_TIMEOUT_MS = 5 * 1000;
|
|
40536
|
+
function toFiniteNumber(value) {
|
|
40537
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
40538
|
+
return value;
|
|
40539
|
+
if (typeof value === 'string') {
|
|
40540
|
+
const numeric = Number(value);
|
|
40541
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
40542
|
+
}
|
|
40543
|
+
if (value && typeof value === 'object') {
|
|
40544
|
+
const longLike = value;
|
|
40545
|
+
if (typeof longLike.toNumber === 'function') {
|
|
40546
|
+
const numeric = longLike.toNumber();
|
|
40547
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
40548
|
+
}
|
|
40549
|
+
}
|
|
40550
|
+
return undefined;
|
|
40551
|
+
}
|
|
40552
|
+
function toUint8Array(value) {
|
|
40553
|
+
if (value instanceof Uint8Array)
|
|
40554
|
+
return value;
|
|
40555
|
+
if (value instanceof ArrayBuffer)
|
|
40556
|
+
return new Uint8Array(value);
|
|
40557
|
+
if (ArrayBuffer.isView(value)) {
|
|
40558
|
+
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
40559
|
+
}
|
|
40560
|
+
if (typeof value === 'string') {
|
|
40561
|
+
const hex = value.replace(/^0x/i, '');
|
|
40562
|
+
if (!hex || hex.length % 2 !== 0 || /[^0-9a-f]/i.test(hex)) {
|
|
40563
|
+
return new Uint8Array(0);
|
|
40564
|
+
}
|
|
40565
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
40566
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
40567
|
+
bytes[index] = Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16);
|
|
40568
|
+
}
|
|
40569
|
+
return bytes;
|
|
40570
|
+
}
|
|
40571
|
+
return new Uint8Array(0);
|
|
40572
|
+
}
|
|
40573
|
+
function readAscii(bytes, offset, length) {
|
|
40574
|
+
return Array.from(bytes.slice(offset, offset + length), byte => String.fromCharCode(byte)).join('');
|
|
40575
|
+
}
|
|
40576
|
+
function parseProtocolV2ResourceHeaderHash(bytes) {
|
|
40577
|
+
if (bytes.byteLength < PROTOCOL_V2_RESOURCE_IDENTITY_READ_SIZE)
|
|
40578
|
+
return undefined;
|
|
40579
|
+
if (readAscii(bytes, 0, 4) !== 'OKPP')
|
|
40580
|
+
return undefined;
|
|
40581
|
+
if (readAscii(bytes, PROTOCOL_V2_OKPP_TYPE_OFFSET, 4) !== 'RESC')
|
|
40582
|
+
return undefined;
|
|
40583
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
40584
|
+
if (view.getUint32(PROTOCOL_V2_OKPP_HEADER_LENGTH_OFFSET, true) !== PROTOCOL_V2_OKPP_HEADER_SIZE$1) {
|
|
40585
|
+
return undefined;
|
|
40586
|
+
}
|
|
40587
|
+
return bytesToHex$3(bytes.slice(PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET$1, PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET$1 + PROTOCOL_V2_OKPP_HASH_SIZE$1));
|
|
40588
|
+
}
|
|
40589
|
+
function readProtocolV2ResourceIdentity({ commands, resource, chunkSize, timeoutMs = PROTOCOL_V2_RESOURCE_INVENTORY_TIMEOUT_MS, }) {
|
|
40590
|
+
var _a, _b, _c, _d;
|
|
40591
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40592
|
+
const path = PROTOCOL_V2_RESOURCE_DEVICE_PATHS[resource.type];
|
|
40593
|
+
const pathInfo = yield commands.typedCall('FilesystemPathInfoQuery', 'FilesystemPathInfo', { path }, { timeoutMs });
|
|
40594
|
+
const size = toFiniteNumber((_a = pathInfo.message) === null || _a === void 0 ? void 0 : _a.size);
|
|
40595
|
+
if (!((_b = pathInfo.message) === null || _b === void 0 ? void 0 : _b.exist) ||
|
|
40596
|
+
((_c = pathInfo.message) === null || _c === void 0 ? void 0 : _c.directory) ||
|
|
40597
|
+
!Number.isSafeInteger(size) ||
|
|
40598
|
+
size !== resource.size ||
|
|
40599
|
+
size < PROTOCOL_V2_OKPP_HEADER_SIZE$1) {
|
|
40600
|
+
return undefined;
|
|
40601
|
+
}
|
|
40602
|
+
const header = new Uint8Array(PROTOCOL_V2_RESOURCE_IDENTITY_READ_SIZE);
|
|
40603
|
+
let offset = 0;
|
|
40604
|
+
while (offset < header.byteLength) {
|
|
40605
|
+
const readLength = Math.min(chunkSize, header.byteLength - offset);
|
|
40606
|
+
const response = yield commands.typedCall('FilesystemFileRead', 'FilesystemFile', {
|
|
40607
|
+
file: { path, offset, total_size: 0 },
|
|
40608
|
+
chunk_len: readLength,
|
|
40609
|
+
}, { timeoutMs });
|
|
40610
|
+
const data = toUint8Array((_d = response.message) === null || _d === void 0 ? void 0 : _d.data);
|
|
40611
|
+
if (data.byteLength === 0)
|
|
40612
|
+
return undefined;
|
|
40613
|
+
const copied = Math.min(data.byteLength, header.byteLength - offset);
|
|
40614
|
+
header.set(data.subarray(0, copied), offset);
|
|
40615
|
+
offset += copied;
|
|
40616
|
+
}
|
|
40617
|
+
const headerHash = parseProtocolV2ResourceHeaderHash(header);
|
|
40618
|
+
return headerHash ? { type: resource.type, size, headerHash } : undefined;
|
|
40619
|
+
});
|
|
40620
|
+
}
|
|
40621
|
+
function readProtocolV2ResourceInventory({ commands, resources, chunkSize = hdTransport.PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE, timeoutMs = PROTOCOL_V2_RESOURCE_INVENTORY_TIMEOUT_MS, }) {
|
|
40622
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40623
|
+
const normalizedChunkSize = Number.isFinite(chunkSize)
|
|
40624
|
+
? Math.max(Math.floor(chunkSize), PROTOCOL_V2_MIN_FILE_READ_CHUNK_SIZE)
|
|
40625
|
+
: hdTransport.PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE;
|
|
40626
|
+
const inventory = [];
|
|
40627
|
+
for (const resource of resources) {
|
|
40628
|
+
try {
|
|
40629
|
+
const item = yield readProtocolV2ResourceIdentity({
|
|
40630
|
+
commands,
|
|
40631
|
+
resource,
|
|
40632
|
+
chunkSize: normalizedChunkSize,
|
|
40633
|
+
timeoutMs,
|
|
40634
|
+
});
|
|
40635
|
+
if (item)
|
|
40636
|
+
inventory.push(item);
|
|
40637
|
+
}
|
|
40638
|
+
catch (_a) {
|
|
40639
|
+
}
|
|
40640
|
+
}
|
|
40641
|
+
return inventory;
|
|
40642
|
+
});
|
|
40643
|
+
}
|
|
40607
40644
|
function normalizeHex$1(value, expectedLength, field) {
|
|
40608
40645
|
if (typeof value !== 'string') {
|
|
40609
40646
|
throw new Error(`Invalid Pro2 resource ${field}: expected a hexadecimal string`);
|
|
@@ -40614,158 +40651,132 @@ function normalizeHex$1(value, expectedLength, field) {
|
|
|
40614
40651
|
}
|
|
40615
40652
|
return normalized;
|
|
40616
40653
|
}
|
|
40617
|
-
function
|
|
40618
|
-
if (value === undefined)
|
|
40619
|
-
return undefined;
|
|
40654
|
+
function validateResource(value, index) {
|
|
40620
40655
|
if (!value || typeof value !== 'object') {
|
|
40621
|
-
throw new Error(
|
|
40622
|
-
}
|
|
40623
|
-
const { source } = value;
|
|
40624
|
-
if (!source || typeof source !== 'object') {
|
|
40625
|
-
throw new Error('Invalid Pro2 resources config: source is required');
|
|
40656
|
+
throw new Error(`Invalid Pro2 resource at stable[${index}]`);
|
|
40626
40657
|
}
|
|
40627
|
-
const
|
|
40628
|
-
if (typeof
|
|
40629
|
-
throw new Error(
|
|
40658
|
+
const resource = value;
|
|
40659
|
+
if (typeof resource.type !== 'string' || !RESOURCE_TYPE_SET.has(resource.type)) {
|
|
40660
|
+
throw new Error(`Invalid Pro2 resource type at stable[${index}]`);
|
|
40630
40661
|
}
|
|
40631
|
-
if (typeof
|
|
40632
|
-
throw new Error(
|
|
40662
|
+
if (typeof resource.url !== 'string' || !resource.url.startsWith('https://')) {
|
|
40663
|
+
throw new Error(`Invalid Pro2 resource url at stable[${index}]`);
|
|
40633
40664
|
}
|
|
40634
|
-
if (!Number.isSafeInteger(
|
|
40635
|
-
throw new Error(
|
|
40665
|
+
if (!Number.isSafeInteger(resource.size) || Number(resource.size) <= 0) {
|
|
40666
|
+
throw new Error(`Invalid Pro2 resource size at stable[${index}]`);
|
|
40636
40667
|
}
|
|
40637
40668
|
return {
|
|
40638
|
-
|
|
40639
|
-
|
|
40640
|
-
|
|
40641
|
-
|
|
40642
|
-
|
|
40669
|
+
type: resource.type,
|
|
40670
|
+
url: resource.url,
|
|
40671
|
+
size: Number(resource.size),
|
|
40672
|
+
fileHash: normalizeHex$1(resource.fileHash, SHA256_HEX_LENGTH, 'fileHash'),
|
|
40673
|
+
headerHash: normalizeHex$1(resource.headerHash, SHA3_512_HEX_LENGTH, 'headerHash'),
|
|
40643
40674
|
};
|
|
40644
40675
|
}
|
|
40645
|
-
|
|
40646
|
-
'
|
|
40647
|
-
|
|
40648
|
-
];
|
|
40649
|
-
function isAllowedManifestDevicePath(path) {
|
|
40650
|
-
if (!path.endsWith('.okpkg') ||
|
|
40651
|
-
path.includes('\\') ||
|
|
40652
|
-
path.includes('//') ||
|
|
40653
|
-
path.split('/').some(part => part === '.' || part === '..')) {
|
|
40654
|
-
return false;
|
|
40676
|
+
function validateBootResources(value) {
|
|
40677
|
+
if (!value || typeof value !== 'object') {
|
|
40678
|
+
throw new Error('Invalid Pro2 boot resources config');
|
|
40655
40679
|
}
|
|
40656
|
-
|
|
40657
|
-
|
|
40680
|
+
const resource = value;
|
|
40681
|
+
if (resource.required !== false) {
|
|
40682
|
+
throw new Error('Invalid Pro2 boot resources required flag: expected false');
|
|
40658
40683
|
}
|
|
40659
|
-
|
|
40660
|
-
|
|
40661
|
-
function assertManifestString(value, field) {
|
|
40662
|
-
if (typeof value !== 'string' || value.length === 0) {
|
|
40663
|
-
throw new Error(`Invalid Pro2 resource manifest ${field}`);
|
|
40684
|
+
if (resource.target !== 'RES') {
|
|
40685
|
+
throw new Error('Invalid Pro2 boot resources target: expected RES');
|
|
40664
40686
|
}
|
|
40665
|
-
|
|
40666
|
-
|
|
40667
|
-
|
|
40668
|
-
const path = assertManifestString(value, field);
|
|
40669
|
-
if (path.startsWith('/') ||
|
|
40670
|
-
path.includes('\\') ||
|
|
40671
|
-
path.includes(':') ||
|
|
40672
|
-
path.split('/').some(part => !part || part === '.' || part === '..')) {
|
|
40673
|
-
throw new Error(`Invalid Pro2 resource manifest ${field}`);
|
|
40674
|
-
}
|
|
40675
|
-
return path;
|
|
40676
|
-
}
|
|
40677
|
-
function parseProtocolV2ResourceManifestFile(value, index) {
|
|
40678
|
-
var _a;
|
|
40679
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
40680
|
-
throw new Error(`Invalid Pro2 resource manifest files[${index}]`);
|
|
40687
|
+
if (resource.manifestUrl !== undefined &&
|
|
40688
|
+
(typeof resource.manifestUrl !== 'string' || !resource.manifestUrl.startsWith('https://'))) {
|
|
40689
|
+
throw new Error('Invalid Pro2 boot resources manifestUrl');
|
|
40681
40690
|
}
|
|
40682
|
-
|
|
40683
|
-
|
|
40684
|
-
const originalName = assertManifestRelativePath(file.original_name, `files[${index}].original_name`);
|
|
40685
|
-
if (originalName.includes('/')) {
|
|
40686
|
-
throw new Error(`Invalid Pro2 resource manifest files[${index}].original_name`);
|
|
40691
|
+
if (!Array.isArray(resource.files) || resource.files.length === 0) {
|
|
40692
|
+
throw new Error('Invalid Pro2 boot resources files');
|
|
40687
40693
|
}
|
|
40688
|
-
const
|
|
40689
|
-
|
|
40690
|
-
|
|
40694
|
+
const files = resource.files.map((value, index) => {
|
|
40695
|
+
if (!value || typeof value !== 'object') {
|
|
40696
|
+
throw new Error(`Invalid Pro2 boot resource file at files[${index}]`);
|
|
40697
|
+
}
|
|
40698
|
+
const file = value;
|
|
40699
|
+
if (typeof file.url !== 'string' || !file.url.startsWith('https://')) {
|
|
40700
|
+
throw new Error(`Invalid Pro2 boot resource url at files[${index}]`);
|
|
40701
|
+
}
|
|
40702
|
+
if (typeof file.devicePath !== 'string' ||
|
|
40703
|
+
!file.devicePath.startsWith('vol0:/') ||
|
|
40704
|
+
file.devicePath.includes('..') ||
|
|
40705
|
+
file.devicePath.includes('\\')) {
|
|
40706
|
+
throw new Error(`Invalid Pro2 boot resource devicePath at files[${index}]`);
|
|
40707
|
+
}
|
|
40708
|
+
if (!Number.isSafeInteger(file.size) || Number(file.size) <= 0) {
|
|
40709
|
+
throw new Error(`Invalid Pro2 boot resource size at files[${index}]`);
|
|
40710
|
+
}
|
|
40711
|
+
return Object.assign(Object.assign({}, (typeof file.name === 'string' && file.name ? { name: file.name } : undefined)), { url: file.url, devicePath: file.devicePath, size: Number(file.size), fileHash: normalizeHex$1(file.fileHash, SHA256_HEX_LENGTH, `boot files[${index}].fileHash`) });
|
|
40712
|
+
});
|
|
40713
|
+
if (new Set(files.map(file => file.devicePath)).size !== files.length) {
|
|
40714
|
+
throw new Error('Invalid Pro2 boot resources files: duplicate devicePath');
|
|
40691
40715
|
}
|
|
40692
|
-
|
|
40693
|
-
|
|
40716
|
+
return Object.assign(Object.assign({ required: false, target: 'RES' }, (resource.manifestUrl ? { manifestUrl: resource.manifestUrl } : undefined)), { files });
|
|
40717
|
+
}
|
|
40718
|
+
function parseProtocolV2Resources(value) {
|
|
40719
|
+
if (value === undefined)
|
|
40720
|
+
return undefined;
|
|
40721
|
+
if (!value ||
|
|
40722
|
+
typeof value !== 'object' ||
|
|
40723
|
+
!Array.isArray(value.stable)) {
|
|
40724
|
+
throw new Error('Invalid Pro2 resources config: stable must be an array');
|
|
40694
40725
|
}
|
|
40695
|
-
const
|
|
40696
|
-
|
|
40697
|
-
|
|
40726
|
+
const config = value;
|
|
40727
|
+
const stable = config.stable.map(validateResource);
|
|
40728
|
+
const types = new Set(stable.map(resource => resource.type));
|
|
40729
|
+
if (stable.length !== PROTOCOL_V2_RESOURCE_TYPES.length || types.size !== stable.length) {
|
|
40730
|
+
throw new Error(`Invalid Pro2 resources config: stable must contain ${PROTOCOL_V2_RESOURCE_TYPES.length} unique resource types`);
|
|
40698
40731
|
}
|
|
40699
|
-
|
|
40700
|
-
|
|
40732
|
+
for (const type of PROTOCOL_V2_RESOURCE_TYPES) {
|
|
40733
|
+
if (!types.has(type)) {
|
|
40734
|
+
throw new Error(`Invalid Pro2 resources config: stable is missing ${type}`);
|
|
40735
|
+
}
|
|
40701
40736
|
}
|
|
40702
|
-
|
|
40703
|
-
|
|
40737
|
+
const boot = config.boot === undefined ? undefined : validateBootResources(config.boot);
|
|
40738
|
+
return Object.assign({ stable: PROTOCOL_V2_RESOURCE_TYPES.map(type => {
|
|
40739
|
+
const resource = stable.find(item => item.type === type);
|
|
40740
|
+
if (!resource) {
|
|
40741
|
+
throw new Error(`Invalid Pro2 resources config: stable is missing ${type}`);
|
|
40742
|
+
}
|
|
40743
|
+
return resource;
|
|
40744
|
+
}) }, (boot ? { boot } : undefined));
|
|
40745
|
+
}
|
|
40746
|
+
function buildProtocolV2ResourceUpdatePlan({ resources, inventory, mode, forced = false, }) {
|
|
40747
|
+
if (forced) {
|
|
40748
|
+
return {
|
|
40749
|
+
status: resources.length > 0 ? 'outdated' : 'valid',
|
|
40750
|
+
resources: [...resources],
|
|
40751
|
+
};
|
|
40704
40752
|
}
|
|
40705
|
-
if (!
|
|
40706
|
-
|
|
40753
|
+
if (!inventory) {
|
|
40754
|
+
return mode === 'bootloader-recovery'
|
|
40755
|
+
? {
|
|
40756
|
+
status: resources.length > 0 ? 'outdated' : 'valid',
|
|
40757
|
+
resources: [...resources],
|
|
40758
|
+
}
|
|
40759
|
+
: { status: 'unknown', resources: [] };
|
|
40707
40760
|
}
|
|
40761
|
+
const inventoryByType = new Map(inventory.map(item => [item.type, item]));
|
|
40762
|
+
const changedResources = resources.filter(resource => {
|
|
40763
|
+
const current = inventoryByType.get(resource.type);
|
|
40764
|
+
return (!current ||
|
|
40765
|
+
current.size !== resource.size ||
|
|
40766
|
+
current.headerHash.toLowerCase() !== resource.headerHash.toLowerCase());
|
|
40767
|
+
});
|
|
40708
40768
|
return {
|
|
40709
|
-
|
|
40710
|
-
|
|
40711
|
-
device_path: devicePath,
|
|
40712
|
-
size: Number(file.size),
|
|
40713
|
-
sha256: digest,
|
|
40714
|
-
signed: true,
|
|
40715
|
-
sig_algo: file.sig_algo,
|
|
40716
|
-
payload_version: (_a = file.payload_version) !== null && _a !== void 0 ? _a : null,
|
|
40769
|
+
status: changedResources.length === 0 ? 'valid' : 'outdated',
|
|
40770
|
+
resources: changedResources,
|
|
40717
40771
|
};
|
|
40718
40772
|
}
|
|
40719
|
-
function
|
|
40720
|
-
|
|
40721
|
-
throw new Error('Invalid Pro2 resource manifest');
|
|
40722
|
-
}
|
|
40723
|
-
const manifest = value;
|
|
40724
|
-
if (manifest.schema !== 1 ||
|
|
40725
|
-
manifest.variant !== 'resource' ||
|
|
40726
|
-
manifest.device_root !== 'vol0:' ||
|
|
40727
|
-
manifest.restore_mode !== 'bootloader_update' ||
|
|
40728
|
-
!Array.isArray(manifest.trees) ||
|
|
40729
|
-
!Array.isArray(manifest.files)) {
|
|
40730
|
-
throw new Error('Invalid Pro2 resource manifest contract');
|
|
40731
|
-
}
|
|
40732
|
-
const files = manifest.files.map(parseProtocolV2ResourceManifestFile);
|
|
40733
|
-
const devicePaths = new Set(files.map(file => file.device_path));
|
|
40734
|
-
const archivePaths = new Set(files.map(file => file.archive_path));
|
|
40735
|
-
if (files.length === 0 ||
|
|
40736
|
-
devicePaths.size !== files.length ||
|
|
40737
|
-
archivePaths.size !== files.length ||
|
|
40738
|
-
!devicePaths.has(PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH$1) ||
|
|
40739
|
-
!files.some(file => file.device_path.startsWith('vol0:/bundles/'))) {
|
|
40740
|
-
throw new Error('Invalid Pro2 resource manifest file set');
|
|
40741
|
-
}
|
|
40742
|
-
return {
|
|
40743
|
-
schema: 1,
|
|
40744
|
-
artifact_name: assertManifestString(manifest.artifact_name, 'artifact_name'),
|
|
40745
|
-
release_name: assertManifestString(manifest.release_name, 'release_name'),
|
|
40746
|
-
variant: 'resource',
|
|
40747
|
-
commit: assertManifestString(manifest.commit, 'commit'),
|
|
40748
|
-
short_sha: assertManifestString(manifest.short_sha, 'short_sha'),
|
|
40749
|
-
timestamp_utc: assertManifestString(manifest.timestamp_utc, 'timestamp_utc'),
|
|
40750
|
-
core_version: assertManifestString(manifest.core_version, 'core_version'),
|
|
40751
|
-
key_set: assertManifestString(manifest.key_set, 'key_set'),
|
|
40752
|
-
device_root: 'vol0:',
|
|
40753
|
-
restore_mode: 'bootloader_update',
|
|
40754
|
-
trees: manifest.trees.map((tree, index) => {
|
|
40755
|
-
if (!tree || typeof tree !== 'object') {
|
|
40756
|
-
throw new Error(`Invalid Pro2 resource manifest trees[${index}]`);
|
|
40757
|
-
}
|
|
40758
|
-
const item = tree;
|
|
40759
|
-
return {
|
|
40760
|
-
path: assertManifestRelativePath(item.path, `trees[${index}].path`),
|
|
40761
|
-
device: assertManifestString(item.device, `trees[${index}].device`),
|
|
40762
|
-
};
|
|
40763
|
-
}),
|
|
40764
|
-
files,
|
|
40765
|
-
};
|
|
40773
|
+
function bytesToHex$3(bytes) {
|
|
40774
|
+
return Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');
|
|
40766
40775
|
}
|
|
40767
|
-
function
|
|
40768
|
-
|
|
40776
|
+
function isProtocolV2ResourceFileValid(binary, resource) {
|
|
40777
|
+
if (binary.byteLength !== resource.size)
|
|
40778
|
+
return false;
|
|
40779
|
+
return bytesToHex$3(sha256.sha256(new Uint8Array(binary))) === resource.fileHash.toLowerCase();
|
|
40769
40780
|
}
|
|
40770
40781
|
|
|
40771
40782
|
var _a$1;
|
|
@@ -40826,7 +40837,6 @@ class DataManager {
|
|
|
40826
40837
|
return __awaiter(this, void 0, void 0, function* () {
|
|
40827
40838
|
this.settings = settings;
|
|
40828
40839
|
this.protocolV2ResourcesConfigError = undefined;
|
|
40829
|
-
this.protocolV2NeoResourcesConfigError = undefined;
|
|
40830
40840
|
const manifestMode = (_b = settings.firmwareManifestMode) !== null && _b !== void 0 ? _b : (settings.fetchConfig ? 'sdk-managed' : undefined);
|
|
40831
40841
|
if (settings.preloadedConfig) {
|
|
40832
40842
|
this.applyRemoteConfig(settings.preloadedConfig);
|
|
@@ -40887,19 +40897,12 @@ class DataManager {
|
|
|
40887
40897
|
let neoResources;
|
|
40888
40898
|
try {
|
|
40889
40899
|
pro2Resources = parseProtocolV2Resources((_b = data.pro2) === null || _b === void 0 ? void 0 : _b.resources);
|
|
40890
|
-
}
|
|
40891
|
-
catch (error) {
|
|
40892
|
-
this.protocolV2ResourcesConfigError =
|
|
40893
|
-
error instanceof Error ? error : new Error(String(error));
|
|
40894
|
-
Log$k.warn('[DataConfig] Ignoring invalid Pro2 resources config:', error);
|
|
40895
|
-
}
|
|
40896
|
-
try {
|
|
40897
40900
|
neoResources = parseProtocolV2Resources((_c = data.neo) === null || _c === void 0 ? void 0 : _c.resources);
|
|
40898
40901
|
}
|
|
40899
40902
|
catch (error) {
|
|
40900
|
-
this.
|
|
40903
|
+
this.protocolV2ResourcesConfigError =
|
|
40901
40904
|
error instanceof Error ? error : new Error(String(error));
|
|
40902
|
-
Log$k.warn('[DataConfig] Ignoring invalid
|
|
40905
|
+
Log$k.warn('[DataConfig] Ignoring invalid Protocol V2 resources config:', error);
|
|
40903
40906
|
}
|
|
40904
40907
|
const enrichedPro2Config = this.enrichFirmwareReleaseInfo(data.pro2);
|
|
40905
40908
|
const enrichedNeoConfig = this.enrichFirmwareReleaseInfo(data.neo);
|
|
@@ -40937,20 +40940,16 @@ class DataManager {
|
|
|
40937
40940
|
}
|
|
40938
40941
|
});
|
|
40939
40942
|
}
|
|
40940
|
-
static forceReloadData({ requireResources = false,
|
|
40943
|
+
static forceReloadData({ requireResources = false, } = {}) {
|
|
40941
40944
|
return __awaiter(this, void 0, void 0, function* () {
|
|
40942
|
-
const resourceDeviceName = resourceDeviceType === hdShared.EDeviceType.Pro2 ? 'Pro2' : 'Neo';
|
|
40943
40945
|
if (!this.settings) {
|
|
40944
40946
|
throw new Error('Remote config settings are not initialized');
|
|
40945
40947
|
}
|
|
40946
40948
|
const hasFreshConfig = this.lastCheckTimestamp > 0 &&
|
|
40947
40949
|
getTimeStamp() - this.lastCheckTimestamp <= FIRMWARE_UPDATE_CONFIG_FRESHNESS_MS;
|
|
40948
40950
|
if (hasFreshConfig) {
|
|
40949
|
-
|
|
40950
|
-
|
|
40951
|
-
: this.protocolV2NeoResourcesConfigError;
|
|
40952
|
-
if (requireResources && resourcesConfigError) {
|
|
40953
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, `Invalid ${resourceDeviceName} resources config: ${resourcesConfigError.message}`);
|
|
40951
|
+
if (requireResources && this.protocolV2ResourcesConfigError) {
|
|
40952
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, `Invalid Pro2 resources config: ${this.protocolV2ResourcesConfigError.message}`);
|
|
40954
40953
|
}
|
|
40955
40954
|
return;
|
|
40956
40955
|
}
|
|
@@ -40958,18 +40957,19 @@ class DataManager {
|
|
|
40958
40957
|
if (!loaded) {
|
|
40959
40958
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.NetworkError, 'Unable to refresh the latest remote config');
|
|
40960
40959
|
}
|
|
40961
|
-
|
|
40962
|
-
|
|
40963
|
-
: this.protocolV2NeoResourcesConfigError;
|
|
40964
|
-
if (requireResources && resourcesConfigError) {
|
|
40965
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, `Invalid ${resourceDeviceName} resources config: ${resourcesConfigError.message}`);
|
|
40960
|
+
if (requireResources && this.protocolV2ResourcesConfigError) {
|
|
40961
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, `Invalid Pro2 resources config: ${this.protocolV2ResourcesConfigError.message}`);
|
|
40966
40962
|
}
|
|
40967
40963
|
this.lastCheckTimestamp = getTimeStamp();
|
|
40968
40964
|
});
|
|
40969
40965
|
}
|
|
40970
|
-
static
|
|
40966
|
+
static getProtocolV2Resources(deviceType = hdShared.EDeviceType.Pro2) {
|
|
40967
|
+
var _b, _c;
|
|
40968
|
+
return (_c = (_b = this.deviceMap[deviceType]) === null || _b === void 0 ? void 0 : _b.resources) === null || _c === void 0 ? void 0 : _c.stable;
|
|
40969
|
+
}
|
|
40970
|
+
static getProtocolV2BootResources(deviceType = hdShared.EDeviceType.Pro2) {
|
|
40971
40971
|
var _b, _c;
|
|
40972
|
-
return (_c = (_b = this.deviceMap[deviceType]) === null || _b === void 0 ? void 0 : _b.resources) === null || _c === void 0 ? void 0 : _c.
|
|
40972
|
+
return (_c = (_b = this.deviceMap[deviceType]) === null || _b === void 0 ? void 0 : _b.resources) === null || _c === void 0 ? void 0 : _c.boot;
|
|
40973
40973
|
}
|
|
40974
40974
|
static getProtobufMessages(schema = 'v1CurrentSchema') {
|
|
40975
40975
|
return this.messages[schema];
|
|
@@ -41006,10 +41006,12 @@ DataManager.deviceMap = {
|
|
|
41006
41006
|
ble: [],
|
|
41007
41007
|
},
|
|
41008
41008
|
[hdShared.EDeviceType.Pro2]: {
|
|
41009
|
-
|
|
41009
|
+
firmware: [],
|
|
41010
|
+
ble: [],
|
|
41010
41011
|
},
|
|
41011
41012
|
[hdShared.EDeviceType.Neo]: {
|
|
41012
|
-
|
|
41013
|
+
firmware: [],
|
|
41014
|
+
ble: [],
|
|
41013
41015
|
},
|
|
41014
41016
|
[hdShared.EDeviceType.ClassicPure]: {
|
|
41015
41017
|
firmware: [],
|
|
@@ -42006,7 +42008,7 @@ const getFirmwareUpdateField = ({ features, updateType, targetVersion, firmwareT
|
|
|
42006
42008
|
if (deviceType === hdShared.EDeviceType.Pro) {
|
|
42007
42009
|
return latestFirmwareField;
|
|
42008
42010
|
}
|
|
42009
|
-
if (deviceType === hdShared.EDeviceType.Pro2
|
|
42011
|
+
if (deviceType === hdShared.EDeviceType.Pro2) {
|
|
42010
42012
|
return 'firmware-v1';
|
|
42011
42013
|
}
|
|
42012
42014
|
return 'firmware';
|
|
@@ -42038,7 +42040,7 @@ const getFirmwareUpdateFieldArray = (features, updateType) => {
|
|
|
42038
42040
|
if (deviceType === 'pro') {
|
|
42039
42041
|
return ['firmware-v8'];
|
|
42040
42042
|
}
|
|
42041
|
-
if (deviceType === 'pro2'
|
|
42043
|
+
if (deviceType === 'pro2') {
|
|
42042
42044
|
return ['firmware-v1'];
|
|
42043
42045
|
}
|
|
42044
42046
|
return ['firmware'];
|
|
@@ -47381,93 +47383,76 @@ class ClearSessionCache extends BaseMethod {
|
|
|
47381
47383
|
}
|
|
47382
47384
|
}
|
|
47383
47385
|
|
|
47384
|
-
|
|
47385
|
-
|
|
47386
|
-
|
|
47387
|
-
|
|
47388
|
-
|
|
47389
|
-
|
|
47390
|
-
|
|
47391
|
-
|
|
47392
|
-
|
|
47393
|
-
'COPROCESSOR',
|
|
47394
|
-
];
|
|
47395
|
-
const PROTOCOL_V2_BOOTLOADER_TARGETS = [
|
|
47396
|
-
'BOOTLOADER',
|
|
47397
|
-
];
|
|
47398
|
-
function loadProtocolV2FirmwareReleaseContext({ device, firmwareType: firmwareTypeParam, checkFirmwareHash = false, methodName, }) {
|
|
47399
|
-
var _a;
|
|
47400
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
47401
|
-
const state = yield device.getDeviceState({
|
|
47402
|
-
refreshSections: checkFirmwareHash
|
|
47403
|
-
? ['identity', 'versions', 'verification']
|
|
47404
|
-
: ['identity', 'versions'],
|
|
47405
|
-
});
|
|
47406
|
-
if (state.identity.deviceType !== 'pro2' && state.identity.deviceType !== 'neo') {
|
|
47407
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotSupportMethod, `${methodName} requires a Pro2 or Neo device for Protocol V2`);
|
|
47408
|
-
}
|
|
47409
|
-
const { features } = device;
|
|
47410
|
-
if (!features) {
|
|
47411
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `${methodName} requires initialized device features`);
|
|
47412
|
-
}
|
|
47413
|
-
const firmwareType = (_a = firmwareTypeParam !== null && firmwareTypeParam !== void 0 ? firmwareTypeParam : state.identity.firmwareType) !== null && _a !== void 0 ? _a : hdShared.EFirmwareType.Universal;
|
|
47414
|
-
return {
|
|
47415
|
-
state: state,
|
|
47416
|
-
features,
|
|
47417
|
-
firmwareType,
|
|
47418
|
-
release: DataManager.getFirmwareLatestRelease(features, firmwareType),
|
|
47419
|
-
};
|
|
47420
|
-
});
|
|
47421
|
-
}
|
|
47422
|
-
function summarizeProtocolV2FirmwareRelease(plan, componentTargets) {
|
|
47423
|
-
var _a;
|
|
47424
|
-
const targetSet = new Set(componentTargets);
|
|
47425
|
-
const components = plan.components.filter(component => targetSet.has(component.componentTarget));
|
|
47426
|
-
const targetsToUpdate = Array.from(new Set(components.flatMap(component => component.status === 'outdated' && component.updateTarget ? [component.updateTarget] : [])));
|
|
47427
|
-
const hasUpgrade = targetsToUpdate.length > 0;
|
|
47428
|
-
const required = !!((_a = plan.release) === null || _a === void 0 ? void 0 : _a.required) && hasUpgrade;
|
|
47429
|
-
let status = 'valid';
|
|
47430
|
-
if (!plan.release || components.length === 0) {
|
|
47431
|
-
status = 'unavailable';
|
|
47432
|
-
}
|
|
47433
|
-
else if (required) {
|
|
47434
|
-
status = 'required';
|
|
47386
|
+
class CheckFirmwareRelease extends BaseMethod {
|
|
47387
|
+
init() {
|
|
47388
|
+
this.allowDeviceMode = [
|
|
47389
|
+
...this.allowDeviceMode,
|
|
47390
|
+
UI_REQUEST.NOT_INITIALIZE,
|
|
47391
|
+
UI_REQUEST.BOOTLOADER,
|
|
47392
|
+
];
|
|
47393
|
+
this.useDevicePassphraseState = false;
|
|
47394
|
+
this.skipForceUpdateCheck = true;
|
|
47435
47395
|
}
|
|
47436
|
-
|
|
47437
|
-
|
|
47396
|
+
run() {
|
|
47397
|
+
var _a;
|
|
47398
|
+
const payload = this.payload;
|
|
47399
|
+
if (this.device.features) {
|
|
47400
|
+
const deviceFirmwareType = this.device.getCurrentFirmwareType();
|
|
47401
|
+
const firmwareType = (_a = payload.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
|
|
47402
|
+
const releaseInfo = getFirmwareReleaseInfo(this.device.features, firmwareType);
|
|
47403
|
+
return Promise.resolve(releaseInfo);
|
|
47404
|
+
}
|
|
47405
|
+
return Promise.resolve(null);
|
|
47438
47406
|
}
|
|
47439
|
-
|
|
47440
|
-
|
|
47407
|
+
}
|
|
47408
|
+
|
|
47409
|
+
class CheckBLEFirmwareRelease extends BaseMethod {
|
|
47410
|
+
init() {
|
|
47411
|
+
this.allowDeviceMode = [
|
|
47412
|
+
...this.allowDeviceMode,
|
|
47413
|
+
UI_REQUEST.NOT_INITIALIZE,
|
|
47414
|
+
UI_REQUEST.BOOTLOADER,
|
|
47415
|
+
];
|
|
47416
|
+
this.useDevicePassphraseState = false;
|
|
47417
|
+
this.skipForceUpdateCheck = true;
|
|
47441
47418
|
}
|
|
47442
|
-
|
|
47443
|
-
|
|
47419
|
+
run() {
|
|
47420
|
+
if (this.device.features) {
|
|
47421
|
+
const releaseInfo = getBleFirmwareReleaseInfo(this.device.features);
|
|
47422
|
+
return Promise.resolve(releaseInfo);
|
|
47423
|
+
}
|
|
47424
|
+
return Promise.resolve(null);
|
|
47444
47425
|
}
|
|
47445
|
-
return Object.assign(Object.assign({}, plan), { status,
|
|
47446
|
-
hasUpgrade,
|
|
47447
|
-
required,
|
|
47448
|
-
components,
|
|
47449
|
-
targetsToUpdate });
|
|
47450
47426
|
}
|
|
47451
|
-
|
|
47452
|
-
|
|
47453
|
-
|
|
47454
|
-
|
|
47455
|
-
|
|
47456
|
-
|
|
47457
|
-
bootloaderMode: state.status.mode === 'bootloader' || state.status.mode === 'romloader',
|
|
47458
|
-
};
|
|
47459
|
-
}
|
|
47460
|
-
function getProtocolV2ComponentReleaseInfo(plan, componentTarget) {
|
|
47461
|
-
var _a;
|
|
47462
|
-
const componentRelease = plan.components.find(component => component.componentTarget === componentTarget);
|
|
47463
|
-
if (!componentRelease || !plan.release) {
|
|
47464
|
-
return undefined;
|
|
47427
|
+
|
|
47428
|
+
class CheckBridgeStatus extends BaseMethod {
|
|
47429
|
+
init() {
|
|
47430
|
+
this.useDevice = false;
|
|
47431
|
+
this.useDevicePassphraseState = false;
|
|
47432
|
+
this.skipForceUpdateCheck = true;
|
|
47465
47433
|
}
|
|
47466
|
-
|
|
47467
|
-
|
|
47468
|
-
|
|
47434
|
+
run() {
|
|
47435
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47436
|
+
return new Promise((resolve, reject) => {
|
|
47437
|
+
axios__default["default"]
|
|
47438
|
+
.request({
|
|
47439
|
+
url: 'http://localhost:21320',
|
|
47440
|
+
method: 'POST',
|
|
47441
|
+
withCredentials: false,
|
|
47442
|
+
timeout: 3000,
|
|
47443
|
+
})
|
|
47444
|
+
.then(() => resolve(true))
|
|
47445
|
+
.catch(e => {
|
|
47446
|
+
if (e.code === 'ECONNABORTED') {
|
|
47447
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BridgeTimeoutError));
|
|
47448
|
+
}
|
|
47449
|
+
else {
|
|
47450
|
+
resolve(false);
|
|
47451
|
+
}
|
|
47452
|
+
});
|
|
47453
|
+
});
|
|
47454
|
+
});
|
|
47469
47455
|
}
|
|
47470
|
-
return Object.assign(Object.assign({}, component), { protocol: 'V2', configKey: componentRelease.configKey, componentTarget, required: plan.release.required, changelog: plan.release.changelog });
|
|
47471
47456
|
}
|
|
47472
47457
|
|
|
47473
47458
|
const REQUIRED_BRIDGE_VERSION = '2.2.0';
|
|
@@ -47524,6 +47509,56 @@ function getBridgeReleaseInfo({ deviceType, currentFirmwareVersion, willUpdateFi
|
|
|
47524
47509
|
});
|
|
47525
47510
|
}
|
|
47526
47511
|
|
|
47512
|
+
class CheckBridgeRelease extends BaseMethod {
|
|
47513
|
+
init() {
|
|
47514
|
+
this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.BOOTLOADER];
|
|
47515
|
+
this.useDevicePassphraseState = false;
|
|
47516
|
+
this.skipForceUpdateCheck = true;
|
|
47517
|
+
}
|
|
47518
|
+
run() {
|
|
47519
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47520
|
+
if (!this.device.features) {
|
|
47521
|
+
return null;
|
|
47522
|
+
}
|
|
47523
|
+
const { willUpdateFirmwareVersion } = this.payload;
|
|
47524
|
+
const { features } = this.device;
|
|
47525
|
+
const deviceType = getDeviceType(features);
|
|
47526
|
+
const currentFirmwareVersion = getDeviceFirmwareVersion(features).join('.');
|
|
47527
|
+
return getBridgeReleaseInfo({
|
|
47528
|
+
deviceType,
|
|
47529
|
+
currentFirmwareVersion,
|
|
47530
|
+
willUpdateFirmwareVersion,
|
|
47531
|
+
});
|
|
47532
|
+
});
|
|
47533
|
+
}
|
|
47534
|
+
}
|
|
47535
|
+
|
|
47536
|
+
class CheckBootloaderRelease extends BaseMethod {
|
|
47537
|
+
init() {
|
|
47538
|
+
this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.BOOTLOADER];
|
|
47539
|
+
this.useDevicePassphraseState = false;
|
|
47540
|
+
this.skipForceUpdateCheck = true;
|
|
47541
|
+
}
|
|
47542
|
+
run() {
|
|
47543
|
+
var _a;
|
|
47544
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47545
|
+
if (!this.device.features) {
|
|
47546
|
+
return null;
|
|
47547
|
+
}
|
|
47548
|
+
const { features } = this.device;
|
|
47549
|
+
const payload = this.payload;
|
|
47550
|
+
const deviceFirmwareType = this.device.getCurrentFirmwareType();
|
|
47551
|
+
const firmwareType = (_a = payload.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
|
|
47552
|
+
const releaseInfo = getBootloaderReleaseInfo({
|
|
47553
|
+
features,
|
|
47554
|
+
willUpdateFirmwareVersion: payload.willUpdateFirmwareVersion,
|
|
47555
|
+
firmwareType,
|
|
47556
|
+
});
|
|
47557
|
+
return Promise.resolve(releaseInfo);
|
|
47558
|
+
});
|
|
47559
|
+
}
|
|
47560
|
+
}
|
|
47561
|
+
|
|
47527
47562
|
const UPDATE_TARGET_BY_COMPONENT_TARGET = {
|
|
47528
47563
|
BOOTLOADER: 'boot',
|
|
47529
47564
|
APPLICATION_P1: 'app_v1',
|
|
@@ -47771,15 +47806,22 @@ class CheckAllFirmwareRelease extends BaseMethod {
|
|
|
47771
47806
|
runProtocolV2() {
|
|
47772
47807
|
var _a;
|
|
47773
47808
|
return __awaiter(this, void 0, void 0, function* () {
|
|
47774
|
-
const { checkFirmwareHash = false, firmwareType: firmwareTypeParam
|
|
47775
|
-
|
|
47776
|
-
const
|
|
47777
|
-
|
|
47778
|
-
|
|
47779
|
-
|
|
47780
|
-
checkFirmwareHash,
|
|
47781
|
-
methodName: 'checkAllFirmwareRelease',
|
|
47809
|
+
const { checkFirmwareHash = false, firmwareType: firmwareTypeParam } = this
|
|
47810
|
+
.payload;
|
|
47811
|
+
const state = yield this.device.getDeviceState({
|
|
47812
|
+
refreshSections: checkFirmwareHash
|
|
47813
|
+
? ['identity', 'versions', 'verification']
|
|
47814
|
+
: ['identity', 'versions'],
|
|
47782
47815
|
});
|
|
47816
|
+
if (state.identity.deviceType !== 'pro2' && state.identity.deviceType !== 'neo') {
|
|
47817
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotSupportMethod, 'checkAllFirmwareRelease requires a Pro2 or Neo device for Protocol V2');
|
|
47818
|
+
}
|
|
47819
|
+
const { features } = this.device;
|
|
47820
|
+
if (!features) {
|
|
47821
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'checkAllFirmwareRelease requires initialized device features');
|
|
47822
|
+
}
|
|
47823
|
+
const firmwareType = (_a = firmwareTypeParam !== null && firmwareTypeParam !== void 0 ? firmwareTypeParam : state.identity.firmwareType) !== null && _a !== void 0 ? _a : hdShared.EFirmwareType.Universal;
|
|
47824
|
+
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
47783
47825
|
const plan = buildProtocolV2FirmwareRelease({
|
|
47784
47826
|
currentVersions: state.versions,
|
|
47785
47827
|
currentVerification: checkFirmwareHash ? state.verification : undefined,
|
|
@@ -47789,250 +47831,48 @@ class CheckAllFirmwareRelease extends BaseMethod {
|
|
|
47789
47831
|
deviceType: state.identity.deviceType,
|
|
47790
47832
|
});
|
|
47791
47833
|
const resourceDeviceType = state.identity.deviceType === 'neo' ? hdShared.EDeviceType.Neo : hdShared.EDeviceType.Pro2;
|
|
47792
|
-
const
|
|
47793
|
-
|
|
47794
|
-
|
|
47795
|
-
|
|
47796
|
-
|
|
47797
|
-
|
|
47798
|
-
|
|
47799
|
-
|
|
47800
|
-
|
|
47801
|
-
|
|
47802
|
-
|
|
47803
|
-
|
|
47804
|
-
|
|
47805
|
-
|
|
47806
|
-
|
|
47807
|
-
let firmwareUpdatePlan;
|
|
47808
|
-
const shouldBuildFirmwareUpdatePlan = targetsToUpdate.length > 0;
|
|
47809
|
-
const requestedPlatform = platform !== null && platform !== void 0 ? platform : 'web';
|
|
47810
|
-
const requiresPreparedPlan = shouldBuildFirmwareUpdatePlan &&
|
|
47811
|
-
(requestedPlatform === 'native' || requestedPlatform === 'desktop');
|
|
47812
|
-
try {
|
|
47813
|
-
if (shouldBuildFirmwareUpdatePlan) {
|
|
47814
|
-
const validatedPlan = buildProtocolV2FirmwareUpdatePlan({
|
|
47815
|
-
features,
|
|
47816
|
-
firmwareType,
|
|
47817
|
-
platform: requestedPlatform,
|
|
47818
|
-
release,
|
|
47819
|
-
targetsToUpdate,
|
|
47820
|
-
forceUpdateTargets: validatedForceUpdateTargets,
|
|
47821
|
-
resourceArchive: resourceSource,
|
|
47822
|
-
});
|
|
47823
|
-
firmwareUpdatePlan = validatedPlan;
|
|
47824
|
-
}
|
|
47825
|
-
else {
|
|
47826
|
-
firmwareUpdatePlan = undefined;
|
|
47827
|
-
}
|
|
47828
|
-
}
|
|
47829
|
-
catch (error) {
|
|
47830
|
-
if (requiresPreparedPlan ||
|
|
47831
|
-
validatedForceUpdateTargets.length > 0 ||
|
|
47832
|
-
validatedProtocolV2ForceUpdateTargets.length > 0 ||
|
|
47833
|
-
!(error instanceof hdShared.HardwareError) ||
|
|
47834
|
-
((_a = error.params) === null || _a === void 0 ? void 0 : _a.firmwareUpdateCode) !== 'FirmwarePlanInvalid') {
|
|
47835
|
-
throw error;
|
|
47836
|
-
}
|
|
47837
|
-
Log$c.warn('[CheckAllFirmwareRelease] Optional Protocol V2 firmware Plan is unavailable; using the release result');
|
|
47838
|
-
firmwareUpdatePlan = undefined;
|
|
47839
|
-
}
|
|
47840
|
-
const firmwarePlan = summarizeProtocolV2FirmwareRelease(plan, PROTOCOL_V2_MAIN_FIRMWARE_TARGETS);
|
|
47841
|
-
const blePlan = summarizeProtocolV2FirmwareRelease(plan, PROTOCOL_V2_BLE_TARGETS);
|
|
47842
|
-
const bootloaderPlan = summarizeProtocolV2FirmwareRelease(plan, PROTOCOL_V2_BOOTLOADER_TARGETS);
|
|
47843
|
-
const { status } = plan;
|
|
47844
|
-
return Object.assign(Object.assign({ firmware: toProtocolV2FirmwareReleaseInfo({ plan: firmwarePlan, state, release }), ble: toProtocolV2FirmwareReleaseInfo({
|
|
47845
|
-
plan: blePlan,
|
|
47846
|
-
state,
|
|
47847
|
-
release: getProtocolV2ComponentReleaseInfo(plan, 'COPROCESSOR'),
|
|
47848
|
-
}), bootloader: toProtocolV2FirmwareReleaseInfo({
|
|
47849
|
-
plan: bootloaderPlan,
|
|
47850
|
-
state,
|
|
47851
|
-
release: getProtocolV2ComponentReleaseInfo(plan, 'BOOTLOADER'),
|
|
47852
|
-
}), features, protocol: 'V2', deviceType: state.identity.deviceType }, plan), { status,
|
|
47853
|
-
resourceStatus, resourceArchive: resourceSource, hasUpgrade: targetsToUpdate.length > 0, targetsToUpdate,
|
|
47854
|
-
firmwareUpdatePlan });
|
|
47855
|
-
});
|
|
47856
|
-
}
|
|
47857
|
-
}
|
|
47858
|
-
|
|
47859
|
-
class CheckFirmwareRelease extends BaseMethod {
|
|
47860
|
-
getSupportedProtocols() {
|
|
47861
|
-
return ['V1', 'V2'];
|
|
47862
|
-
}
|
|
47863
|
-
init() {
|
|
47864
|
-
this.allowDeviceMode = [
|
|
47865
|
-
...this.allowDeviceMode,
|
|
47866
|
-
UI_REQUEST.NOT_INITIALIZE,
|
|
47867
|
-
UI_REQUEST.BOOTLOADER,
|
|
47868
|
-
];
|
|
47869
|
-
this.useDevicePassphraseState = false;
|
|
47870
|
-
this.skipForceUpdateCheck = true;
|
|
47871
|
-
}
|
|
47872
|
-
run() {
|
|
47873
|
-
var _a;
|
|
47874
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
47875
|
-
const payload = this.payload;
|
|
47876
|
-
if (!this.device.features)
|
|
47877
|
-
return null;
|
|
47878
|
-
if (this.device.isProtocolV2()) {
|
|
47879
|
-
const { state, firmwareType, release } = yield loadProtocolV2FirmwareReleaseContext({
|
|
47880
|
-
device: this.device,
|
|
47881
|
-
firmwareType: payload.firmwareType,
|
|
47882
|
-
methodName: 'checkFirmwareRelease',
|
|
47883
|
-
});
|
|
47884
|
-
const plan = summarizeProtocolV2FirmwareRelease(buildProtocolV2FirmwareRelease({
|
|
47885
|
-
currentVersions: state.versions,
|
|
47886
|
-
firmwareType,
|
|
47887
|
-
release,
|
|
47888
|
-
deviceType: state.identity.deviceType,
|
|
47889
|
-
}), PROTOCOL_V2_MAIN_FIRMWARE_TARGETS);
|
|
47890
|
-
return toProtocolV2FirmwareReleaseInfo({ plan, state, release });
|
|
47891
|
-
}
|
|
47892
|
-
const deviceFirmwareType = this.device.getCurrentFirmwareType();
|
|
47893
|
-
const firmwareType = (_a = payload.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
|
|
47894
|
-
const releaseInfo = getFirmwareReleaseInfo(this.device.features, firmwareType);
|
|
47895
|
-
return releaseInfo;
|
|
47896
|
-
});
|
|
47897
|
-
}
|
|
47898
|
-
}
|
|
47899
|
-
|
|
47900
|
-
class CheckBLEFirmwareRelease extends BaseMethod {
|
|
47901
|
-
getSupportedProtocols() {
|
|
47902
|
-
return ['V1', 'V2'];
|
|
47903
|
-
}
|
|
47904
|
-
init() {
|
|
47905
|
-
this.allowDeviceMode = [
|
|
47906
|
-
...this.allowDeviceMode,
|
|
47907
|
-
UI_REQUEST.NOT_INITIALIZE,
|
|
47908
|
-
UI_REQUEST.BOOTLOADER,
|
|
47909
|
-
];
|
|
47910
|
-
this.useDevicePassphraseState = false;
|
|
47911
|
-
this.skipForceUpdateCheck = true;
|
|
47912
|
-
}
|
|
47913
|
-
run() {
|
|
47914
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
47915
|
-
if (!this.device.features)
|
|
47916
|
-
return null;
|
|
47917
|
-
if (this.device.isProtocolV2()) {
|
|
47918
|
-
const { state, firmwareType, release } = yield loadProtocolV2FirmwareReleaseContext({
|
|
47919
|
-
device: this.device,
|
|
47920
|
-
methodName: 'checkBLEFirmwareRelease',
|
|
47921
|
-
});
|
|
47922
|
-
const plan = summarizeProtocolV2FirmwareRelease(buildProtocolV2FirmwareRelease({
|
|
47923
|
-
currentVersions: state.versions,
|
|
47924
|
-
firmwareType,
|
|
47925
|
-
release,
|
|
47926
|
-
deviceType: state.identity.deviceType,
|
|
47927
|
-
}), PROTOCOL_V2_BLE_TARGETS);
|
|
47928
|
-
return toProtocolV2FirmwareReleaseInfo({
|
|
47929
|
-
plan,
|
|
47930
|
-
state,
|
|
47931
|
-
release: getProtocolV2ComponentReleaseInfo(plan, 'COPROCESSOR'),
|
|
47932
|
-
});
|
|
47933
|
-
}
|
|
47934
|
-
const releaseInfo = getBleFirmwareReleaseInfo(this.device.features);
|
|
47935
|
-
return releaseInfo;
|
|
47936
|
-
});
|
|
47937
|
-
}
|
|
47938
|
-
}
|
|
47939
|
-
|
|
47940
|
-
class CheckBridgeStatus extends BaseMethod {
|
|
47941
|
-
init() {
|
|
47942
|
-
this.useDevice = false;
|
|
47943
|
-
this.useDevicePassphraseState = false;
|
|
47944
|
-
this.skipForceUpdateCheck = true;
|
|
47945
|
-
}
|
|
47946
|
-
run() {
|
|
47947
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
47948
|
-
return new Promise((resolve, reject) => {
|
|
47949
|
-
axios__default["default"]
|
|
47950
|
-
.request({
|
|
47951
|
-
url: 'http://localhost:21320',
|
|
47952
|
-
method: 'POST',
|
|
47953
|
-
withCredentials: false,
|
|
47954
|
-
timeout: 3000,
|
|
47955
|
-
})
|
|
47956
|
-
.then(() => resolve(true))
|
|
47957
|
-
.catch(e => {
|
|
47958
|
-
if (e.code === 'ECONNABORTED') {
|
|
47959
|
-
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BridgeTimeoutError));
|
|
47834
|
+
const resources = DataManager.getProtocolV2Resources(resourceDeviceType);
|
|
47835
|
+
let resourceStatus = 'unknown';
|
|
47836
|
+
if (resources === null || resources === void 0 ? void 0 : resources.length) {
|
|
47837
|
+
const loaderMode = state.status.mode === 'bootloader' || state.status.mode === 'romloader';
|
|
47838
|
+
if (loaderMode) {
|
|
47839
|
+
try {
|
|
47840
|
+
const inventory = yield readProtocolV2ResourceInventory({
|
|
47841
|
+
commands: this.device.getCommands(),
|
|
47842
|
+
resources,
|
|
47843
|
+
});
|
|
47844
|
+
resourceStatus = buildProtocolV2ResourceUpdatePlan({
|
|
47845
|
+
resources,
|
|
47846
|
+
inventory,
|
|
47847
|
+
mode: 'bootloader-recovery',
|
|
47848
|
+
}).status;
|
|
47960
47849
|
}
|
|
47961
|
-
|
|
47962
|
-
|
|
47850
|
+
catch (_b) {
|
|
47851
|
+
resourceStatus = buildProtocolV2ResourceUpdatePlan({
|
|
47852
|
+
resources,
|
|
47853
|
+
mode: 'bootloader-recovery',
|
|
47854
|
+
}).status;
|
|
47963
47855
|
}
|
|
47964
|
-
}
|
|
47965
|
-
});
|
|
47966
|
-
});
|
|
47967
|
-
}
|
|
47968
|
-
}
|
|
47969
|
-
|
|
47970
|
-
class CheckBridgeRelease extends BaseMethod {
|
|
47971
|
-
init() {
|
|
47972
|
-
this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.BOOTLOADER];
|
|
47973
|
-
this.useDevicePassphraseState = false;
|
|
47974
|
-
this.skipForceUpdateCheck = true;
|
|
47975
|
-
}
|
|
47976
|
-
run() {
|
|
47977
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
47978
|
-
if (!this.device.features) {
|
|
47979
|
-
return null;
|
|
47980
|
-
}
|
|
47981
|
-
const { willUpdateFirmwareVersion } = this.payload;
|
|
47982
|
-
const { features } = this.device;
|
|
47983
|
-
const deviceType = getDeviceType(features);
|
|
47984
|
-
const currentFirmwareVersion = getDeviceFirmwareVersion(features).join('.');
|
|
47985
|
-
return getBridgeReleaseInfo({
|
|
47986
|
-
deviceType,
|
|
47987
|
-
currentFirmwareVersion,
|
|
47988
|
-
willUpdateFirmwareVersion,
|
|
47989
|
-
});
|
|
47990
|
-
});
|
|
47991
|
-
}
|
|
47992
|
-
}
|
|
47993
|
-
|
|
47994
|
-
class CheckBootloaderRelease extends BaseMethod {
|
|
47995
|
-
getSupportedProtocols() {
|
|
47996
|
-
return ['V1', 'V2'];
|
|
47997
|
-
}
|
|
47998
|
-
init() {
|
|
47999
|
-
this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.BOOTLOADER];
|
|
48000
|
-
this.useDevicePassphraseState = false;
|
|
48001
|
-
this.skipForceUpdateCheck = true;
|
|
48002
|
-
}
|
|
48003
|
-
run() {
|
|
48004
|
-
var _a;
|
|
48005
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
48006
|
-
if (!this.device.features)
|
|
48007
|
-
return null;
|
|
48008
|
-
const { features } = this.device;
|
|
48009
|
-
const payload = this.payload;
|
|
48010
|
-
if (this.device.isProtocolV2()) {
|
|
48011
|
-
const { state, firmwareType, release } = yield loadProtocolV2FirmwareReleaseContext({
|
|
48012
|
-
device: this.device,
|
|
48013
|
-
firmwareType: payload.firmwareType,
|
|
48014
|
-
methodName: 'checkBootloaderRelease',
|
|
48015
|
-
});
|
|
48016
|
-
const plan = summarizeProtocolV2FirmwareRelease(buildProtocolV2FirmwareRelease({
|
|
48017
|
-
currentVersions: state.versions,
|
|
48018
|
-
firmwareType,
|
|
48019
|
-
release,
|
|
48020
|
-
deviceType: state.identity.deviceType,
|
|
48021
|
-
}), PROTOCOL_V2_BOOTLOADER_TARGETS);
|
|
48022
|
-
return toProtocolV2FirmwareReleaseInfo({
|
|
48023
|
-
plan,
|
|
48024
|
-
state,
|
|
48025
|
-
release: getProtocolV2ComponentReleaseInfo(plan, 'BOOTLOADER'),
|
|
48026
|
-
});
|
|
47856
|
+
}
|
|
48027
47857
|
}
|
|
48028
|
-
const
|
|
48029
|
-
|
|
48030
|
-
|
|
48031
|
-
|
|
48032
|
-
|
|
48033
|
-
|
|
48034
|
-
|
|
48035
|
-
|
|
47858
|
+
const targetsToUpdate = [
|
|
47859
|
+
...plan.targetsToUpdate,
|
|
47860
|
+
...(resourceStatus === 'outdated' ? ['resource'] : []),
|
|
47861
|
+
];
|
|
47862
|
+
const firmwareStatus = plan.status === 'unavailable' ? 'unknown' : plan.status;
|
|
47863
|
+
const emptyRelease = 'none';
|
|
47864
|
+
return Object.assign(Object.assign({ firmware: {
|
|
47865
|
+
status: firmwareStatus,
|
|
47866
|
+
changelog: release ? [release.changelog] : [],
|
|
47867
|
+
release: release !== null && release !== void 0 ? release : emptyRelease,
|
|
47868
|
+
bootloaderMode: state.status.mode === 'bootloader' || state.status.mode === 'romloader',
|
|
47869
|
+
}, ble: {
|
|
47870
|
+
status: 'valid',
|
|
47871
|
+
release: emptyRelease,
|
|
47872
|
+
}, bootloader: {
|
|
47873
|
+
status: 'valid',
|
|
47874
|
+
release: emptyRelease,
|
|
47875
|
+
}, features, protocol: 'V2', deviceType: state.identity.deviceType }, plan), { resourceStatus, hasUpgrade: plan.hasUpgrade || resourceStatus === 'outdated', targetsToUpdate });
|
|
48036
47876
|
});
|
|
48037
47877
|
}
|
|
48038
47878
|
}
|
|
@@ -49404,6 +49244,8 @@ class FirmwareUpdateBaseMethod extends BaseMethod {
|
|
|
49404
49244
|
!this.payload.skipWebDevicePrompt &&
|
|
49405
49245
|
!hasPromptedWebDevice &&
|
|
49406
49246
|
!isPromptingWebDevice) {
|
|
49247
|
+
clearInterval(intervalTimer);
|
|
49248
|
+
clearTimeout(timeoutTimer);
|
|
49407
49249
|
isPromptingWebDevice = true;
|
|
49408
49250
|
try {
|
|
49409
49251
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.SelectDeviceInBootloaderForWebDevice);
|
|
@@ -49777,35 +49619,24 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
|
|
|
49777
49619
|
});
|
|
49778
49620
|
}
|
|
49779
49621
|
run() {
|
|
49780
|
-
var _a, _b;
|
|
49622
|
+
var _a, _b, _c;
|
|
49781
49623
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49782
49624
|
const { device } = this;
|
|
49783
49625
|
const { features } = device;
|
|
49784
49626
|
const payload = this.payload;
|
|
49785
|
-
const
|
|
49786
|
-
|
|
49787
|
-
if (hasPreparedPlan !== hasPreparedArtifact) {
|
|
49788
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Prepared bootloader plans require exactly one prepared artifact');
|
|
49789
|
-
}
|
|
49790
|
-
if (payload.binary !== undefined && hasPreparedArtifact) {
|
|
49791
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Bootloader binary and prepared artifact are mutually exclusive');
|
|
49792
|
-
}
|
|
49793
|
-
const preparedPlan = hasPreparedArtifact
|
|
49794
|
-
? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
|
|
49627
|
+
const hostBinding = payload.artifact
|
|
49628
|
+
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
|
|
49795
49629
|
: undefined;
|
|
49796
|
-
const artifactReader =
|
|
49797
|
-
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest).artifactReader
|
|
49798
|
-
: payload.artifactReader;
|
|
49799
|
-
const executionParams = Object.assign(Object.assign({}, payload), { artifactReader });
|
|
49630
|
+
const executionParams = Object.assign(Object.assign({}, payload), { artifactReader: (_a = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _a !== void 0 ? _a : payload.artifactReader });
|
|
49800
49631
|
if (payload.artifact) {
|
|
49801
49632
|
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
49802
|
-
preparedPlan,
|
|
49633
|
+
preparedPlan: payload.preparedPlan,
|
|
49803
49634
|
deviceIdentity: getDeviceUUID(features) || undefined,
|
|
49804
49635
|
bootloaderMode: resolveDeviceBootloaderMode(features),
|
|
49805
49636
|
deviceModel: String(getDeviceType(features)),
|
|
49806
49637
|
});
|
|
49807
49638
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
49808
|
-
preparedPlan,
|
|
49639
|
+
preparedPlan: payload.preparedPlan,
|
|
49809
49640
|
executor: 'v2',
|
|
49810
49641
|
scopeTargets: ['bootloader'],
|
|
49811
49642
|
bindings: [
|
|
@@ -49825,7 +49656,7 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
|
|
|
49825
49656
|
try {
|
|
49826
49657
|
const deviceType = device.getCurrentDeviceType();
|
|
49827
49658
|
const deviceFirmwareType = device.getCurrentFirmwareType();
|
|
49828
|
-
const firmwareType = (
|
|
49659
|
+
const firmwareType = (_b = payload.firmwareType) !== null && _b !== void 0 ? _b : deviceFirmwareType;
|
|
49829
49660
|
if (DeviceModelToTypes.model_touch.includes(deviceType)) {
|
|
49830
49661
|
return yield this.updateTouchBootloader({
|
|
49831
49662
|
device,
|
|
@@ -49843,7 +49674,7 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
|
|
|
49843
49674
|
const { binary } = payload;
|
|
49844
49675
|
const deviceType = device.getCurrentDeviceType();
|
|
49845
49676
|
const deviceFirmwareType = device.getCurrentFirmwareType();
|
|
49846
|
-
const firmwareType = (
|
|
49677
|
+
const firmwareType = (_c = payload.firmwareType) !== null && _c !== void 0 ? _c : deviceFirmwareType;
|
|
49847
49678
|
if (DeviceModelToTypes.model_touch.includes(deviceType)) {
|
|
49848
49679
|
return this.updateTouchBootloader({
|
|
49849
49680
|
device,
|
|
@@ -50197,9 +50028,6 @@ class FirmwareUpdateV2 extends BaseMethod {
|
|
|
50197
50028
|
payload.artifact !== undefined) {
|
|
50198
50029
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Firmware update binary and artifact are mutually exclusive');
|
|
50199
50030
|
}
|
|
50200
|
-
if (payload.preparedPlan !== undefined && payload.artifact === undefined) {
|
|
50201
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Prepared firmware plans require a prepared artifact');
|
|
50202
|
-
}
|
|
50203
50031
|
if (!payload.updateType) {
|
|
50204
50032
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'updateType is required');
|
|
50205
50033
|
}
|
|
@@ -50215,8 +50043,7 @@ class FirmwareUpdateV2 extends BaseMethod {
|
|
|
50215
50043
|
this.params = Object.assign(Object.assign({}, this.params), { binary: payload.binary });
|
|
50216
50044
|
}
|
|
50217
50045
|
if ('artifact' in payload) {
|
|
50218
|
-
const
|
|
50219
|
-
const hostBinding = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest);
|
|
50046
|
+
const hostBinding = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration);
|
|
50220
50047
|
const target = payload.isUpdateBootloader ? 'bootloader' : payload.updateType;
|
|
50221
50048
|
const resourceBindings = ((_a = payload.resourceEntries) !== null && _a !== void 0 ? _a : []).map((entry) => ({
|
|
50222
50049
|
target: 'resource',
|
|
@@ -50224,13 +50051,13 @@ class FirmwareUpdateV2 extends BaseMethod {
|
|
|
50224
50051
|
artifact: entry.artifact,
|
|
50225
50052
|
}));
|
|
50226
50053
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
50227
|
-
preparedPlan,
|
|
50054
|
+
preparedPlan: payload.preparedPlan,
|
|
50228
50055
|
executor: 'v2',
|
|
50229
50056
|
platform: payload.platform,
|
|
50230
50057
|
scopeTargets: [target, ...(target === 'firmware' ? ['resource'] : [])],
|
|
50231
50058
|
bindings: [{ target, artifact: payload.artifact }, ...resourceBindings],
|
|
50232
50059
|
});
|
|
50233
|
-
this.params = Object.assign(Object.assign({}, this.params), { preparedPlan, artifact: payload.artifact, resourceEntries: payload.resourceEntries, artifactReader: hostBinding.artifactReader });
|
|
50060
|
+
this.params = Object.assign(Object.assign({}, this.params), { preparedPlan: payload.preparedPlan, artifact: payload.artifact, resourceEntries: payload.resourceEntries, artifactReader: hostBinding.artifactReader });
|
|
50234
50061
|
}
|
|
50235
50062
|
}
|
|
50236
50063
|
_promptDeviceInBootloaderForWebDevice() {
|
|
@@ -50575,7 +50402,7 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
50575
50402
|
this.artifactSources = [];
|
|
50576
50403
|
}
|
|
50577
50404
|
init() {
|
|
50578
|
-
var _a, _b, _c, _d, _e;
|
|
50405
|
+
var _a, _b, _c, _d, _e, _f;
|
|
50579
50406
|
this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
|
|
50580
50407
|
this.requireDeviceMode = [];
|
|
50581
50408
|
this.useDevicePassphraseState = false;
|
|
@@ -50593,15 +50420,12 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
50593
50420
|
{ name: 'firmwareType', type: 'string' },
|
|
50594
50421
|
{ name: 'platform', type: 'string' },
|
|
50595
50422
|
]);
|
|
50596
|
-
const
|
|
50597
|
-
?
|
|
50423
|
+
const hostBinding = payload.artifacts || payload.preparedPlan
|
|
50424
|
+
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
|
|
50598
50425
|
: undefined;
|
|
50599
|
-
|
|
50600
|
-
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest).artifactReader
|
|
50601
|
-
: payload.artifactReader;
|
|
50602
|
-
if (preparedPlan) {
|
|
50426
|
+
if (hostBinding) {
|
|
50603
50427
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
50604
|
-
preparedPlan,
|
|
50428
|
+
preparedPlan: payload.preparedPlan,
|
|
50605
50429
|
executor: 'v3',
|
|
50606
50430
|
platform: payload.platform,
|
|
50607
50431
|
scopeTargets: ['bootloader', 'firmware', 'resource', 'ble'],
|
|
@@ -50639,7 +50463,7 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
50639
50463
|
});
|
|
50640
50464
|
}
|
|
50641
50465
|
this.params = {
|
|
50642
|
-
preparedPlan,
|
|
50466
|
+
preparedPlan: payload.preparedPlan,
|
|
50643
50467
|
bleBinary: payload.bleBinary,
|
|
50644
50468
|
firmwareBinary: payload.firmwareBinary,
|
|
50645
50469
|
forcedUpdateRes: payload.forcedUpdateRes,
|
|
@@ -50650,7 +50474,7 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
50650
50474
|
resourceBinary: payload.resourceBinary,
|
|
50651
50475
|
firmwareType: payload.firmwareType,
|
|
50652
50476
|
platform: payload.platform,
|
|
50653
|
-
artifactReader,
|
|
50477
|
+
artifactReader: (_f = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _f !== void 0 ? _f : payload.artifactReader,
|
|
50654
50478
|
artifacts: payload.artifacts,
|
|
50655
50479
|
};
|
|
50656
50480
|
}
|
|
@@ -51266,88 +51090,6 @@ const INSTALLABLE_FIRMWARE_TARGET_IDS = new Set([
|
|
|
51266
51090
|
]);
|
|
51267
51091
|
new Map(Object.entries(ProtocolV2FirmwareTargetType).flatMap(([key, value]) => INSTALLABLE_FIRMWARE_TARGET_IDS.has(value) ? [[key, value]] : []));
|
|
51268
51092
|
|
|
51269
|
-
let memoryHostSequence = 0;
|
|
51270
|
-
const createReference = (binary, prefix) => {
|
|
51271
|
-
const digest = utils.bytesToHex(sha256.sha256(new Uint8Array(binary)));
|
|
51272
|
-
return {
|
|
51273
|
-
artifactRef: `fwmem:${prefix}:${digest.slice(0, 32)}`,
|
|
51274
|
-
size: binary.byteLength,
|
|
51275
|
-
sha256: digest,
|
|
51276
|
-
};
|
|
51277
|
-
};
|
|
51278
|
-
function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }) {
|
|
51279
|
-
if (plan.executor !== 'v4') {
|
|
51280
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory host only supports V4 plans');
|
|
51281
|
-
}
|
|
51282
|
-
memoryHostSequence += 1;
|
|
51283
|
-
const hostId = `${Date.now()}:${memoryHostSequence}`;
|
|
51284
|
-
const binaries = new Map();
|
|
51285
|
-
const inputs = artifacts.map((input, artifactIndex) => {
|
|
51286
|
-
var _a;
|
|
51287
|
-
const artifactBinary = new Uint8Array(input.binary).slice();
|
|
51288
|
-
const artifact = createReference(artifactBinary.buffer, `${hostId}:artifact:${artifactIndex}`);
|
|
51289
|
-
binaries.set(artifact.artifactRef, artifactBinary);
|
|
51290
|
-
const materializedEntries = (_a = input.materializedEntries) === null || _a === void 0 ? void 0 : _a.map((entry, entryIndex) => {
|
|
51291
|
-
const entryBinary = new Uint8Array(entry.binary).slice();
|
|
51292
|
-
const entryArtifact = createReference(entryBinary.buffer, `${hostId}:entry:${artifactIndex}:${entryIndex}`);
|
|
51293
|
-
binaries.set(entryArtifact.artifactRef, entryBinary);
|
|
51294
|
-
return {
|
|
51295
|
-
entryName: entry.entryName,
|
|
51296
|
-
artifact: entryArtifact,
|
|
51297
|
-
};
|
|
51298
|
-
});
|
|
51299
|
-
return Object.assign({ artifactId: input.artifactId, artifact }, ((materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length) ? { materializedEntries } : {}));
|
|
51300
|
-
});
|
|
51301
|
-
const preparedPlan = sdk.prepareFirmwareUpdatePlan({
|
|
51302
|
-
plan,
|
|
51303
|
-
leaseRef: `fwmemlease:${hostId}`,
|
|
51304
|
-
artifacts: inputs,
|
|
51305
|
-
});
|
|
51306
|
-
const readers = new Map();
|
|
51307
|
-
let readerSequence = 0;
|
|
51308
|
-
const artifactReader = {
|
|
51309
|
-
open({ artifactRef }) {
|
|
51310
|
-
const binary = binaries.get(artifactRef);
|
|
51311
|
-
if (!binary) {
|
|
51312
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory artifact is unavailable');
|
|
51313
|
-
}
|
|
51314
|
-
readerSequence += 1;
|
|
51315
|
-
const readerId = `fwmemreader:${hostId}:${readerSequence}`;
|
|
51316
|
-
readers.set(readerId, binary);
|
|
51317
|
-
return Promise.resolve({ readerId, size: binary.byteLength });
|
|
51318
|
-
},
|
|
51319
|
-
read({ readerId, offset, length }) {
|
|
51320
|
-
const binary = readers.get(readerId);
|
|
51321
|
-
if (!binary || offset < 0 || length <= 0 || offset + length > binary.byteLength) {
|
|
51322
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory artifact read is invalid');
|
|
51323
|
-
}
|
|
51324
|
-
const data = binary.slice(offset, offset + length).buffer;
|
|
51325
|
-
return Promise.resolve({
|
|
51326
|
-
data,
|
|
51327
|
-
bytesRead: data.byteLength,
|
|
51328
|
-
eof: offset + length === binary.byteLength,
|
|
51329
|
-
});
|
|
51330
|
-
},
|
|
51331
|
-
close({ readerId }) {
|
|
51332
|
-
readers.delete(readerId);
|
|
51333
|
-
return Promise.resolve();
|
|
51334
|
-
},
|
|
51335
|
-
};
|
|
51336
|
-
const hostBindingGeneration = sdk.registerFirmwareUpdateHostBinding({
|
|
51337
|
-
artifactReader,
|
|
51338
|
-
preparedPlanDigest: preparedPlan.preparedPlanDigest,
|
|
51339
|
-
});
|
|
51340
|
-
return {
|
|
51341
|
-
preparedPlan,
|
|
51342
|
-
hostBindingGeneration,
|
|
51343
|
-
release: () => {
|
|
51344
|
-
sdk.unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
|
|
51345
|
-
readers.clear();
|
|
51346
|
-
binaries.clear();
|
|
51347
|
-
},
|
|
51348
|
-
};
|
|
51349
|
-
}
|
|
51350
|
-
|
|
51351
51093
|
const Log$6 = getLogger(exports.LoggerNames.Method);
|
|
51352
51094
|
const SESSION_ERROR$1 = 'session not found';
|
|
51353
51095
|
const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 90 * 1000;
|
|
@@ -51374,24 +51116,7 @@ const PROTOCOL_V2_OKPP_HEADER_SIZE = 0x52a0;
|
|
|
51374
51116
|
const PROTOCOL_V2_OKPP_PAYLOAD_HASH_OFFSET = 0x200;
|
|
51375
51117
|
const PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET = 0x240;
|
|
51376
51118
|
const PROTOCOL_V2_OKPP_HASH_SIZE = 64;
|
|
51377
|
-
const PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES = 1024 * 1024;
|
|
51378
|
-
const PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT = 512;
|
|
51379
|
-
const PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES = 256 * 1024 * 1024;
|
|
51380
51119
|
const PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS = new Set(['se03', 'se04']);
|
|
51381
|
-
const getProtocolV2ZipEntrySizes = (entry) => {
|
|
51382
|
-
var _a;
|
|
51383
|
-
const { compressedSize, uncompressedSize } = (_a = entry._data) !== null && _a !== void 0 ? _a : {};
|
|
51384
|
-
if (!Number.isSafeInteger(compressedSize) ||
|
|
51385
|
-
Number(compressedSize) < 0 ||
|
|
51386
|
-
!Number.isSafeInteger(uncompressedSize) ||
|
|
51387
|
-
Number(uncompressedSize) <= 0) {
|
|
51388
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP entry size is invalid: ${entry.name}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51389
|
-
}
|
|
51390
|
-
return {
|
|
51391
|
-
compressedSize: Number(compressedSize),
|
|
51392
|
-
uncompressedSize: Number(uncompressedSize),
|
|
51393
|
-
};
|
|
51394
|
-
};
|
|
51395
51120
|
function assertProtocolV2FirmwareTargetsSupported(deviceType, params) {
|
|
51396
51121
|
var _a;
|
|
51397
51122
|
const unsupportedTargets = new Set(((_a = params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter(target => PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS.has(target)));
|
|
@@ -51462,14 +51187,6 @@ const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS = {
|
|
|
51462
51187
|
},
|
|
51463
51188
|
};
|
|
51464
51189
|
const PROTOCOL_V2_FIRMWARE_STAGING_PATHS = new Set(Object.values(PROTOCOL_V2_REMOTE_COMPONENT_TARGETS).map(target => `${PROTOCOL_V2_FIRMWARE_STAGING_VOLUME}${target.fileName}`));
|
|
51465
|
-
const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH = 'vol0:/loaders/bootloader/boot_resource.okpkg';
|
|
51466
|
-
const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH = `${PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH}.staging`;
|
|
51467
|
-
const resolveProtocolV2ResourceWritePath = (devicePath) => {
|
|
51468
|
-
const normalizedPath = devicePath.replace(/^vol0:(?!\/)/i, 'vol0:/').toLowerCase();
|
|
51469
|
-
return normalizedPath === PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH
|
|
51470
|
-
? PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH
|
|
51471
|
-
: devicePath;
|
|
51472
|
-
};
|
|
51473
51190
|
const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map([
|
|
51474
51191
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, 'boot'],
|
|
51475
51192
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, 'app_v1'],
|
|
@@ -51480,10 +51197,6 @@ const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map([
|
|
|
51480
51197
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03, 'se03'],
|
|
51481
51198
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, 'se04'],
|
|
51482
51199
|
]);
|
|
51483
|
-
const PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET = new Map(Object.values(PROTOCOL_V2_REMOTE_COMPONENT_TARGETS).map(target => [
|
|
51484
|
-
PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId),
|
|
51485
|
-
target,
|
|
51486
|
-
]));
|
|
51487
51200
|
const PROTOCOL_V2_ROMLOADER_UNSUPPORTED_MESSAGE = 'FW_MGMT_TARGET_ROMLOADER is not accepted by the current Pro2 bootloader update request. Flash romloader with the loader-specific flow instead of firmwareUpdateV4.';
|
|
51488
51201
|
const PROTOCOL_V2_TARGET_ID_BY_DECODED_NAME = new Map(Object.entries(ProtocolV2FirmwareTargetType).map(([key, value]) => [key, value]));
|
|
51489
51202
|
const PROTOCOL_V2_TARGET_STATUS_BY_DECODED_NAME = new Map([
|
|
@@ -51648,7 +51361,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51648
51361
|
return ['V2'];
|
|
51649
51362
|
}
|
|
51650
51363
|
init() {
|
|
51651
|
-
var _a, _b;
|
|
51364
|
+
var _a, _b, _c;
|
|
51652
51365
|
this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
|
|
51653
51366
|
this.requireDeviceMode = [];
|
|
51654
51367
|
this.unlockPolicy = 'unlock-before-run';
|
|
@@ -51679,85 +51392,54 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51679
51392
|
{ name: 'se02Binary', type: 'buffer' },
|
|
51680
51393
|
{ name: 'se03Binary', type: 'buffer' },
|
|
51681
51394
|
{ name: 'se04Binary', type: 'buffer' },
|
|
51682
|
-
{ name: 'resourceArchiveBinary', type: 'buffer' },
|
|
51683
51395
|
{ name: 'firmwareType', type: 'string' },
|
|
51684
51396
|
{ name: 'targetsToUpdate', type: 'array', allowEmpty: true },
|
|
51685
51397
|
{ name: 'platform', type: 'string' },
|
|
51686
51398
|
{ name: 'expectedDeviceId', type: 'string' },
|
|
51399
|
+
{ name: 'resourceFiles', type: 'array', allowEmpty: true },
|
|
51687
51400
|
]);
|
|
51688
51401
|
if (payload.expectedDeviceId !== undefined &&
|
|
51689
51402
|
(payload.expectedDeviceId.length === 0 || payload.expectedDeviceId.length > 160)) {
|
|
51690
51403
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 expected device identity is invalid');
|
|
51691
51404
|
}
|
|
51692
|
-
const
|
|
51693
|
-
?
|
|
51405
|
+
const hostBinding = payload.preparedPlan || payload.componentArtifacts || payload.resourceBundleArtifacts
|
|
51406
|
+
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
|
|
51694
51407
|
: undefined;
|
|
51695
|
-
|
|
51696
|
-
payload.bootloaderBinary,
|
|
51697
|
-
payload.romloaderBinary,
|
|
51698
|
-
payload.applicationP1Binary,
|
|
51699
|
-
payload.applicationP2Binary,
|
|
51700
|
-
payload.coprocessorBinary,
|
|
51701
|
-
payload.se01Binary,
|
|
51702
|
-
payload.se02Binary,
|
|
51703
|
-
payload.se03Binary,
|
|
51704
|
-
payload.se04Binary,
|
|
51705
|
-
payload.resourceArchiveBinary,
|
|
51706
|
-
].some(Boolean);
|
|
51707
|
-
if (preparedPlan && hasLocalArtifacts) {
|
|
51708
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Prepared firmware plans cannot be combined with legacy or local firmware inputs');
|
|
51709
|
-
}
|
|
51710
|
-
let { artifactReader } = payload;
|
|
51711
|
-
if (preparedPlan) {
|
|
51712
|
-
artifactReader = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest).artifactReader;
|
|
51713
|
-
}
|
|
51714
|
-
else if (payload.hostBindingGeneration !== undefined) {
|
|
51715
|
-
artifactReader = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration).artifactReader;
|
|
51716
|
-
}
|
|
51717
|
-
if (preparedPlan) {
|
|
51408
|
+
if (hostBinding) {
|
|
51718
51409
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
51719
|
-
preparedPlan,
|
|
51410
|
+
preparedPlan: payload.preparedPlan,
|
|
51720
51411
|
executor: 'v4',
|
|
51721
51412
|
platform: payload.platform,
|
|
51722
|
-
scopeTargets: [
|
|
51723
|
-
|
|
51413
|
+
scopeTargets: [
|
|
51414
|
+
'boot',
|
|
51415
|
+
'app_v1',
|
|
51416
|
+
'app_v2',
|
|
51417
|
+
'coprocessor',
|
|
51418
|
+
'resource',
|
|
51419
|
+
'se01',
|
|
51420
|
+
'se02',
|
|
51421
|
+
'se03',
|
|
51422
|
+
'se04',
|
|
51423
|
+
],
|
|
51424
|
+
bindings: [
|
|
51425
|
+
...Object.entries((_a = payload.componentArtifacts) !== null && _a !== void 0 ? _a : {}).flatMap(([target, artifact]) => artifact
|
|
51426
|
+
? [
|
|
51427
|
+
{
|
|
51428
|
+
target: target,
|
|
51429
|
+
artifact,
|
|
51430
|
+
},
|
|
51431
|
+
]
|
|
51432
|
+
: []),
|
|
51433
|
+
...((_b = payload.resourceBundleArtifacts) !== null && _b !== void 0 ? _b : []).map((entry) => ({
|
|
51434
|
+
target: 'resource',
|
|
51435
|
+
logicalName: entry.name,
|
|
51436
|
+
artifact: entry.artifact,
|
|
51437
|
+
})),
|
|
51438
|
+
],
|
|
51724
51439
|
});
|
|
51725
|
-
if (payload.componentArtifacts) {
|
|
51726
|
-
const componentBindings = Object.entries(payload.componentArtifacts).flatMap(([target, artifact]) => artifact
|
|
51727
|
-
? [
|
|
51728
|
-
{
|
|
51729
|
-
target: target,
|
|
51730
|
-
artifact: artifact,
|
|
51731
|
-
},
|
|
51732
|
-
]
|
|
51733
|
-
: []);
|
|
51734
|
-
assertFirmwareUpdatePreparedPlanBinding({
|
|
51735
|
-
preparedPlan,
|
|
51736
|
-
executor: 'v4',
|
|
51737
|
-
platform: payload.platform,
|
|
51738
|
-
scopeTargets: componentBindings.map(binding => binding.target),
|
|
51739
|
-
bindings: componentBindings,
|
|
51740
|
-
});
|
|
51741
|
-
}
|
|
51742
|
-
}
|
|
51743
|
-
const preparedExpectedTargetVersions = preparedPlan === null || preparedPlan === void 0 ? void 0 : preparedPlan.artifacts.reduce((result, artifact) => {
|
|
51744
|
-
if (artifact.role === 'component' &&
|
|
51745
|
-
artifact.target !== 'resource' &&
|
|
51746
|
-
artifact.targetVersion &&
|
|
51747
|
-
PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.has(artifact.target)) {
|
|
51748
|
-
result[artifact.target] = artifact.targetVersion;
|
|
51749
|
-
}
|
|
51750
|
-
return result;
|
|
51751
|
-
}, {});
|
|
51752
|
-
const localTargetsToUpdate = (_a = payload.targetsToUpdate) === null || _a === void 0 ? void 0 : _a.map((target) => target === 'boot_resources' ? 'resource' : target);
|
|
51753
|
-
if (payload.resourceArchiveBinary &&
|
|
51754
|
-
localTargetsToUpdate &&
|
|
51755
|
-
!localTargetsToUpdate.includes('resource')) {
|
|
51756
|
-
localTargetsToUpdate.push('resource');
|
|
51757
51440
|
}
|
|
51758
|
-
const resolvedLocalTargetsToUpdate = localTargetsToUpdate !== null && localTargetsToUpdate !== void 0 ? localTargetsToUpdate : (payload.resourceArchiveBinary ? ['resource'] : undefined);
|
|
51759
51441
|
this.params = {
|
|
51760
|
-
preparedPlan,
|
|
51442
|
+
preparedPlan: payload.preparedPlan,
|
|
51761
51443
|
chunkSize: payload.chunkSize,
|
|
51762
51444
|
forcedUpdateRes: payload.forcedUpdateRes,
|
|
51763
51445
|
bootloaderBinary: payload.bootloaderBinary,
|
|
@@ -51769,18 +51451,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51769
51451
|
se02Binary: payload.se02Binary,
|
|
51770
51452
|
se03Binary: payload.se03Binary,
|
|
51771
51453
|
se04Binary: payload.se04Binary,
|
|
51772
|
-
|
|
51773
|
-
firmwareType:
|
|
51774
|
-
targetsToUpdate:
|
|
51775
|
-
|
|
51776
|
-
: resolvedLocalTargetsToUpdate,
|
|
51777
|
-
expectedTargetVersions: preparedPlan
|
|
51778
|
-
? preparedExpectedTargetVersions
|
|
51779
|
-
: payload.expectedTargetVersions,
|
|
51454
|
+
resourceFiles: payload.resourceFiles,
|
|
51455
|
+
firmwareType: payload.firmwareType,
|
|
51456
|
+
targetsToUpdate: payload.targetsToUpdate,
|
|
51457
|
+
expectedTargetVersions: payload.expectedTargetVersions,
|
|
51780
51458
|
platform: payload.platform,
|
|
51781
51459
|
expectedDeviceId: payload.expectedDeviceId,
|
|
51782
|
-
artifactReader,
|
|
51783
|
-
componentArtifacts:
|
|
51460
|
+
artifactReader: (_c = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _c !== void 0 ? _c : payload.artifactReader,
|
|
51461
|
+
componentArtifacts: payload.componentArtifacts,
|
|
51462
|
+
resourceBundleArtifacts: payload.resourceBundleArtifacts,
|
|
51784
51463
|
};
|
|
51785
51464
|
}
|
|
51786
51465
|
getProtocolV2FirmwareChunkSize(direction, filePath) {
|
|
@@ -51811,7 +51490,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51811
51490
|
});
|
|
51812
51491
|
}
|
|
51813
51492
|
runProtocolV2() {
|
|
51814
|
-
var _a, _b, _c, _d, _e
|
|
51493
|
+
var _a, _b, _c, _d, _e;
|
|
51815
51494
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51816
51495
|
yield this.captureProtocolV2PhysicalIdentity();
|
|
51817
51496
|
const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
|
|
@@ -51823,80 +51502,85 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51823
51502
|
const deviceFirmwareType = getFirmwareType(deviceFeatures);
|
|
51824
51503
|
const firmwareType = (_a = this.params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
|
|
51825
51504
|
this.validateExpectedTargetVersions();
|
|
51826
|
-
if (
|
|
51827
|
-
this.params.
|
|
51828
|
-
((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource'))) {
|
|
51829
|
-
const localMemoryHost = yield this.prepareProtocolV2LocalMemoryHost({
|
|
51830
|
-
features: deviceFeatures,
|
|
51831
|
-
firmwareType,
|
|
51832
|
-
});
|
|
51833
|
-
try {
|
|
51834
|
-
return yield this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
|
|
51835
|
-
}
|
|
51836
|
-
finally {
|
|
51837
|
-
localMemoryHost.release();
|
|
51838
|
-
}
|
|
51839
|
-
}
|
|
51840
|
-
const hasPreparedComponentArtifacts = Object.values((_c = this.params.componentArtifacts) !== null && _c !== void 0 ? _c : {}).some(Boolean);
|
|
51841
|
-
if (this.params.preparedPlan || hasPreparedComponentArtifacts) {
|
|
51505
|
+
if ((this.params.componentArtifacts && Object.keys(this.params.componentArtifacts).length > 0) ||
|
|
51506
|
+
((_b = this.params.resourceBundleArtifacts) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
51842
51507
|
return this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
|
|
51843
51508
|
}
|
|
51844
|
-
const
|
|
51509
|
+
const hasExplicitResourceFiles = !!((_c = this.params.resourceFiles) === null || _c === void 0 ? void 0 : _c.length);
|
|
51510
|
+
const wantsStableResources = !!((_d = this.params.targetsToUpdate) === null || _d === void 0 ? void 0 : _d.includes('resource'));
|
|
51511
|
+
const wantsBootResources = !!((_e = this.params.targetsToUpdate) === null || _e === void 0 ? void 0 : _e.includes('boot_resources'));
|
|
51512
|
+
const needsRemoteResources = !hasExplicitResourceFiles && wantsStableResources;
|
|
51513
|
+
const needsRemoteBootResources = !hasExplicitResourceFiles && (wantsBootResources || wantsStableResources);
|
|
51845
51514
|
let fwBinaryMap = [];
|
|
51846
51515
|
let bootloaderBinary = null;
|
|
51847
51516
|
let installItems;
|
|
51517
|
+
let resourceBundles;
|
|
51848
51518
|
try {
|
|
51849
51519
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
51520
|
+
resourceBundles = this.prepareExplicitProtocolV2ResourceFiles();
|
|
51850
51521
|
fwBinaryMap = this.collectExplicitTargetBinaries();
|
|
51851
51522
|
bootloaderBinary = this.prepareBootloaderBinary();
|
|
51852
|
-
const
|
|
51853
|
-
|
|
51854
|
-
fwBinaryMap,
|
|
51855
|
-
});
|
|
51856
|
-
const missingFirmwareTargets = this.getMissingProtocolV2FirmwareTargets(explicitInstallItems);
|
|
51857
|
-
const needsRemoteFirmware = ((_e = this.params.targetsToUpdate) === null || _e === void 0 ? void 0 : _e.length)
|
|
51858
|
-
? missingFirmwareTargets.length > 0
|
|
51859
|
-
: explicitInstallItems.length === 0;
|
|
51860
|
-
if (wantsResources) {
|
|
51861
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive must be provided through a local or external PreparedPlan', {
|
|
51862
|
-
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51863
|
-
});
|
|
51864
|
-
}
|
|
51865
|
-
if (needsRemoteFirmware &&
|
|
51523
|
+
const needsRemoteFirmware = !this.hasExplicitProtocolV2Payload(fwBinaryMap);
|
|
51524
|
+
if ((needsRemoteFirmware || needsRemoteResources || needsRemoteBootResources) &&
|
|
51866
51525
|
(this.params.artifactReader ||
|
|
51867
51526
|
DataManager.getSettings('firmwareManifestMode') === 'external-only')) {
|
|
51868
51527
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware artifacts must be prepared by the external firmware host', {
|
|
51869
51528
|
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51870
51529
|
});
|
|
51871
51530
|
}
|
|
51872
|
-
if (needsRemoteFirmware) {
|
|
51873
|
-
yield DataManager.forceReloadData(
|
|
51531
|
+
if (needsRemoteFirmware || needsRemoteResources || needsRemoteBootResources) {
|
|
51532
|
+
yield DataManager.forceReloadData({
|
|
51533
|
+
requireResources: needsRemoteResources || needsRemoteBootResources,
|
|
51534
|
+
});
|
|
51874
51535
|
}
|
|
51875
51536
|
if (needsRemoteFirmware) {
|
|
51876
|
-
const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures
|
|
51537
|
+
const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures);
|
|
51877
51538
|
bootloaderBinary = remoteBinaries.bootloaderBinary;
|
|
51878
51539
|
fwBinaryMap = remoteBinaries.fwBinaryMap;
|
|
51879
51540
|
installItems = remoteBinaries.installItems;
|
|
51880
51541
|
}
|
|
51881
|
-
this.
|
|
51542
|
+
const bootResourceFiles = yield this.prepareProtocolV2BootResources();
|
|
51543
|
+
if (bootResourceFiles === null || bootResourceFiles === void 0 ? void 0 : bootResourceFiles.length) {
|
|
51544
|
+
resourceBundles = this.mergeProtocolV2ResourceBundles(resourceBundles, bootResourceFiles);
|
|
51545
|
+
}
|
|
51546
|
+
if (!needsRemoteResources) {
|
|
51547
|
+
this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
|
|
51548
|
+
}
|
|
51882
51549
|
}
|
|
51883
51550
|
catch (err) {
|
|
51884
|
-
if (typeof err === 'object' &&
|
|
51885
|
-
err !== null &&
|
|
51886
|
-
'params' in err &&
|
|
51887
|
-
((_f = err.params) === null || _f === void 0 ? void 0 : _f.firmwareUpdateCode) === 'FirmwareArtifactsNotPrepared') {
|
|
51888
|
-
throw err;
|
|
51889
|
-
}
|
|
51890
51551
|
if (err instanceof hdShared.HardwareError && err.errorCode === hdShared.HardwareErrorCode.NetworkError) {
|
|
51891
51552
|
throw err;
|
|
51892
51553
|
}
|
|
51893
51554
|
throw normalizeFirmwarePreparationError(err);
|
|
51894
51555
|
}
|
|
51895
|
-
if (!bootloaderBinary &&
|
|
51556
|
+
if (!bootloaderBinary &&
|
|
51557
|
+
fwBinaryMap.length === 0 &&
|
|
51558
|
+
!(installItems === null || installItems === void 0 ? void 0 : installItems.length) &&
|
|
51559
|
+
!(resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length) &&
|
|
51560
|
+
!needsRemoteResources) {
|
|
51896
51561
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
|
|
51897
51562
|
}
|
|
51898
|
-
|
|
51899
|
-
|
|
51563
|
+
if (needsRemoteResources) {
|
|
51564
|
+
const enteredBootloader = yield this.enterProtocolV2BootloaderMode();
|
|
51565
|
+
try {
|
|
51566
|
+
const stableResources = yield this.prepareProtocolV2ResourceBundles();
|
|
51567
|
+
resourceBundles = this.mergeProtocolV2ResourceBundles(resourceBundles, stableResources);
|
|
51568
|
+
this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
|
|
51569
|
+
}
|
|
51570
|
+
catch (err) {
|
|
51571
|
+
if (enteredBootloader) {
|
|
51572
|
+
try {
|
|
51573
|
+
yield this.exitProtocolV2BootloaderToNormal();
|
|
51574
|
+
}
|
|
51575
|
+
catch (restoreError) {
|
|
51576
|
+
Log$6.warn('[FirmwareUpdateV4] failed to restore App mode after resource preparation error:', restoreError);
|
|
51577
|
+
}
|
|
51578
|
+
}
|
|
51579
|
+
throw normalizeFirmwarePreparationError(err);
|
|
51580
|
+
}
|
|
51581
|
+
}
|
|
51582
|
+
return this.executeProtocolV2Update(Object.assign(Object.assign({ fwBinaryMap,
|
|
51583
|
+
bootloaderBinary }, (installItems ? { installItems } : undefined)), ((resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length) ? { resourceBundles } : undefined)));
|
|
51900
51584
|
});
|
|
51901
51585
|
}
|
|
51902
51586
|
openProtocolV2PreparedSource(artifact) {
|
|
@@ -51933,34 +51617,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51933
51617
|
prepareProtocolV2InstallSources(firmwareType, features) {
|
|
51934
51618
|
var _a, _b;
|
|
51935
51619
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51936
|
-
if (this.params.preparedPlan) {
|
|
51937
|
-
const requestedTargets = new Set(this.params.preparedPlan.targetsToUpdate.filter((target) => target !== 'resource'));
|
|
51938
|
-
const installSources = [];
|
|
51939
|
-
const preparedTargets = new Set();
|
|
51940
|
-
for (const artifact of this.params.preparedPlan.artifacts) {
|
|
51941
|
-
if (artifact.target !== 'resource') {
|
|
51942
|
-
const target = artifact.target;
|
|
51943
|
-
const installTarget = PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.get(target);
|
|
51944
|
-
if (!requestedTargets.has(target) ||
|
|
51945
|
-
artifact.role !== 'component' ||
|
|
51946
|
-
artifact.container !== 'raw' ||
|
|
51947
|
-
!installTarget ||
|
|
51948
|
-
preparedTargets.has(target)) {
|
|
51949
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 prepared component artifact is invalid: ${artifact.artifactId}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51950
|
-
}
|
|
51951
|
-
installSources.push(Object.assign(Object.assign({}, installTarget), { source: yield this.openProtocolV2PreparedSource(artifact.artifact) }));
|
|
51952
|
-
preparedTargets.add(target);
|
|
51953
|
-
}
|
|
51954
|
-
}
|
|
51955
|
-
const missingTarget = Array.from(requestedTargets).find(target => !preparedTargets.has(target));
|
|
51956
|
-
if (missingTarget) {
|
|
51957
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 ${missingTarget} artifact is not prepared`, {
|
|
51958
|
-
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51959
|
-
artifactName: missingTarget,
|
|
51960
|
-
});
|
|
51961
|
-
}
|
|
51962
|
-
return installSources;
|
|
51963
|
-
}
|
|
51964
51620
|
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
51965
51621
|
if (!release) {
|
|
51966
51622
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware release is unavailable');
|
|
@@ -51991,278 +51647,39 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51991
51647
|
return installSources;
|
|
51992
51648
|
});
|
|
51993
51649
|
}
|
|
51994
|
-
|
|
51995
|
-
var _a, _b;
|
|
51996
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
51997
|
-
const installItems = this.buildProtocolV2InstallItems({
|
|
51998
|
-
bootloaderBinary: this.prepareBootloaderBinary(),
|
|
51999
|
-
fwBinaryMap: this.collectExplicitTargetBinaries(),
|
|
52000
|
-
});
|
|
52001
|
-
const requestedComponentTargets = new Set(((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter((target) => target !== 'resource' && target !== 'boot_resources'));
|
|
52002
|
-
const localComponentTargets = new Set(installItems.flatMap(item => {
|
|
52003
|
-
const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
|
|
52004
|
-
return target ? [target] : [];
|
|
52005
|
-
}));
|
|
52006
|
-
const missingTarget = Array.from(requestedComponentTargets).find(target => !localComponentTargets.has(target));
|
|
52007
|
-
if (missingTarget) {
|
|
52008
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local update has no binary for requested target ${missingTarget}`, {
|
|
52009
|
-
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
52010
|
-
artifactName: missingTarget,
|
|
52011
|
-
});
|
|
52012
|
-
}
|
|
52013
|
-
const planArtifacts = [];
|
|
52014
|
-
const memoryArtifacts = [];
|
|
52015
|
-
for (const item of installItems) {
|
|
52016
|
-
const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
|
|
52017
|
-
if (!target || item.binary.byteLength <= 0) {
|
|
52018
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local firmware artifact is invalid: ${item.fileName}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52019
|
-
}
|
|
52020
|
-
const artifactId = `component:${target}`;
|
|
52021
|
-
planArtifacts.push(Object.assign({ artifactId,
|
|
52022
|
-
target, container: 'raw', logicalName: item.fileName, expectedSize: item.binary.byteLength, expectedSha256: bytesToHex(sha256.sha256(new Uint8Array(item.binary))) }, (((_b = this.params.expectedTargetVersions) === null || _b === void 0 ? void 0 : _b[target])
|
|
52023
|
-
? { targetVersion: this.params.expectedTargetVersions[target] }
|
|
52024
|
-
: {})));
|
|
52025
|
-
memoryArtifacts.push({ artifactId, binary: item.binary });
|
|
52026
|
-
}
|
|
52027
|
-
const resourceArchive = yield this.prepareProtocolV2LocalResourceArchive(this.params.resourceArchiveBinary);
|
|
52028
|
-
const resourceArtifactId = 'resource:archive';
|
|
52029
|
-
planArtifacts.push({
|
|
52030
|
-
artifactId: resourceArtifactId,
|
|
52031
|
-
target: 'resource',
|
|
52032
|
-
container: 'zip',
|
|
52033
|
-
logicalName: 'protocol-v2-local-resource-archive',
|
|
52034
|
-
expectedSize: resourceArchive.binary.byteLength,
|
|
52035
|
-
expectedSha256: bytesToHex(sha256.sha256(new Uint8Array(resourceArchive.binary))),
|
|
52036
|
-
});
|
|
52037
|
-
memoryArtifacts.push({
|
|
52038
|
-
artifactId: resourceArtifactId,
|
|
52039
|
-
binary: resourceArchive.binary,
|
|
52040
|
-
materializedEntries: resourceArchive.materializedEntries,
|
|
52041
|
-
});
|
|
52042
|
-
const plan = buildProtocolV2LocalFirmwareUpdatePlan({
|
|
52043
|
-
features,
|
|
52044
|
-
firmwareType,
|
|
52045
|
-
platform: this.params.platform,
|
|
52046
|
-
artifacts: planArtifacts,
|
|
52047
|
-
});
|
|
52048
|
-
let memoryHost;
|
|
52049
|
-
try {
|
|
52050
|
-
memoryHost = prepareFirmwareUpdateV4MemoryHost({
|
|
52051
|
-
sdk: {
|
|
52052
|
-
prepareFirmwareUpdatePlan,
|
|
52053
|
-
registerFirmwareUpdateHostBinding,
|
|
52054
|
-
unregisterFirmwareUpdateHostBinding,
|
|
52055
|
-
},
|
|
52056
|
-
plan,
|
|
52057
|
-
artifacts: memoryArtifacts,
|
|
52058
|
-
});
|
|
52059
|
-
const preparedPlan = validateFirmwareUpdatePreparedPlan(memoryHost.preparedPlan);
|
|
52060
|
-
assertFirmwareUpdatePreparedPlanBinding({
|
|
52061
|
-
preparedPlan,
|
|
52062
|
-
executor: 'v4',
|
|
52063
|
-
platform: this.params.platform,
|
|
52064
|
-
scopeTargets: [],
|
|
52065
|
-
bindings: [],
|
|
52066
|
-
});
|
|
52067
|
-
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
52068
|
-
preparedPlan,
|
|
52069
|
-
deviceIdentity: this.protocolV2ExpectedSerialNumber,
|
|
52070
|
-
deviceModel: this.getProtocolV2PreparedPlanDeviceModel(features),
|
|
52071
|
-
});
|
|
52072
|
-
const hostBinding = resolveFirmwareUpdateHostBinding(memoryHost.hostBindingGeneration, preparedPlan.preparedPlanDigest);
|
|
52073
|
-
this.params.preparedPlan = preparedPlan;
|
|
52074
|
-
this.params.targetsToUpdate = [...preparedPlan.targetsToUpdate];
|
|
52075
|
-
this.params.artifactReader = hostBinding.artifactReader;
|
|
52076
|
-
this.params.componentArtifacts = undefined;
|
|
52077
|
-
return memoryHost;
|
|
52078
|
-
}
|
|
52079
|
-
catch (error) {
|
|
52080
|
-
memoryHost === null || memoryHost === void 0 ? void 0 : memoryHost.release();
|
|
52081
|
-
throw error;
|
|
52082
|
-
}
|
|
52083
|
-
});
|
|
52084
|
-
}
|
|
52085
|
-
prepareProtocolV2LocalResourceArchive(binary) {
|
|
52086
|
-
var _a;
|
|
52087
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
52088
|
-
if (binary.byteLength <= 0 || binary.byteLength > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
|
|
52089
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP archive size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52090
|
-
}
|
|
52091
|
-
const zip = yield JSZip__default["default"].loadAsync(binary);
|
|
52092
|
-
const zipEntries = Object.values(zip.files);
|
|
52093
|
-
if (zipEntries.some(entry => entry.unsafeOriginalName && entry.unsafeOriginalName !== entry.name)) {
|
|
52094
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unsafe entry path', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52095
|
-
}
|
|
52096
|
-
const entries = zipEntries.filter(entry => !entry.dir);
|
|
52097
|
-
if (entries.length === 0 || entries.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT + 1) {
|
|
52098
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP entry set is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52099
|
-
}
|
|
52100
|
-
let declaredUncompressedSize = 0;
|
|
52101
|
-
let declaredCompressedSize = 0;
|
|
52102
|
-
for (const entry of entries) {
|
|
52103
|
-
const sizes = getProtocolV2ZipEntrySizes(entry);
|
|
52104
|
-
declaredCompressedSize += sizes.compressedSize;
|
|
52105
|
-
declaredUncompressedSize += sizes.uncompressedSize;
|
|
52106
|
-
const entryLimit = entry.name === 'manifest.json'
|
|
52107
|
-
? PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES
|
|
52108
|
-
: PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES;
|
|
52109
|
-
if (sizes.uncompressedSize > entryLimit ||
|
|
52110
|
-
declaredCompressedSize > binary.byteLength ||
|
|
52111
|
-
declaredUncompressedSize >
|
|
52112
|
-
PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES + PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
|
|
52113
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP declared size exceeds the allowed limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52114
|
-
}
|
|
52115
|
-
}
|
|
52116
|
-
const manifestEntry = zip.file('manifest.json');
|
|
52117
|
-
if (!manifestEntry) {
|
|
52118
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP has no manifest.json', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52119
|
-
}
|
|
52120
|
-
const manifestBinary = yield manifestEntry.async('arraybuffer');
|
|
52121
|
-
if (manifestBinary.byteLength <= 0 ||
|
|
52122
|
-
manifestBinary.byteLength > PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
|
|
52123
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52124
|
-
}
|
|
52125
|
-
let manifestValue;
|
|
52126
|
-
try {
|
|
52127
|
-
manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
|
|
52128
|
-
}
|
|
52129
|
-
catch (error) {
|
|
52130
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52131
|
-
}
|
|
52132
|
-
const manifest = parseProtocolV2ResourceManifest(manifestValue);
|
|
52133
|
-
const selectedFiles = selectProtocolV2ResourceManifestFiles({
|
|
52134
|
-
manifest,
|
|
52135
|
-
targetsToUpdate: (_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [],
|
|
52136
|
-
});
|
|
52137
|
-
const expectedEntryNames = new Set([
|
|
52138
|
-
'manifest.json',
|
|
52139
|
-
...selectedFiles.map(file => file.archive_path),
|
|
52140
|
-
]);
|
|
52141
|
-
if (entries.length !== expectedEntryNames.size ||
|
|
52142
|
-
entries.some(entry => !expectedEntryNames.has(entry.name))) {
|
|
52143
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unexpected entry', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52144
|
-
}
|
|
52145
|
-
let totalSize = 0;
|
|
52146
|
-
const materializedEntries = [
|
|
52147
|
-
{ entryName: 'manifest.json', binary: manifestBinary },
|
|
52148
|
-
];
|
|
52149
|
-
for (const file of selectedFiles) {
|
|
52150
|
-
const entry = zip.file(file.archive_path);
|
|
52151
|
-
if (!entry) {
|
|
52152
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP is missing ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52153
|
-
}
|
|
52154
|
-
const { uncompressedSize } = getProtocolV2ZipEntrySizes(entry);
|
|
52155
|
-
totalSize += uncompressedSize;
|
|
52156
|
-
if (uncompressedSize !== file.size || totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
|
|
52157
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file declared size is invalid: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52158
|
-
}
|
|
52159
|
-
const fileBinary = yield entry.async('arraybuffer');
|
|
52160
|
-
const digest = bytesToHex(sha256.sha256(new Uint8Array(fileBinary)));
|
|
52161
|
-
if (fileBinary.byteLength !== file.size || digest !== file.sha256.toLowerCase()) {
|
|
52162
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file does not match manifest: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
52163
|
-
}
|
|
52164
|
-
materializedEntries.push({ entryName: file.archive_path, binary: fileBinary });
|
|
52165
|
-
}
|
|
52166
|
-
return { binary, materializedEntries };
|
|
52167
|
-
});
|
|
52168
|
-
}
|
|
52169
|
-
prepareProtocolV2ResourceSources() {
|
|
52170
|
-
var _a, _b;
|
|
51650
|
+
prepareProtocolV2ResourceSources(firmwareType, features) {
|
|
51651
|
+
var _a, _b, _c;
|
|
52171
51652
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52172
|
-
const
|
|
51653
|
+
const preparedArtifacts = (_a = this.params.resourceBundleArtifacts) !== null && _a !== void 0 ? _a : [];
|
|
51654
|
+
const resourceRequested = ((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource')) || preparedArtifacts.length > 0;
|
|
52173
51655
|
if (!resourceRequested) {
|
|
52174
51656
|
return [];
|
|
52175
51657
|
}
|
|
52176
|
-
const
|
|
52177
|
-
|
|
52178
|
-
|
|
52179
|
-
}
|
|
52180
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive is not prepared', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52181
|
-
});
|
|
52182
|
-
}
|
|
52183
|
-
prepareProtocolV2ResourceArchiveSources() {
|
|
52184
|
-
var _a, _b, _c, _d;
|
|
52185
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
52186
|
-
const archiveArtifacts = (_b = (_a = this.params.preparedPlan) === null || _a === void 0 ? void 0 : _a.artifacts.filter(artifact => artifact.role === 'resourceBundle' &&
|
|
52187
|
-
artifact.target === 'resource' &&
|
|
52188
|
-
artifact.container === 'zip')) !== null && _b !== void 0 ? _b : [];
|
|
52189
|
-
if (archiveArtifacts.length === 0) {
|
|
52190
|
-
return undefined;
|
|
52191
|
-
}
|
|
52192
|
-
if (archiveArtifacts.length !== 1) {
|
|
52193
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared plan must contain exactly one resource archive', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52194
|
-
}
|
|
52195
|
-
const archiveArtifact = archiveArtifacts[0];
|
|
52196
|
-
const archiveSource = yield this.openProtocolV2PreparedSource(archiveArtifact.artifact);
|
|
52197
|
-
if (archiveSource.size > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
|
|
52198
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive exceeds the total size limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52199
|
-
}
|
|
52200
|
-
let archiveBinary;
|
|
52201
|
-
try {
|
|
52202
|
-
archiveBinary = yield readFirmwareByteSourceFully(archiveSource);
|
|
52203
|
-
}
|
|
52204
|
-
finally {
|
|
52205
|
-
yield archiveSource.close();
|
|
52206
|
-
}
|
|
52207
|
-
const archiveDigest = bytesToHex(sha256.sha256(new Uint8Array(archiveBinary)));
|
|
52208
|
-
if (archiveDigest !== archiveArtifact.artifact.sha256.toLowerCase()) {
|
|
52209
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive does not match its approved receipt', { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
52210
|
-
}
|
|
52211
|
-
const verifiedArchive = yield this.prepareProtocolV2LocalResourceArchive(archiveBinary);
|
|
52212
|
-
const entries = (_c = archiveArtifact.materializedEntries) !== null && _c !== void 0 ? _c : [];
|
|
52213
|
-
const entriesByName = new Map(entries.map(entry => [entry.entryName, entry]));
|
|
52214
|
-
if (entries.length !== verifiedArchive.materializedEntries.length ||
|
|
52215
|
-
verifiedArchive.materializedEntries.some(entry => {
|
|
52216
|
-
const preparedEntry = entriesByName.get(entry.entryName);
|
|
52217
|
-
const digest = bytesToHex(sha256.sha256(new Uint8Array(entry.binary)));
|
|
52218
|
-
return (!preparedEntry ||
|
|
52219
|
-
preparedEntry.artifact.size !== entry.binary.byteLength ||
|
|
52220
|
-
preparedEntry.artifact.sha256.toLowerCase() !== digest);
|
|
52221
|
-
})) {
|
|
52222
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource entries do not match the approved archive', { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
52223
|
-
}
|
|
52224
|
-
const verifiedEntriesByName = new Map(verifiedArchive.materializedEntries.map(entry => [entry.entryName, entry.binary]));
|
|
52225
|
-
const manifestBinary = verifiedEntriesByName.get('manifest.json');
|
|
52226
|
-
if (!manifestBinary) {
|
|
52227
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive has no valid manifest.json', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52228
|
-
}
|
|
52229
|
-
let manifestValue;
|
|
52230
|
-
try {
|
|
52231
|
-
manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
|
|
52232
|
-
}
|
|
52233
|
-
catch (error) {
|
|
52234
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 prepared resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52235
|
-
}
|
|
52236
|
-
const manifest = parseProtocolV2ResourceManifest(manifestValue);
|
|
52237
|
-
const selectedFiles = selectProtocolV2ResourceManifestFiles({
|
|
52238
|
-
manifest,
|
|
52239
|
-
targetsToUpdate: (_d = this.params.targetsToUpdate) !== null && _d !== void 0 ? _d : [],
|
|
52240
|
-
});
|
|
52241
|
-
if (selectedFiles.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT) {
|
|
52242
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive contains too many files', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52243
|
-
}
|
|
52244
|
-
let totalSize = 0;
|
|
51658
|
+
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
51659
|
+
const descriptors = (_c = release === null || release === void 0 ? void 0 : release.resourceBundles) !== null && _c !== void 0 ? _c : [];
|
|
51660
|
+
const artifactByName = new Map(preparedArtifacts.map(item => [item.name, item.artifact]));
|
|
52245
51661
|
const sources = [];
|
|
52246
|
-
for (const
|
|
52247
|
-
const
|
|
52248
|
-
if (!
|
|
52249
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2
|
|
52250
|
-
|
|
52251
|
-
|
|
52252
|
-
|
|
52253
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive exceeds the total size limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51662
|
+
for (const descriptor of descriptors) {
|
|
51663
|
+
const artifact = artifactByName.get(descriptor.name);
|
|
51664
|
+
if (!artifact) {
|
|
51665
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource bundle ${descriptor.name} is not prepared`, {
|
|
51666
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51667
|
+
artifactName: descriptor.name,
|
|
51668
|
+
});
|
|
52254
51669
|
}
|
|
52255
|
-
const
|
|
52256
|
-
|
|
52257
|
-
|
|
52258
|
-
:
|
|
52259
|
-
|
|
52260
|
-
|
|
52261
|
-
|
|
52262
|
-
|
|
52263
|
-
|
|
52264
|
-
|
|
52265
|
-
|
|
51670
|
+
const devicePath = validateProtocolV2FilesystemPath(descriptor.devicePath, 'resourceBundles[].devicePath');
|
|
51671
|
+
sources.push({
|
|
51672
|
+
name: descriptor.name,
|
|
51673
|
+
source: yield this.openProtocolV2PreparedSource(artifact),
|
|
51674
|
+
devicePath,
|
|
51675
|
+
version: descriptor.version,
|
|
51676
|
+
payloadHash: descriptor.payloadHash,
|
|
51677
|
+
headerHash: descriptor.headerHash,
|
|
51678
|
+
});
|
|
51679
|
+
artifactByName.delete(descriptor.name);
|
|
51680
|
+
}
|
|
51681
|
+
if (artifactByName.size > 0) {
|
|
51682
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 release does not contain resource bundle ${artifactByName.keys().next().value}`);
|
|
52266
51683
|
}
|
|
52267
51684
|
return sources;
|
|
52268
51685
|
});
|
|
@@ -52272,7 +51689,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52272
51689
|
try {
|
|
52273
51690
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
52274
51691
|
const installSources = yield this.prepareProtocolV2InstallSources(firmwareType, features);
|
|
52275
|
-
const resourceSources = yield this.prepareProtocolV2ResourceSources();
|
|
51692
|
+
const resourceSources = yield this.prepareProtocolV2ResourceSources(firmwareType, features);
|
|
52276
51693
|
if (installSources.length === 0 && resourceSources.length === 0) {
|
|
52277
51694
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
|
|
52278
51695
|
}
|
|
@@ -52356,15 +51773,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52356
51773
|
}
|
|
52357
51774
|
}
|
|
52358
51775
|
getProtocolV2RequestedTargets() {
|
|
52359
|
-
var _a, _b, _c;
|
|
51776
|
+
var _a, _b, _c, _d;
|
|
52360
51777
|
if ((_a = this.params.targetsToUpdate) === null || _a === void 0 ? void 0 : _a.length) {
|
|
52361
51778
|
return [...new Set(this.params.targetsToUpdate)];
|
|
52362
51779
|
}
|
|
52363
|
-
if ((_b = this.params.preparedPlan) === null || _b === void 0 ? void 0 : _b.targetsToUpdate.length) {
|
|
52364
|
-
return [...new Set(this.params.preparedPlan.targetsToUpdate)];
|
|
52365
|
-
}
|
|
52366
51780
|
const targets = new Set();
|
|
52367
|
-
Object.keys((
|
|
51781
|
+
Object.keys((_b = this.params.componentArtifacts) !== null && _b !== void 0 ? _b : {}).forEach(target => targets.add(target));
|
|
51782
|
+
if (((_c = this.params.resourceBundleArtifacts) === null || _c === void 0 ? void 0 : _c.length) || ((_d = this.params.resourceFiles) === null || _d === void 0 ? void 0 : _d.length)) {
|
|
51783
|
+
targets.add('resource');
|
|
51784
|
+
}
|
|
52368
51785
|
if (this.params.bootloaderBinary)
|
|
52369
51786
|
targets.add('boot');
|
|
52370
51787
|
if (this.params.applicationP1Binary)
|
|
@@ -52401,26 +51818,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52401
51818
|
const serialNumber = (_b = (_a = deviceInfo.hw) === null || _a === void 0 ? void 0 : _a.serial_no) === null || _b === void 0 ? void 0 : _b.trim();
|
|
52402
51819
|
return serialNumber || undefined;
|
|
52403
51820
|
}
|
|
52404
|
-
getProtocolV2PreparedPlanDeviceModel(features) {
|
|
52405
|
-
const currentDeviceType = this.device.getCurrentDeviceType();
|
|
52406
|
-
const featureDeviceType = features ? getDeviceType(features) : undefined;
|
|
52407
|
-
const deviceType = currentDeviceType === hdShared.EDeviceType.Pro2 || currentDeviceType === hdShared.EDeviceType.Neo
|
|
52408
|
-
? currentDeviceType
|
|
52409
|
-
: featureDeviceType;
|
|
52410
|
-
return deviceType === hdShared.EDeviceType.Pro2 || deviceType === hdShared.EDeviceType.Neo
|
|
52411
|
-
? String(deviceType)
|
|
52412
|
-
: undefined;
|
|
52413
|
-
}
|
|
52414
|
-
getProtocolV2ConnectionRoute() {
|
|
52415
|
-
var _a, _b, _c, _d, _e;
|
|
52416
|
-
const descriptor = this.device.originalDescriptor;
|
|
52417
|
-
return (((_a = descriptor === null || descriptor === void 0 ? void 0 : descriptor.path) === null || _a === void 0 ? void 0 : _a.trim()) ||
|
|
52418
|
-
((_d = (_c = (_b = this.device).getConnectId) === null || _c === void 0 ? void 0 : _c.call(_b)) === null || _d === void 0 ? void 0 : _d.trim()) ||
|
|
52419
|
-
((_e = descriptor === null || descriptor === void 0 ? void 0 : descriptor.id) === null || _e === void 0 ? void 0 : _e.trim()) ||
|
|
52420
|
-
undefined);
|
|
52421
|
-
}
|
|
52422
51821
|
assertProtocolV2DeviceInfoIdentity(deviceInfo) {
|
|
52423
|
-
assertProtocolV2ReconnectIdentity(this.protocolV2ExpectedSerialNumber, this.getProtocolV2SerialNumber(deviceInfo), this.protocolV2ExpectedPath, this.
|
|
51822
|
+
assertProtocolV2ReconnectIdentity(this.protocolV2ExpectedSerialNumber, this.getProtocolV2SerialNumber(deviceInfo), this.protocolV2ExpectedPath, this.device.originalDescriptor.path);
|
|
52424
51823
|
}
|
|
52425
51824
|
getProtocolV2DeviceInfoTimeout() {
|
|
52426
51825
|
var _a;
|
|
@@ -52437,20 +51836,19 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52437
51836
|
});
|
|
52438
51837
|
}
|
|
52439
51838
|
captureProtocolV2PhysicalIdentity() {
|
|
52440
|
-
var _a, _b, _c;
|
|
51839
|
+
var _a, _b, _c, _d, _e;
|
|
52441
51840
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52442
51841
|
const deviceInfo = yield this.requestProtocolV2PhysicalIdentity();
|
|
52443
51842
|
const serialNumber = this.getProtocolV2SerialNumber(deviceInfo);
|
|
52444
|
-
const path = this.
|
|
52445
|
-
if ((
|
|
51843
|
+
const path = ((_b = (_a = this.device.originalDescriptor) === null || _a === void 0 ? void 0 : _a.path) === null || _b === void 0 ? void 0 : _b.trim()) || undefined;
|
|
51844
|
+
if ((_c = this.params) === null || _c === void 0 ? void 0 : _c.preparedPlan) {
|
|
52446
51845
|
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
52447
51846
|
preparedPlan: this.params.preparedPlan,
|
|
52448
51847
|
deviceIdentity: serialNumber,
|
|
52449
|
-
deviceModel: this.getProtocolV2PreparedPlanDeviceModel(this.device.features),
|
|
52450
51848
|
});
|
|
52451
51849
|
}
|
|
52452
|
-
else if ((
|
|
52453
|
-
assertProtocolV2ReconnectIdentity((
|
|
51850
|
+
else if ((_d = this.params) === null || _d === void 0 ? void 0 : _d.expectedDeviceId) {
|
|
51851
|
+
assertProtocolV2ReconnectIdentity((_e = this.params) === null || _e === void 0 ? void 0 : _e.expectedDeviceId, serialNumber);
|
|
52454
51852
|
}
|
|
52455
51853
|
else {
|
|
52456
51854
|
assertProtocolV2ReconnectIdentity(serialNumber, serialNumber, path, path);
|
|
@@ -52470,15 +51868,11 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52470
51868
|
var _a;
|
|
52471
51869
|
return (_a = this.params.bootloaderBinary) !== null && _a !== void 0 ? _a : null;
|
|
52472
51870
|
}
|
|
52473
|
-
|
|
51871
|
+
hasExplicitProtocolV2Payload(fwBinaryMap) {
|
|
52474
51872
|
var _a;
|
|
52475
|
-
|
|
52476
|
-
|
|
52477
|
-
|
|
52478
|
-
}));
|
|
52479
|
-
return ((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [])
|
|
52480
|
-
.filter((target) => target !== 'resource' && target !== 'boot_resources')
|
|
52481
|
-
.filter(target => !preparedTargets.has(target));
|
|
51873
|
+
return (!!((_a = this.params.resourceFiles) === null || _a === void 0 ? void 0 : _a.length) ||
|
|
51874
|
+
!!this.params.bootloaderBinary ||
|
|
51875
|
+
fwBinaryMap.length > 0);
|
|
52482
51876
|
}
|
|
52483
51877
|
buildProtocolV2InstallItems({ bootloaderBinary, fwBinaryMap, }) {
|
|
52484
51878
|
const installItems = [];
|
|
@@ -52527,17 +51921,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52527
51921
|
if (!component.url) {
|
|
52528
51922
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Missing Protocol V2 firmware component url: ${key}/${component.target}`);
|
|
52529
51923
|
}
|
|
52530
|
-
const expectedFingerprint = normalizeProtocolV2Hex(component.fingerprint);
|
|
52531
|
-
if (!Number.isSafeInteger(component.expectedSize) ||
|
|
52532
|
-
Number(component.expectedSize) <= 0 ||
|
|
52533
|
-
!expectedFingerprint ||
|
|
52534
|
-
!/^[0-9a-f]{64}$/u.test(expectedFingerprint)) {
|
|
52535
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware component integrity metadata is invalid: ${key}/${component.target}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
52536
|
-
}
|
|
52537
51924
|
const { binary } = yield getSysResourceBinary(component.url);
|
|
52538
|
-
if (binary.byteLength !== component.expectedSize) {
|
|
52539
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware size mismatch: ${key}/${component.target}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
52540
|
-
}
|
|
52541
51925
|
if (!isProtocolV2FirmwareFingerprintValid(binary, component.fingerprint)) {
|
|
52542
51926
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware fingerprint mismatch: ${key}/${component.target}`);
|
|
52543
51927
|
}
|
|
@@ -52551,7 +51935,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52551
51935
|
return Object.assign(Object.assign({}, target), { binary });
|
|
52552
51936
|
});
|
|
52553
51937
|
}
|
|
52554
|
-
prepareRemoteProtocolV2Binaries(firmwareType, features
|
|
51938
|
+
prepareRemoteProtocolV2Binaries(firmwareType, features) {
|
|
52555
51939
|
var _a, _b;
|
|
52556
51940
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52557
51941
|
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
@@ -52559,10 +51943,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52559
51943
|
const fwBinaryMap = [];
|
|
52560
51944
|
const installItems = [];
|
|
52561
51945
|
if (!release) {
|
|
52562
|
-
const missingFirmwareTargets = this.getMissingProtocolV2FirmwareTargets(explicitInstallItems);
|
|
52563
|
-
if (missingFirmwareTargets.length > 0) {
|
|
52564
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware release is unavailable for requested targets: ${missingFirmwareTargets.join(', ')}`);
|
|
52565
|
-
}
|
|
52566
51946
|
return {
|
|
52567
51947
|
bootloaderBinary,
|
|
52568
51948
|
fwBinaryMap,
|
|
@@ -52571,8 +51951,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52571
51951
|
}
|
|
52572
51952
|
const entries = this.getRemoteComponentEntries(release);
|
|
52573
51953
|
const targetsToUpdate = new Set((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : []);
|
|
52574
|
-
const explicitInstallItemByTargetId = new Map(explicitInstallItems.map(item => [item.targetId, item]));
|
|
52575
|
-
const preparedTargets = new Set();
|
|
52576
51954
|
for (const [key, component] of entries) {
|
|
52577
51955
|
const targetName = (_b = component.target) === null || _b === void 0 ? void 0 : _b.toUpperCase();
|
|
52578
51956
|
const target = PROTOCOL_V2_REMOTE_COMPONENT_TARGETS[targetName];
|
|
@@ -52580,27 +51958,27 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52580
51958
|
? PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId)
|
|
52581
51959
|
: undefined;
|
|
52582
51960
|
if (updateTarget && targetsToUpdate.has(updateTarget)) {
|
|
52583
|
-
const
|
|
52584
|
-
|
|
52585
|
-
|
|
52586
|
-
|
|
51961
|
+
const remoteBinary = yield this.downloadRemoteProtocolV2Component(key, component);
|
|
51962
|
+
if (remoteBinary.kind === 'bootloader') {
|
|
51963
|
+
bootloaderBinary = remoteBinary.binary;
|
|
51964
|
+
installItems.push({
|
|
51965
|
+
fileName: remoteBinary.fileName,
|
|
51966
|
+
binary: remoteBinary.binary,
|
|
51967
|
+
targetId: remoteBinary.targetId,
|
|
51968
|
+
kind: remoteBinary.kind,
|
|
51969
|
+
});
|
|
52587
51970
|
}
|
|
52588
51971
|
else {
|
|
52589
51972
|
const binaryEntry = {
|
|
52590
|
-
fileName:
|
|
52591
|
-
binary:
|
|
52592
|
-
targetId:
|
|
51973
|
+
fileName: remoteBinary.fileName,
|
|
51974
|
+
binary: remoteBinary.binary,
|
|
51975
|
+
targetId: remoteBinary.targetId,
|
|
52593
51976
|
};
|
|
52594
51977
|
fwBinaryMap.push(binaryEntry);
|
|
51978
|
+
installItems.push(Object.assign(Object.assign({}, binaryEntry), { kind: remoteBinary.kind }));
|
|
52595
51979
|
}
|
|
52596
|
-
installItems.push(Object.assign({}, installItem));
|
|
52597
|
-
preparedTargets.add(updateTarget);
|
|
52598
51980
|
}
|
|
52599
51981
|
}
|
|
52600
|
-
const missingTarget = Array.from(targetsToUpdate).find(target => target !== 'resource' && !preparedTargets.has(target));
|
|
52601
|
-
if (missingTarget) {
|
|
52602
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 release does not contain requested target ${missingTarget}`);
|
|
52603
|
-
}
|
|
52604
51982
|
return {
|
|
52605
51983
|
bootloaderBinary,
|
|
52606
51984
|
fwBinaryMap,
|
|
@@ -52608,6 +51986,178 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52608
51986
|
};
|
|
52609
51987
|
});
|
|
52610
51988
|
}
|
|
51989
|
+
getProtocolV2DeviceType() {
|
|
51990
|
+
const deviceType = this.device.getCurrentDeviceType();
|
|
51991
|
+
if (deviceType === hdShared.EDeviceType.Pro2 || deviceType === hdShared.EDeviceType.Neo)
|
|
51992
|
+
return deviceType;
|
|
51993
|
+
throw new Error(`Unsupported Protocol V2 device type: ${deviceType}`);
|
|
51994
|
+
}
|
|
51995
|
+
prepareProtocolV2BootResources() {
|
|
51996
|
+
var _a, _b, _c, _d, _e;
|
|
51997
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51998
|
+
const wantsStableResources = !!((_a = this.params.targetsToUpdate) === null || _a === void 0 ? void 0 : _a.includes('resource'));
|
|
51999
|
+
const wantsBootResources = !!((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('boot_resources'));
|
|
52000
|
+
if (!wantsStableResources && !wantsBootResources) {
|
|
52001
|
+
return undefined;
|
|
52002
|
+
}
|
|
52003
|
+
if ((_c = this.params.resourceFiles) === null || _c === void 0 ? void 0 : _c.length) {
|
|
52004
|
+
return undefined;
|
|
52005
|
+
}
|
|
52006
|
+
const resource = DataManager.getProtocolV2BootResources(this.getProtocolV2DeviceType());
|
|
52007
|
+
if (!resource) {
|
|
52008
|
+
if (wantsBootResources) {
|
|
52009
|
+
throw new Error('Missing Protocol V2 boot resources configuration');
|
|
52010
|
+
}
|
|
52011
|
+
Log$6.debug('[FirmwareUpdateV4] no boot resources configured; continue with stable resources');
|
|
52012
|
+
return undefined;
|
|
52013
|
+
}
|
|
52014
|
+
const files = [];
|
|
52015
|
+
for (const file of resource.files) {
|
|
52016
|
+
const isCurrent = !this.params.forcedUpdateRes && (yield this.isProtocolV2BootResourceCurrent(file));
|
|
52017
|
+
if (isCurrent) {
|
|
52018
|
+
Log$6.log(`[FirmwareUpdateV4] boot resource unchanged, skipping ${file.devicePath}`);
|
|
52019
|
+
}
|
|
52020
|
+
else {
|
|
52021
|
+
Log$6.log(`[FirmwareUpdateV4] downloading boot resource ${file.devicePath}`);
|
|
52022
|
+
const { binary } = yield getSysResourceBinary(file.url);
|
|
52023
|
+
if (!isProtocolV2ResourceFileValid(binary, file)) {
|
|
52024
|
+
throw new Error(`Boot resource file verification failed: ${file.devicePath}`);
|
|
52025
|
+
}
|
|
52026
|
+
files.push({
|
|
52027
|
+
name: (_e = (_d = file.name) !== null && _d !== void 0 ? _d : file.devicePath.split('/').pop()) !== null && _e !== void 0 ? _e : file.devicePath,
|
|
52028
|
+
binary,
|
|
52029
|
+
devicePath: file.devicePath,
|
|
52030
|
+
});
|
|
52031
|
+
}
|
|
52032
|
+
}
|
|
52033
|
+
return files;
|
|
52034
|
+
});
|
|
52035
|
+
}
|
|
52036
|
+
isProtocolV2BootResourceCurrent(file) {
|
|
52037
|
+
var _a, _b, _c, _d;
|
|
52038
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52039
|
+
try {
|
|
52040
|
+
const commands = this.device.getCommands();
|
|
52041
|
+
const pathInfo = yield commands.typedCall('FilesystemPathInfoQuery', 'FilesystemPathInfo', { path: file.devicePath }, { timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT });
|
|
52042
|
+
const size = toProtocolV2FiniteNumber((_a = pathInfo.message) === null || _a === void 0 ? void 0 : _a.size);
|
|
52043
|
+
if (!((_b = pathInfo.message) === null || _b === void 0 ? void 0 : _b.exist) ||
|
|
52044
|
+
((_c = pathInfo.message) === null || _c === void 0 ? void 0 : _c.directory) ||
|
|
52045
|
+
!Number.isSafeInteger(size) ||
|
|
52046
|
+
size !== file.size) {
|
|
52047
|
+
return false;
|
|
52048
|
+
}
|
|
52049
|
+
const digest = sha256.sha256.create();
|
|
52050
|
+
const chunkSize = this.getProtocolV2FirmwareChunkSize('write');
|
|
52051
|
+
let offset = 0;
|
|
52052
|
+
while (offset < file.size) {
|
|
52053
|
+
const response = yield commands.typedCall('FilesystemFileRead', 'FilesystemFile', {
|
|
52054
|
+
file: { path: file.devicePath, offset, total_size: 0 },
|
|
52055
|
+
chunk_len: Math.min(chunkSize, file.size - offset),
|
|
52056
|
+
}, { timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT });
|
|
52057
|
+
const data = toProtocolV2Bytes((_d = response.message) === null || _d === void 0 ? void 0 : _d.data);
|
|
52058
|
+
if (data.byteLength === 0)
|
|
52059
|
+
return false;
|
|
52060
|
+
const consumed = data.subarray(0, Math.min(data.byteLength, file.size - offset));
|
|
52061
|
+
digest.update(consumed);
|
|
52062
|
+
offset += consumed.byteLength;
|
|
52063
|
+
}
|
|
52064
|
+
return bytesToHex(digest.digest()) === normalizeProtocolV2Hex(file.fileHash);
|
|
52065
|
+
}
|
|
52066
|
+
catch (error) {
|
|
52067
|
+
Log$6.debug(`[FirmwareUpdateV4] unable to compare boot resource ${file.devicePath}; scheduling rewrite`, error);
|
|
52068
|
+
return false;
|
|
52069
|
+
}
|
|
52070
|
+
});
|
|
52071
|
+
}
|
|
52072
|
+
mergeProtocolV2ResourceBundles(...groups) {
|
|
52073
|
+
const merged = groups.flatMap(group => group !== null && group !== void 0 ? group : []);
|
|
52074
|
+
if (!merged.length)
|
|
52075
|
+
return undefined;
|
|
52076
|
+
const seenPaths = new Set();
|
|
52077
|
+
for (const bundle of merged) {
|
|
52078
|
+
if (seenPaths.has(bundle.devicePath)) {
|
|
52079
|
+
throw new Error(`Duplicate Protocol V2 resource devicePath: ${bundle.devicePath}`);
|
|
52080
|
+
}
|
|
52081
|
+
seenPaths.add(bundle.devicePath);
|
|
52082
|
+
}
|
|
52083
|
+
return merged;
|
|
52084
|
+
}
|
|
52085
|
+
prepareExplicitProtocolV2ResourceFiles() {
|
|
52086
|
+
var _a;
|
|
52087
|
+
const files = (_a = this.params.resourceFiles) !== null && _a !== void 0 ? _a : [];
|
|
52088
|
+
if (!(files === null || files === void 0 ? void 0 : files.length))
|
|
52089
|
+
return undefined;
|
|
52090
|
+
const prepared = files.map((file, index) => {
|
|
52091
|
+
var _a;
|
|
52092
|
+
const devicePath = validateProtocolV2FilesystemPath(file.devicePath, `resourceFiles[${index}].devicePath`);
|
|
52093
|
+
const descriptor = file;
|
|
52094
|
+
if (descriptor.size !== undefined && descriptor.size !== file.binary.byteLength) {
|
|
52095
|
+
throw new Error(`resourceFiles[${index}] size mismatch`);
|
|
52096
|
+
}
|
|
52097
|
+
if (descriptor.fileHash &&
|
|
52098
|
+
!isProtocolV2ResourceFileValid(file.binary, {
|
|
52099
|
+
size: file.binary.byteLength,
|
|
52100
|
+
fileHash: descriptor.fileHash,
|
|
52101
|
+
})) {
|
|
52102
|
+
throw new Error(`resourceFiles[${index}] SHA-256 mismatch`);
|
|
52103
|
+
}
|
|
52104
|
+
return {
|
|
52105
|
+
name: (_a = devicePath.split('/').pop()) !== null && _a !== void 0 ? _a : devicePath,
|
|
52106
|
+
binary: file.binary,
|
|
52107
|
+
devicePath,
|
|
52108
|
+
};
|
|
52109
|
+
});
|
|
52110
|
+
if (new Set(prepared.map(file => file.devicePath)).size !== prepared.length) {
|
|
52111
|
+
throw new Error('resourceFiles contain duplicate devicePath values');
|
|
52112
|
+
}
|
|
52113
|
+
return prepared;
|
|
52114
|
+
}
|
|
52115
|
+
prepareProtocolV2ResourceBundles() {
|
|
52116
|
+
var _a;
|
|
52117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52118
|
+
if (!((_a = this.params.targetsToUpdate) === null || _a === void 0 ? void 0 : _a.includes('resource'))) {
|
|
52119
|
+
return undefined;
|
|
52120
|
+
}
|
|
52121
|
+
const resources = DataManager.getProtocolV2Resources(this.getProtocolV2DeviceType());
|
|
52122
|
+
if (!(resources === null || resources === void 0 ? void 0 : resources.length)) {
|
|
52123
|
+
throw new Error('Missing Pro2 stable resource configuration');
|
|
52124
|
+
}
|
|
52125
|
+
const inventory = this.params.forcedUpdateRes
|
|
52126
|
+
? undefined
|
|
52127
|
+
: yield readProtocolV2ResourceInventory({
|
|
52128
|
+
commands: this.device.getCommands(),
|
|
52129
|
+
resources,
|
|
52130
|
+
chunkSize: this.getProtocolV2FirmwareChunkSize('write'),
|
|
52131
|
+
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
52132
|
+
});
|
|
52133
|
+
const plan = buildProtocolV2ResourceUpdatePlan({
|
|
52134
|
+
resources,
|
|
52135
|
+
inventory,
|
|
52136
|
+
mode: 'bootloader-recovery',
|
|
52137
|
+
forced: this.params.forcedUpdateRes,
|
|
52138
|
+
});
|
|
52139
|
+
Log$6.log(`[FirmwareUpdateV4] Protocol V2 resource plan mode=bootloader-recovery status=${plan.status} count=${plan.resources.length}`);
|
|
52140
|
+
const bundles = [];
|
|
52141
|
+
for (const resource of plan.resources) {
|
|
52142
|
+
bundles.push(yield this.downloadProtocolV2Resource(resource));
|
|
52143
|
+
}
|
|
52144
|
+
return bundles;
|
|
52145
|
+
});
|
|
52146
|
+
}
|
|
52147
|
+
downloadProtocolV2Resource(resource) {
|
|
52148
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52149
|
+
Log$6.log(`[FirmwareUpdateV4] downloading Pro2 resource ${resource.type}`);
|
|
52150
|
+
const { binary } = yield getSysResourceBinary(resource.url);
|
|
52151
|
+
if (!isProtocolV2ResourceFileValid(binary, resource)) {
|
|
52152
|
+
throw new Error(`Pro2 resource file verification failed: ${resource.type}`);
|
|
52153
|
+
}
|
|
52154
|
+
return {
|
|
52155
|
+
name: `${resource.type}.okpkg`,
|
|
52156
|
+
binary,
|
|
52157
|
+
devicePath: PROTOCOL_V2_RESOURCE_DEVICE_PATHS[resource.type],
|
|
52158
|
+
};
|
|
52159
|
+
});
|
|
52160
|
+
}
|
|
52611
52161
|
getProtocolV2ResourceFilePath(path) {
|
|
52612
52162
|
if (path.startsWith('vol'))
|
|
52613
52163
|
return path;
|
|
@@ -52615,7 +52165,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52615
52165
|
return `vol0:${path}`;
|
|
52616
52166
|
return `vol0:/${path}`;
|
|
52617
52167
|
}
|
|
52618
|
-
readProtocolV2DeviceFileHeader(path
|
|
52168
|
+
readProtocolV2DeviceFileHeader(path) {
|
|
52619
52169
|
var _a, _b, _c, _d;
|
|
52620
52170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52621
52171
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
@@ -52627,8 +52177,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52627
52177
|
if (!((_b = pathInfoRes.message) === null || _b === void 0 ? void 0 : _b.exist) ||
|
|
52628
52178
|
((_c = pathInfoRes.message) === null || _c === void 0 ? void 0 : _c.directory) ||
|
|
52629
52179
|
fileSize === undefined ||
|
|
52630
|
-
fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE
|
|
52631
|
-
(expectedSize !== undefined && fileSize !== expectedSize)) {
|
|
52180
|
+
fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE) {
|
|
52632
52181
|
return null;
|
|
52633
52182
|
}
|
|
52634
52183
|
const chunkSize = this.getProtocolV2FirmwareChunkSize('read');
|
|
@@ -52665,10 +52214,10 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52665
52214
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52666
52215
|
if ((_a = this.params) === null || _a === void 0 ? void 0 : _a.forcedUpdateRes)
|
|
52667
52216
|
return false;
|
|
52668
|
-
if (!bundle.
|
|
52217
|
+
if (!bundle.version && !bundle.payloadHash)
|
|
52669
52218
|
return false;
|
|
52670
52219
|
try {
|
|
52671
|
-
const header = yield this.readProtocolV2DeviceFileHeader(bundle.devicePath
|
|
52220
|
+
const header = yield this.readProtocolV2DeviceFileHeader(bundle.devicePath);
|
|
52672
52221
|
if (!header)
|
|
52673
52222
|
return false;
|
|
52674
52223
|
if (bundle.version) {
|
|
@@ -52676,12 +52225,16 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52676
52225
|
if (cmp === undefined || cmp !== 0)
|
|
52677
52226
|
return false;
|
|
52678
52227
|
}
|
|
52679
|
-
|
|
52680
|
-
|
|
52681
|
-
|
|
52682
|
-
|
|
52683
|
-
|
|
52684
|
-
|
|
52228
|
+
if (bundle.payloadHash) {
|
|
52229
|
+
const expected = normalizeProtocolV2Hex(bundle.payloadHash);
|
|
52230
|
+
if (expected && header.payloadHash !== expected)
|
|
52231
|
+
return false;
|
|
52232
|
+
}
|
|
52233
|
+
if (bundle.headerHash) {
|
|
52234
|
+
const expected = normalizeProtocolV2Hex(bundle.headerHash);
|
|
52235
|
+
if (expected && header.headerHash !== expected)
|
|
52236
|
+
return false;
|
|
52237
|
+
}
|
|
52685
52238
|
return true;
|
|
52686
52239
|
}
|
|
52687
52240
|
catch (error) {
|
|
@@ -52796,6 +52349,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52796
52349
|
}
|
|
52797
52350
|
buildProtocolV2ExecutionPhases({ installSources, resourceSources, }) {
|
|
52798
52351
|
const phases = [];
|
|
52352
|
+
if (resourceSources.length > 0) {
|
|
52353
|
+
phases.push({
|
|
52354
|
+
kind: 'resource-sync',
|
|
52355
|
+
installSources: [],
|
|
52356
|
+
resourceSources,
|
|
52357
|
+
});
|
|
52358
|
+
}
|
|
52799
52359
|
const bootloaderSources = installSources.filter(source => source.kind === 'bootloader');
|
|
52800
52360
|
if (bootloaderSources.length > 0) {
|
|
52801
52361
|
phases.push({
|
|
@@ -52808,13 +52368,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52808
52368
|
resourceSources: [],
|
|
52809
52369
|
});
|
|
52810
52370
|
}
|
|
52811
|
-
if (resourceSources.length > 0) {
|
|
52812
|
-
phases.push({
|
|
52813
|
-
kind: 'resource-sync',
|
|
52814
|
-
installSources: [],
|
|
52815
|
-
resourceSources,
|
|
52816
|
-
});
|
|
52817
|
-
}
|
|
52818
52371
|
const componentSources = installSources.filter(source => source.kind !== 'bootloader');
|
|
52819
52372
|
if (componentSources.length > 0) {
|
|
52820
52373
|
phases.push({
|
|
@@ -52865,7 +52418,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52865
52418
|
});
|
|
52866
52419
|
});
|
|
52867
52420
|
}
|
|
52868
|
-
executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, }) {
|
|
52421
|
+
executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, resourceBundles, }) {
|
|
52869
52422
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52870
52423
|
const memoryInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
|
|
52871
52424
|
fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
|
|
@@ -52880,9 +52433,16 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52880
52433
|
kind: item.kind,
|
|
52881
52434
|
});
|
|
52882
52435
|
})));
|
|
52436
|
+
const resourceSources = yield Promise.all((resourceBundles !== null && resourceBundles !== void 0 ? resourceBundles : []).map((bundle) => __awaiter(this, void 0, void 0, function* () {
|
|
52437
|
+
return ({
|
|
52438
|
+
name: bundle.name,
|
|
52439
|
+
source: yield this.openProtocolV2MemorySource(bundle.binary),
|
|
52440
|
+
devicePath: bundle.devicePath,
|
|
52441
|
+
});
|
|
52442
|
+
})));
|
|
52883
52443
|
return yield this.executeProtocolV2Phases({
|
|
52884
52444
|
installSources,
|
|
52885
|
-
resourceSources
|
|
52445
|
+
resourceSources,
|
|
52886
52446
|
});
|
|
52887
52447
|
}
|
|
52888
52448
|
finally {
|
|
@@ -52906,14 +52466,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52906
52466
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
|
|
52907
52467
|
let processedSize = 0;
|
|
52908
52468
|
for (const resource of resourcesToSync) {
|
|
52909
|
-
const writePath = resolveProtocolV2ResourceWritePath(resource.devicePath);
|
|
52910
52469
|
processedSize = yield this.protocolV2SourceUpdateProcess({
|
|
52911
52470
|
source: resource.source,
|
|
52912
|
-
filePath:
|
|
52471
|
+
filePath: resource.devicePath,
|
|
52913
52472
|
processedSize,
|
|
52914
52473
|
totalSize,
|
|
52915
52474
|
});
|
|
52916
|
-
yield this.verifyProtocolV2StagedFile(
|
|
52475
|
+
yield this.verifyProtocolV2StagedFile(resource.devicePath, resource.source.size);
|
|
52917
52476
|
}
|
|
52918
52477
|
const stagedInstallTargets = [];
|
|
52919
52478
|
for (const item of installSources) {
|
|
@@ -53903,7 +53462,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
53903
53462
|
}
|
|
53904
53463
|
|
|
53905
53464
|
const FILESYSTEM_PATH_INFO_QUERY_MESSAGE_TYPE = 60802;
|
|
53906
|
-
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE
|
|
53465
|
+
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
53907
53466
|
const FILESYSTEM_DIR_LIST_MESSAGE_TYPE = 60808;
|
|
53908
53467
|
const NFT_UPDATE_MESSAGE_TYPE = 61500;
|
|
53909
53468
|
class DeviceUploadNft extends BaseMethod {
|
|
@@ -53932,7 +53491,7 @@ class DeviceUploadNft extends BaseMethod {
|
|
|
53932
53491
|
assertCapabilities() {
|
|
53933
53492
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53934
53493
|
const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
|
|
53935
|
-
const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE
|
|
53494
|
+
const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE);
|
|
53936
53495
|
const hasPathInfo = supportsProtocolV2Message(protocolInfo, FILESYSTEM_PATH_INFO_QUERY_MESSAGE_TYPE);
|
|
53937
53496
|
const hasDirList = supportsProtocolV2Message(protocolInfo, FILESYSTEM_DIR_LIST_MESSAGE_TYPE);
|
|
53938
53497
|
const hasNftUpdate = supportsProtocolV2Message(protocolInfo, NFT_UPDATE_MESSAGE_TYPE);
|
|
@@ -54067,8 +53626,6 @@ class FileWrite extends BaseMethod {
|
|
|
54067
53626
|
|
|
54068
53627
|
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
|
|
54069
53628
|
const PORTFOLIO_CHUNK_SIZE = 2048;
|
|
54070
|
-
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
54071
|
-
const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
|
|
54072
53629
|
class UploadPortfolio extends FileWrite {
|
|
54073
53630
|
init() {
|
|
54074
53631
|
const { packageBytes, timeoutMs } = this.payload;
|
|
@@ -54082,12 +53639,6 @@ class UploadPortfolio extends FileWrite {
|
|
|
54082
53639
|
run: { get: () => super.run }
|
|
54083
53640
|
});
|
|
54084
53641
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54085
|
-
const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
|
|
54086
|
-
const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE);
|
|
54087
|
-
const hasPortfolioUpdate = supportsProtocolV2Message(protocolInfo, PORTFOLIO_UPDATE_MESSAGE_TYPE);
|
|
54088
|
-
if (!hasFileWrite || !hasPortfolioUpdate) {
|
|
54089
|
-
throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
|
|
54090
|
-
}
|
|
54091
53642
|
const stagedFile = yield _super.run.call(this);
|
|
54092
53643
|
this.throwIfAborted();
|
|
54093
53644
|
yield this.device.commands.typedCall('PortfolioUpdate', 'Success', {});
|
|
@@ -65629,14 +65180,11 @@ exports.normalizeSafetyCheckLevel = normalizeSafetyCheckLevel;
|
|
|
65629
65180
|
exports.normalizeVersionArray = normalizeVersionArray;
|
|
65630
65181
|
exports.parseConnectSettings = parseConnectSettings;
|
|
65631
65182
|
exports.parseMessage = parseMessage;
|
|
65632
|
-
exports.parseProtocolV2ResourceManifest = parseProtocolV2ResourceManifest;
|
|
65633
65183
|
exports.patchFeatures = patchFeatures;
|
|
65634
65184
|
exports.preloadSessionCache = preloadSessionCache;
|
|
65635
|
-
exports.prepareFirmwareUpdateV4MemoryHost = prepareFirmwareUpdateV4MemoryHost;
|
|
65636
65185
|
exports.projectDeviceStateFeatures = projectFeatures;
|
|
65637
65186
|
exports.registerFirmwareUpdateHostBinding = registerFirmwareUpdateHostBinding;
|
|
65638
65187
|
exports.safeThrowError = safeThrowError;
|
|
65639
|
-
exports.selectProtocolV2ResourceManifestFiles = selectProtocolV2ResourceManifestFiles;
|
|
65640
65188
|
exports.setLoggerPostMessage = setLoggerPostMessage;
|
|
65641
65189
|
exports.supportInputPinOnSoftware = supportInputPinOnSoftware;
|
|
65642
65190
|
exports.switchTransport = switchTransport;
|