@onekeyfe/hd-core 1.2.0-alpha.96 → 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 -1313
- 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 +7 -29
- 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 -469
- 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() {
|
|
@@ -50593,27 +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
|
-
payload.bleVersion,
|
|
50601
|
-
payload.bleBinary,
|
|
50602
|
-
payload.firmwareVersion,
|
|
50603
|
-
payload.firmwareBinary,
|
|
50604
|
-
payload.resourceBinary,
|
|
50605
|
-
payload.bootloaderVersion,
|
|
50606
|
-
payload.bootloaderBinary,
|
|
50607
|
-
].some(input => input !== undefined);
|
|
50608
|
-
if (preparedPlan && hasLegacyInputs) {
|
|
50609
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Prepared firmware plans cannot be combined with legacy firmware inputs');
|
|
50610
|
-
}
|
|
50611
|
-
const artifactReader = preparedPlan
|
|
50612
|
-
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest).artifactReader
|
|
50613
|
-
: payload.artifactReader;
|
|
50614
|
-
if (preparedPlan) {
|
|
50426
|
+
if (hostBinding) {
|
|
50615
50427
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
50616
|
-
preparedPlan,
|
|
50428
|
+
preparedPlan: payload.preparedPlan,
|
|
50617
50429
|
executor: 'v3',
|
|
50618
50430
|
platform: payload.platform,
|
|
50619
50431
|
scopeTargets: ['bootloader', 'firmware', 'resource', 'ble'],
|
|
@@ -50651,7 +50463,7 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
50651
50463
|
});
|
|
50652
50464
|
}
|
|
50653
50465
|
this.params = {
|
|
50654
|
-
preparedPlan,
|
|
50466
|
+
preparedPlan: payload.preparedPlan,
|
|
50655
50467
|
bleBinary: payload.bleBinary,
|
|
50656
50468
|
firmwareBinary: payload.firmwareBinary,
|
|
50657
50469
|
forcedUpdateRes: payload.forcedUpdateRes,
|
|
@@ -50660,9 +50472,9 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
|
|
|
50660
50472
|
bootloaderBinary: payload.bootloaderBinary,
|
|
50661
50473
|
firmwareVersion: payload.firmwareVersion,
|
|
50662
50474
|
resourceBinary: payload.resourceBinary,
|
|
50663
|
-
firmwareType:
|
|
50475
|
+
firmwareType: payload.firmwareType,
|
|
50664
50476
|
platform: payload.platform,
|
|
50665
|
-
artifactReader,
|
|
50477
|
+
artifactReader: (_f = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _f !== void 0 ? _f : payload.artifactReader,
|
|
50666
50478
|
artifacts: payload.artifacts,
|
|
50667
50479
|
};
|
|
50668
50480
|
}
|
|
@@ -51278,88 +51090,6 @@ const INSTALLABLE_FIRMWARE_TARGET_IDS = new Set([
|
|
|
51278
51090
|
]);
|
|
51279
51091
|
new Map(Object.entries(ProtocolV2FirmwareTargetType).flatMap(([key, value]) => INSTALLABLE_FIRMWARE_TARGET_IDS.has(value) ? [[key, value]] : []));
|
|
51280
51092
|
|
|
51281
|
-
let memoryHostSequence = 0;
|
|
51282
|
-
const createReference = (binary, prefix) => {
|
|
51283
|
-
const digest = utils.bytesToHex(sha256.sha256(new Uint8Array(binary)));
|
|
51284
|
-
return {
|
|
51285
|
-
artifactRef: `fwmem:${prefix}:${digest.slice(0, 32)}`,
|
|
51286
|
-
size: binary.byteLength,
|
|
51287
|
-
sha256: digest,
|
|
51288
|
-
};
|
|
51289
|
-
};
|
|
51290
|
-
function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }) {
|
|
51291
|
-
if (plan.executor !== 'v4') {
|
|
51292
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory host only supports V4 plans');
|
|
51293
|
-
}
|
|
51294
|
-
memoryHostSequence += 1;
|
|
51295
|
-
const hostId = `${Date.now()}:${memoryHostSequence}`;
|
|
51296
|
-
const binaries = new Map();
|
|
51297
|
-
const inputs = artifacts.map((input, artifactIndex) => {
|
|
51298
|
-
var _a;
|
|
51299
|
-
const artifactBinary = new Uint8Array(input.binary).slice();
|
|
51300
|
-
const artifact = createReference(artifactBinary.buffer, `${hostId}:artifact:${artifactIndex}`);
|
|
51301
|
-
binaries.set(artifact.artifactRef, artifactBinary);
|
|
51302
|
-
const materializedEntries = (_a = input.materializedEntries) === null || _a === void 0 ? void 0 : _a.map((entry, entryIndex) => {
|
|
51303
|
-
const entryBinary = new Uint8Array(entry.binary).slice();
|
|
51304
|
-
const entryArtifact = createReference(entryBinary.buffer, `${hostId}:entry:${artifactIndex}:${entryIndex}`);
|
|
51305
|
-
binaries.set(entryArtifact.artifactRef, entryBinary);
|
|
51306
|
-
return {
|
|
51307
|
-
entryName: entry.entryName,
|
|
51308
|
-
artifact: entryArtifact,
|
|
51309
|
-
};
|
|
51310
|
-
});
|
|
51311
|
-
return Object.assign({ artifactId: input.artifactId, artifact }, ((materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length) ? { materializedEntries } : {}));
|
|
51312
|
-
});
|
|
51313
|
-
const preparedPlan = sdk.prepareFirmwareUpdatePlan({
|
|
51314
|
-
plan,
|
|
51315
|
-
leaseRef: `fwmemlease:${hostId}`,
|
|
51316
|
-
artifacts: inputs,
|
|
51317
|
-
});
|
|
51318
|
-
const readers = new Map();
|
|
51319
|
-
let readerSequence = 0;
|
|
51320
|
-
const artifactReader = {
|
|
51321
|
-
open({ artifactRef }) {
|
|
51322
|
-
const binary = binaries.get(artifactRef);
|
|
51323
|
-
if (!binary) {
|
|
51324
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory artifact is unavailable');
|
|
51325
|
-
}
|
|
51326
|
-
readerSequence += 1;
|
|
51327
|
-
const readerId = `fwmemreader:${hostId}:${readerSequence}`;
|
|
51328
|
-
readers.set(readerId, binary);
|
|
51329
|
-
return Promise.resolve({ readerId, size: binary.byteLength });
|
|
51330
|
-
},
|
|
51331
|
-
read({ readerId, offset, length }) {
|
|
51332
|
-
const binary = readers.get(readerId);
|
|
51333
|
-
if (!binary || offset < 0 || length <= 0 || offset + length > binary.byteLength) {
|
|
51334
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory artifact read is invalid');
|
|
51335
|
-
}
|
|
51336
|
-
const data = binary.slice(offset, offset + length).buffer;
|
|
51337
|
-
return Promise.resolve({
|
|
51338
|
-
data,
|
|
51339
|
-
bytesRead: data.byteLength,
|
|
51340
|
-
eof: offset + length === binary.byteLength,
|
|
51341
|
-
});
|
|
51342
|
-
},
|
|
51343
|
-
close({ readerId }) {
|
|
51344
|
-
readers.delete(readerId);
|
|
51345
|
-
return Promise.resolve();
|
|
51346
|
-
},
|
|
51347
|
-
};
|
|
51348
|
-
const hostBindingGeneration = sdk.registerFirmwareUpdateHostBinding({
|
|
51349
|
-
artifactReader,
|
|
51350
|
-
preparedPlanDigest: preparedPlan.preparedPlanDigest,
|
|
51351
|
-
});
|
|
51352
|
-
return {
|
|
51353
|
-
preparedPlan,
|
|
51354
|
-
hostBindingGeneration,
|
|
51355
|
-
release: () => {
|
|
51356
|
-
sdk.unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
|
|
51357
|
-
readers.clear();
|
|
51358
|
-
binaries.clear();
|
|
51359
|
-
},
|
|
51360
|
-
};
|
|
51361
|
-
}
|
|
51362
|
-
|
|
51363
51093
|
const Log$6 = getLogger(exports.LoggerNames.Method);
|
|
51364
51094
|
const SESSION_ERROR$1 = 'session not found';
|
|
51365
51095
|
const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 90 * 1000;
|
|
@@ -51386,24 +51116,7 @@ const PROTOCOL_V2_OKPP_HEADER_SIZE = 0x52a0;
|
|
|
51386
51116
|
const PROTOCOL_V2_OKPP_PAYLOAD_HASH_OFFSET = 0x200;
|
|
51387
51117
|
const PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET = 0x240;
|
|
51388
51118
|
const PROTOCOL_V2_OKPP_HASH_SIZE = 64;
|
|
51389
|
-
const PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES = 1024 * 1024;
|
|
51390
|
-
const PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT = 512;
|
|
51391
|
-
const PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES = 256 * 1024 * 1024;
|
|
51392
51119
|
const PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS = new Set(['se03', 'se04']);
|
|
51393
|
-
const getProtocolV2ZipEntrySizes = (entry) => {
|
|
51394
|
-
var _a;
|
|
51395
|
-
const { compressedSize, uncompressedSize } = (_a = entry._data) !== null && _a !== void 0 ? _a : {};
|
|
51396
|
-
if (!Number.isSafeInteger(compressedSize) ||
|
|
51397
|
-
Number(compressedSize) < 0 ||
|
|
51398
|
-
!Number.isSafeInteger(uncompressedSize) ||
|
|
51399
|
-
Number(uncompressedSize) <= 0) {
|
|
51400
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP entry size is invalid: ${entry.name}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51401
|
-
}
|
|
51402
|
-
return {
|
|
51403
|
-
compressedSize: Number(compressedSize),
|
|
51404
|
-
uncompressedSize: Number(uncompressedSize),
|
|
51405
|
-
};
|
|
51406
|
-
};
|
|
51407
51120
|
function assertProtocolV2FirmwareTargetsSupported(deviceType, params) {
|
|
51408
51121
|
var _a;
|
|
51409
51122
|
const unsupportedTargets = new Set(((_a = params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter(target => PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS.has(target)));
|
|
@@ -51474,14 +51187,6 @@ const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS = {
|
|
|
51474
51187
|
},
|
|
51475
51188
|
};
|
|
51476
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}`));
|
|
51477
|
-
const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH = 'vol0:/loaders/bootloader/boot_resource.okpkg';
|
|
51478
|
-
const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH = `${PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH}.staging`;
|
|
51479
|
-
const resolveProtocolV2ResourceWritePath = (devicePath) => {
|
|
51480
|
-
const normalizedPath = devicePath.replace(/^vol0:(?!\/)/i, 'vol0:/').toLowerCase();
|
|
51481
|
-
return normalizedPath === PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH
|
|
51482
|
-
? PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH
|
|
51483
|
-
: devicePath;
|
|
51484
|
-
};
|
|
51485
51190
|
const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map([
|
|
51486
51191
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, 'boot'],
|
|
51487
51192
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, 'app_v1'],
|
|
@@ -51492,10 +51197,6 @@ const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map([
|
|
|
51492
51197
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03, 'se03'],
|
|
51493
51198
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, 'se04'],
|
|
51494
51199
|
]);
|
|
51495
|
-
const PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET = new Map(Object.values(PROTOCOL_V2_REMOTE_COMPONENT_TARGETS).map(target => [
|
|
51496
|
-
PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId),
|
|
51497
|
-
target,
|
|
51498
|
-
]));
|
|
51499
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.';
|
|
51500
51201
|
const PROTOCOL_V2_TARGET_ID_BY_DECODED_NAME = new Map(Object.entries(ProtocolV2FirmwareTargetType).map(([key, value]) => [key, value]));
|
|
51501
51202
|
const PROTOCOL_V2_TARGET_STATUS_BY_DECODED_NAME = new Map([
|
|
@@ -51660,7 +51361,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51660
51361
|
return ['V2'];
|
|
51661
51362
|
}
|
|
51662
51363
|
init() {
|
|
51663
|
-
var _a, _b;
|
|
51364
|
+
var _a, _b, _c;
|
|
51664
51365
|
this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
|
|
51665
51366
|
this.requireDeviceMode = [];
|
|
51666
51367
|
this.unlockPolicy = 'unlock-before-run';
|
|
@@ -51691,85 +51392,54 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51691
51392
|
{ name: 'se02Binary', type: 'buffer' },
|
|
51692
51393
|
{ name: 'se03Binary', type: 'buffer' },
|
|
51693
51394
|
{ name: 'se04Binary', type: 'buffer' },
|
|
51694
|
-
{ name: 'resourceArchiveBinary', type: 'buffer' },
|
|
51695
51395
|
{ name: 'firmwareType', type: 'string' },
|
|
51696
51396
|
{ name: 'targetsToUpdate', type: 'array', allowEmpty: true },
|
|
51697
51397
|
{ name: 'platform', type: 'string' },
|
|
51698
51398
|
{ name: 'expectedDeviceId', type: 'string' },
|
|
51399
|
+
{ name: 'resourceFiles', type: 'array', allowEmpty: true },
|
|
51699
51400
|
]);
|
|
51700
51401
|
if (payload.expectedDeviceId !== undefined &&
|
|
51701
51402
|
(payload.expectedDeviceId.length === 0 || payload.expectedDeviceId.length > 160)) {
|
|
51702
51403
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 expected device identity is invalid');
|
|
51703
51404
|
}
|
|
51704
|
-
const
|
|
51705
|
-
?
|
|
51405
|
+
const hostBinding = payload.preparedPlan || payload.componentArtifacts || payload.resourceBundleArtifacts
|
|
51406
|
+
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
|
|
51706
51407
|
: undefined;
|
|
51707
|
-
|
|
51708
|
-
payload.bootloaderBinary,
|
|
51709
|
-
payload.romloaderBinary,
|
|
51710
|
-
payload.applicationP1Binary,
|
|
51711
|
-
payload.applicationP2Binary,
|
|
51712
|
-
payload.coprocessorBinary,
|
|
51713
|
-
payload.se01Binary,
|
|
51714
|
-
payload.se02Binary,
|
|
51715
|
-
payload.se03Binary,
|
|
51716
|
-
payload.se04Binary,
|
|
51717
|
-
payload.resourceArchiveBinary,
|
|
51718
|
-
].some(Boolean);
|
|
51719
|
-
if (preparedPlan && hasLocalArtifacts) {
|
|
51720
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Prepared firmware plans cannot be combined with legacy or local firmware inputs');
|
|
51721
|
-
}
|
|
51722
|
-
let { artifactReader } = payload;
|
|
51723
|
-
if (preparedPlan) {
|
|
51724
|
-
artifactReader = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan.preparedPlanDigest).artifactReader;
|
|
51725
|
-
}
|
|
51726
|
-
else if (payload.hostBindingGeneration !== undefined) {
|
|
51727
|
-
artifactReader = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration).artifactReader;
|
|
51728
|
-
}
|
|
51729
|
-
if (preparedPlan) {
|
|
51408
|
+
if (hostBinding) {
|
|
51730
51409
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
51731
|
-
preparedPlan,
|
|
51410
|
+
preparedPlan: payload.preparedPlan,
|
|
51732
51411
|
executor: 'v4',
|
|
51733
51412
|
platform: payload.platform,
|
|
51734
|
-
scopeTargets: [
|
|
51735
|
-
|
|
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
|
+
],
|
|
51736
51439
|
});
|
|
51737
|
-
if (payload.componentArtifacts) {
|
|
51738
|
-
const componentBindings = Object.entries(payload.componentArtifacts).flatMap(([target, artifact]) => artifact
|
|
51739
|
-
? [
|
|
51740
|
-
{
|
|
51741
|
-
target: target,
|
|
51742
|
-
artifact: artifact,
|
|
51743
|
-
},
|
|
51744
|
-
]
|
|
51745
|
-
: []);
|
|
51746
|
-
assertFirmwareUpdatePreparedPlanBinding({
|
|
51747
|
-
preparedPlan,
|
|
51748
|
-
executor: 'v4',
|
|
51749
|
-
platform: payload.platform,
|
|
51750
|
-
scopeTargets: componentBindings.map(binding => binding.target),
|
|
51751
|
-
bindings: componentBindings,
|
|
51752
|
-
});
|
|
51753
|
-
}
|
|
51754
|
-
}
|
|
51755
|
-
const preparedExpectedTargetVersions = preparedPlan === null || preparedPlan === void 0 ? void 0 : preparedPlan.artifacts.reduce((result, artifact) => {
|
|
51756
|
-
if (artifact.role === 'component' &&
|
|
51757
|
-
artifact.target !== 'resource' &&
|
|
51758
|
-
artifact.targetVersion &&
|
|
51759
|
-
PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.has(artifact.target)) {
|
|
51760
|
-
result[artifact.target] = artifact.targetVersion;
|
|
51761
|
-
}
|
|
51762
|
-
return result;
|
|
51763
|
-
}, {});
|
|
51764
|
-
const localTargetsToUpdate = (_a = payload.targetsToUpdate) === null || _a === void 0 ? void 0 : _a.map((target) => target === 'boot_resources' ? 'resource' : target);
|
|
51765
|
-
if (payload.resourceArchiveBinary &&
|
|
51766
|
-
localTargetsToUpdate &&
|
|
51767
|
-
!localTargetsToUpdate.includes('resource')) {
|
|
51768
|
-
localTargetsToUpdate.push('resource');
|
|
51769
51440
|
}
|
|
51770
|
-
const resolvedLocalTargetsToUpdate = localTargetsToUpdate !== null && localTargetsToUpdate !== void 0 ? localTargetsToUpdate : (payload.resourceArchiveBinary ? ['resource'] : undefined);
|
|
51771
51441
|
this.params = {
|
|
51772
|
-
preparedPlan,
|
|
51442
|
+
preparedPlan: payload.preparedPlan,
|
|
51773
51443
|
chunkSize: payload.chunkSize,
|
|
51774
51444
|
forcedUpdateRes: payload.forcedUpdateRes,
|
|
51775
51445
|
bootloaderBinary: payload.bootloaderBinary,
|
|
@@ -51781,18 +51451,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51781
51451
|
se02Binary: payload.se02Binary,
|
|
51782
51452
|
se03Binary: payload.se03Binary,
|
|
51783
51453
|
se04Binary: payload.se04Binary,
|
|
51784
|
-
|
|
51785
|
-
firmwareType:
|
|
51786
|
-
targetsToUpdate:
|
|
51787
|
-
|
|
51788
|
-
: resolvedLocalTargetsToUpdate,
|
|
51789
|
-
expectedTargetVersions: preparedPlan
|
|
51790
|
-
? preparedExpectedTargetVersions
|
|
51791
|
-
: payload.expectedTargetVersions,
|
|
51454
|
+
resourceFiles: payload.resourceFiles,
|
|
51455
|
+
firmwareType: payload.firmwareType,
|
|
51456
|
+
targetsToUpdate: payload.targetsToUpdate,
|
|
51457
|
+
expectedTargetVersions: payload.expectedTargetVersions,
|
|
51792
51458
|
platform: payload.platform,
|
|
51793
51459
|
expectedDeviceId: payload.expectedDeviceId,
|
|
51794
|
-
artifactReader,
|
|
51795
|
-
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,
|
|
51796
51463
|
};
|
|
51797
51464
|
}
|
|
51798
51465
|
getProtocolV2FirmwareChunkSize(direction, filePath) {
|
|
@@ -51823,7 +51490,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51823
51490
|
});
|
|
51824
51491
|
}
|
|
51825
51492
|
runProtocolV2() {
|
|
51826
|
-
var _a, _b, _c, _d, _e
|
|
51493
|
+
var _a, _b, _c, _d, _e;
|
|
51827
51494
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51828
51495
|
yield this.captureProtocolV2PhysicalIdentity();
|
|
51829
51496
|
const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
|
|
@@ -51835,80 +51502,85 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51835
51502
|
const deviceFirmwareType = getFirmwareType(deviceFeatures);
|
|
51836
51503
|
const firmwareType = (_a = this.params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
|
|
51837
51504
|
this.validateExpectedTargetVersions();
|
|
51838
|
-
if (
|
|
51839
|
-
this.params.
|
|
51840
|
-
((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource'))) {
|
|
51841
|
-
const localMemoryHost = yield this.prepareProtocolV2LocalMemoryHost({
|
|
51842
|
-
features: deviceFeatures,
|
|
51843
|
-
firmwareType,
|
|
51844
|
-
});
|
|
51845
|
-
try {
|
|
51846
|
-
return yield this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
|
|
51847
|
-
}
|
|
51848
|
-
finally {
|
|
51849
|
-
localMemoryHost.release();
|
|
51850
|
-
}
|
|
51851
|
-
}
|
|
51852
|
-
const hasPreparedComponentArtifacts = Object.values((_c = this.params.componentArtifacts) !== null && _c !== void 0 ? _c : {}).some(Boolean);
|
|
51853
|
-
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)) {
|
|
51854
51507
|
return this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
|
|
51855
51508
|
}
|
|
51856
|
-
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);
|
|
51857
51514
|
let fwBinaryMap = [];
|
|
51858
51515
|
let bootloaderBinary = null;
|
|
51859
51516
|
let installItems;
|
|
51517
|
+
let resourceBundles;
|
|
51860
51518
|
try {
|
|
51861
51519
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
51520
|
+
resourceBundles = this.prepareExplicitProtocolV2ResourceFiles();
|
|
51862
51521
|
fwBinaryMap = this.collectExplicitTargetBinaries();
|
|
51863
51522
|
bootloaderBinary = this.prepareBootloaderBinary();
|
|
51864
|
-
const
|
|
51865
|
-
|
|
51866
|
-
fwBinaryMap,
|
|
51867
|
-
});
|
|
51868
|
-
const missingFirmwareTargets = this.getMissingProtocolV2FirmwareTargets(explicitInstallItems);
|
|
51869
|
-
const needsRemoteFirmware = ((_e = this.params.targetsToUpdate) === null || _e === void 0 ? void 0 : _e.length)
|
|
51870
|
-
? missingFirmwareTargets.length > 0
|
|
51871
|
-
: explicitInstallItems.length === 0;
|
|
51872
|
-
if (wantsResources) {
|
|
51873
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive must be provided through a local or external PreparedPlan', {
|
|
51874
|
-
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51875
|
-
});
|
|
51876
|
-
}
|
|
51877
|
-
if (needsRemoteFirmware &&
|
|
51523
|
+
const needsRemoteFirmware = !this.hasExplicitProtocolV2Payload(fwBinaryMap);
|
|
51524
|
+
if ((needsRemoteFirmware || needsRemoteResources || needsRemoteBootResources) &&
|
|
51878
51525
|
(this.params.artifactReader ||
|
|
51879
51526
|
DataManager.getSettings('firmwareManifestMode') === 'external-only')) {
|
|
51880
51527
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware artifacts must be prepared by the external firmware host', {
|
|
51881
51528
|
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51882
51529
|
});
|
|
51883
51530
|
}
|
|
51884
|
-
if (needsRemoteFirmware) {
|
|
51885
|
-
yield DataManager.forceReloadData(
|
|
51531
|
+
if (needsRemoteFirmware || needsRemoteResources || needsRemoteBootResources) {
|
|
51532
|
+
yield DataManager.forceReloadData({
|
|
51533
|
+
requireResources: needsRemoteResources || needsRemoteBootResources,
|
|
51534
|
+
});
|
|
51886
51535
|
}
|
|
51887
51536
|
if (needsRemoteFirmware) {
|
|
51888
|
-
const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures
|
|
51537
|
+
const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures);
|
|
51889
51538
|
bootloaderBinary = remoteBinaries.bootloaderBinary;
|
|
51890
51539
|
fwBinaryMap = remoteBinaries.fwBinaryMap;
|
|
51891
51540
|
installItems = remoteBinaries.installItems;
|
|
51892
51541
|
}
|
|
51893
|
-
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
|
+
}
|
|
51894
51549
|
}
|
|
51895
51550
|
catch (err) {
|
|
51896
|
-
if (typeof err === 'object' &&
|
|
51897
|
-
err !== null &&
|
|
51898
|
-
'params' in err &&
|
|
51899
|
-
((_f = err.params) === null || _f === void 0 ? void 0 : _f.firmwareUpdateCode) === 'FirmwareArtifactsNotPrepared') {
|
|
51900
|
-
throw err;
|
|
51901
|
-
}
|
|
51902
51551
|
if (err instanceof hdShared.HardwareError && err.errorCode === hdShared.HardwareErrorCode.NetworkError) {
|
|
51903
51552
|
throw err;
|
|
51904
51553
|
}
|
|
51905
51554
|
throw normalizeFirmwarePreparationError(err);
|
|
51906
51555
|
}
|
|
51907
|
-
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) {
|
|
51908
51561
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
|
|
51909
51562
|
}
|
|
51910
|
-
|
|
51911
|
-
|
|
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)));
|
|
51912
51584
|
});
|
|
51913
51585
|
}
|
|
51914
51586
|
openProtocolV2PreparedSource(artifact) {
|
|
@@ -51945,34 +51617,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51945
51617
|
prepareProtocolV2InstallSources(firmwareType, features) {
|
|
51946
51618
|
var _a, _b;
|
|
51947
51619
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51948
|
-
if (this.params.preparedPlan) {
|
|
51949
|
-
const requestedTargets = new Set(this.params.preparedPlan.targetsToUpdate.filter((target) => target !== 'resource'));
|
|
51950
|
-
const installSources = [];
|
|
51951
|
-
const preparedTargets = new Set();
|
|
51952
|
-
for (const artifact of this.params.preparedPlan.artifacts) {
|
|
51953
|
-
if (artifact.target !== 'resource') {
|
|
51954
|
-
const target = artifact.target;
|
|
51955
|
-
const installTarget = PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.get(target);
|
|
51956
|
-
if (!requestedTargets.has(target) ||
|
|
51957
|
-
artifact.role !== 'component' ||
|
|
51958
|
-
artifact.container !== 'raw' ||
|
|
51959
|
-
!installTarget ||
|
|
51960
|
-
preparedTargets.has(target)) {
|
|
51961
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 prepared component artifact is invalid: ${artifact.artifactId}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51962
|
-
}
|
|
51963
|
-
installSources.push(Object.assign(Object.assign({}, installTarget), { source: yield this.openProtocolV2PreparedSource(artifact.artifact) }));
|
|
51964
|
-
preparedTargets.add(target);
|
|
51965
|
-
}
|
|
51966
|
-
}
|
|
51967
|
-
const missingTarget = Array.from(requestedTargets).find(target => !preparedTargets.has(target));
|
|
51968
|
-
if (missingTarget) {
|
|
51969
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 ${missingTarget} artifact is not prepared`, {
|
|
51970
|
-
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51971
|
-
artifactName: missingTarget,
|
|
51972
|
-
});
|
|
51973
|
-
}
|
|
51974
|
-
return installSources;
|
|
51975
|
-
}
|
|
51976
51620
|
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
51977
51621
|
if (!release) {
|
|
51978
51622
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware release is unavailable');
|
|
@@ -52003,278 +51647,39 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52003
51647
|
return installSources;
|
|
52004
51648
|
});
|
|
52005
51649
|
}
|
|
52006
|
-
|
|
52007
|
-
var _a, _b;
|
|
52008
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
52009
|
-
const installItems = this.buildProtocolV2InstallItems({
|
|
52010
|
-
bootloaderBinary: this.prepareBootloaderBinary(),
|
|
52011
|
-
fwBinaryMap: this.collectExplicitTargetBinaries(),
|
|
52012
|
-
});
|
|
52013
|
-
const requestedComponentTargets = new Set(((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter((target) => target !== 'resource' && target !== 'boot_resources'));
|
|
52014
|
-
const localComponentTargets = new Set(installItems.flatMap(item => {
|
|
52015
|
-
const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
|
|
52016
|
-
return target ? [target] : [];
|
|
52017
|
-
}));
|
|
52018
|
-
const missingTarget = Array.from(requestedComponentTargets).find(target => !localComponentTargets.has(target));
|
|
52019
|
-
if (missingTarget) {
|
|
52020
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local update has no binary for requested target ${missingTarget}`, {
|
|
52021
|
-
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
52022
|
-
artifactName: missingTarget,
|
|
52023
|
-
});
|
|
52024
|
-
}
|
|
52025
|
-
const planArtifacts = [];
|
|
52026
|
-
const memoryArtifacts = [];
|
|
52027
|
-
for (const item of installItems) {
|
|
52028
|
-
const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
|
|
52029
|
-
if (!target || item.binary.byteLength <= 0) {
|
|
52030
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local firmware artifact is invalid: ${item.fileName}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52031
|
-
}
|
|
52032
|
-
const artifactId = `component:${target}`;
|
|
52033
|
-
planArtifacts.push(Object.assign({ artifactId,
|
|
52034
|
-
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])
|
|
52035
|
-
? { targetVersion: this.params.expectedTargetVersions[target] }
|
|
52036
|
-
: {})));
|
|
52037
|
-
memoryArtifacts.push({ artifactId, binary: item.binary });
|
|
52038
|
-
}
|
|
52039
|
-
const resourceArchive = yield this.prepareProtocolV2LocalResourceArchive(this.params.resourceArchiveBinary);
|
|
52040
|
-
const resourceArtifactId = 'resource:archive';
|
|
52041
|
-
planArtifacts.push({
|
|
52042
|
-
artifactId: resourceArtifactId,
|
|
52043
|
-
target: 'resource',
|
|
52044
|
-
container: 'zip',
|
|
52045
|
-
logicalName: 'protocol-v2-local-resource-archive',
|
|
52046
|
-
expectedSize: resourceArchive.binary.byteLength,
|
|
52047
|
-
expectedSha256: bytesToHex(sha256.sha256(new Uint8Array(resourceArchive.binary))),
|
|
52048
|
-
});
|
|
52049
|
-
memoryArtifacts.push({
|
|
52050
|
-
artifactId: resourceArtifactId,
|
|
52051
|
-
binary: resourceArchive.binary,
|
|
52052
|
-
materializedEntries: resourceArchive.materializedEntries,
|
|
52053
|
-
});
|
|
52054
|
-
const plan = buildProtocolV2LocalFirmwareUpdatePlan({
|
|
52055
|
-
features,
|
|
52056
|
-
firmwareType,
|
|
52057
|
-
platform: this.params.platform,
|
|
52058
|
-
artifacts: planArtifacts,
|
|
52059
|
-
});
|
|
52060
|
-
let memoryHost;
|
|
52061
|
-
try {
|
|
52062
|
-
memoryHost = prepareFirmwareUpdateV4MemoryHost({
|
|
52063
|
-
sdk: {
|
|
52064
|
-
prepareFirmwareUpdatePlan,
|
|
52065
|
-
registerFirmwareUpdateHostBinding,
|
|
52066
|
-
unregisterFirmwareUpdateHostBinding,
|
|
52067
|
-
},
|
|
52068
|
-
plan,
|
|
52069
|
-
artifacts: memoryArtifacts,
|
|
52070
|
-
});
|
|
52071
|
-
const preparedPlan = validateFirmwareUpdatePreparedPlan(memoryHost.preparedPlan);
|
|
52072
|
-
assertFirmwareUpdatePreparedPlanBinding({
|
|
52073
|
-
preparedPlan,
|
|
52074
|
-
executor: 'v4',
|
|
52075
|
-
platform: this.params.platform,
|
|
52076
|
-
scopeTargets: [],
|
|
52077
|
-
bindings: [],
|
|
52078
|
-
});
|
|
52079
|
-
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
52080
|
-
preparedPlan,
|
|
52081
|
-
deviceIdentity: this.protocolV2ExpectedSerialNumber,
|
|
52082
|
-
deviceModel: this.getProtocolV2PreparedPlanDeviceModel(features),
|
|
52083
|
-
});
|
|
52084
|
-
const hostBinding = resolveFirmwareUpdateHostBinding(memoryHost.hostBindingGeneration, preparedPlan.preparedPlanDigest);
|
|
52085
|
-
this.params.preparedPlan = preparedPlan;
|
|
52086
|
-
this.params.targetsToUpdate = [...preparedPlan.targetsToUpdate];
|
|
52087
|
-
this.params.artifactReader = hostBinding.artifactReader;
|
|
52088
|
-
this.params.componentArtifacts = undefined;
|
|
52089
|
-
return memoryHost;
|
|
52090
|
-
}
|
|
52091
|
-
catch (error) {
|
|
52092
|
-
memoryHost === null || memoryHost === void 0 ? void 0 : memoryHost.release();
|
|
52093
|
-
throw error;
|
|
52094
|
-
}
|
|
52095
|
-
});
|
|
52096
|
-
}
|
|
52097
|
-
prepareProtocolV2LocalResourceArchive(binary) {
|
|
52098
|
-
var _a;
|
|
52099
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
52100
|
-
if (binary.byteLength <= 0 || binary.byteLength > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
|
|
52101
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP archive size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52102
|
-
}
|
|
52103
|
-
const zip = yield JSZip__default["default"].loadAsync(binary);
|
|
52104
|
-
const zipEntries = Object.values(zip.files);
|
|
52105
|
-
if (zipEntries.some(entry => entry.unsafeOriginalName && entry.unsafeOriginalName !== entry.name)) {
|
|
52106
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unsafe entry path', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52107
|
-
}
|
|
52108
|
-
const entries = zipEntries.filter(entry => !entry.dir);
|
|
52109
|
-
if (entries.length === 0 || entries.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT + 1) {
|
|
52110
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP entry set is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52111
|
-
}
|
|
52112
|
-
let declaredUncompressedSize = 0;
|
|
52113
|
-
let declaredCompressedSize = 0;
|
|
52114
|
-
for (const entry of entries) {
|
|
52115
|
-
const sizes = getProtocolV2ZipEntrySizes(entry);
|
|
52116
|
-
declaredCompressedSize += sizes.compressedSize;
|
|
52117
|
-
declaredUncompressedSize += sizes.uncompressedSize;
|
|
52118
|
-
const entryLimit = entry.name === 'manifest.json'
|
|
52119
|
-
? PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES
|
|
52120
|
-
: PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES;
|
|
52121
|
-
if (sizes.uncompressedSize > entryLimit ||
|
|
52122
|
-
declaredCompressedSize > binary.byteLength ||
|
|
52123
|
-
declaredUncompressedSize >
|
|
52124
|
-
PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES + PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
|
|
52125
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP declared size exceeds the allowed limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52126
|
-
}
|
|
52127
|
-
}
|
|
52128
|
-
const manifestEntry = zip.file('manifest.json');
|
|
52129
|
-
if (!manifestEntry) {
|
|
52130
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP has no manifest.json', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52131
|
-
}
|
|
52132
|
-
const manifestBinary = yield manifestEntry.async('arraybuffer');
|
|
52133
|
-
if (manifestBinary.byteLength <= 0 ||
|
|
52134
|
-
manifestBinary.byteLength > PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
|
|
52135
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52136
|
-
}
|
|
52137
|
-
let manifestValue;
|
|
52138
|
-
try {
|
|
52139
|
-
manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
|
|
52140
|
-
}
|
|
52141
|
-
catch (error) {
|
|
52142
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52143
|
-
}
|
|
52144
|
-
const manifest = parseProtocolV2ResourceManifest(manifestValue);
|
|
52145
|
-
const selectedFiles = selectProtocolV2ResourceManifestFiles({
|
|
52146
|
-
manifest,
|
|
52147
|
-
targetsToUpdate: (_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [],
|
|
52148
|
-
});
|
|
52149
|
-
const expectedEntryNames = new Set([
|
|
52150
|
-
'manifest.json',
|
|
52151
|
-
...selectedFiles.map(file => file.archive_path),
|
|
52152
|
-
]);
|
|
52153
|
-
if (entries.length !== expectedEntryNames.size ||
|
|
52154
|
-
entries.some(entry => !expectedEntryNames.has(entry.name))) {
|
|
52155
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unexpected entry', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52156
|
-
}
|
|
52157
|
-
let totalSize = 0;
|
|
52158
|
-
const materializedEntries = [
|
|
52159
|
-
{ entryName: 'manifest.json', binary: manifestBinary },
|
|
52160
|
-
];
|
|
52161
|
-
for (const file of selectedFiles) {
|
|
52162
|
-
const entry = zip.file(file.archive_path);
|
|
52163
|
-
if (!entry) {
|
|
52164
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP is missing ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52165
|
-
}
|
|
52166
|
-
const { uncompressedSize } = getProtocolV2ZipEntrySizes(entry);
|
|
52167
|
-
totalSize += uncompressedSize;
|
|
52168
|
-
if (uncompressedSize !== file.size || totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
|
|
52169
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file declared size is invalid: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52170
|
-
}
|
|
52171
|
-
const fileBinary = yield entry.async('arraybuffer');
|
|
52172
|
-
const digest = bytesToHex(sha256.sha256(new Uint8Array(fileBinary)));
|
|
52173
|
-
if (fileBinary.byteLength !== file.size || digest !== file.sha256.toLowerCase()) {
|
|
52174
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file does not match manifest: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
52175
|
-
}
|
|
52176
|
-
materializedEntries.push({ entryName: file.archive_path, binary: fileBinary });
|
|
52177
|
-
}
|
|
52178
|
-
return { binary, materializedEntries };
|
|
52179
|
-
});
|
|
52180
|
-
}
|
|
52181
|
-
prepareProtocolV2ResourceSources() {
|
|
52182
|
-
var _a, _b;
|
|
51650
|
+
prepareProtocolV2ResourceSources(firmwareType, features) {
|
|
51651
|
+
var _a, _b, _c;
|
|
52183
51652
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52184
|
-
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;
|
|
52185
51655
|
if (!resourceRequested) {
|
|
52186
51656
|
return [];
|
|
52187
51657
|
}
|
|
52188
|
-
const
|
|
52189
|
-
|
|
52190
|
-
|
|
52191
|
-
}
|
|
52192
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive is not prepared', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52193
|
-
});
|
|
52194
|
-
}
|
|
52195
|
-
prepareProtocolV2ResourceArchiveSources() {
|
|
52196
|
-
var _a, _b, _c, _d;
|
|
52197
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
52198
|
-
const archiveArtifacts = (_b = (_a = this.params.preparedPlan) === null || _a === void 0 ? void 0 : _a.artifacts.filter(artifact => artifact.role === 'resourceBundle' &&
|
|
52199
|
-
artifact.target === 'resource' &&
|
|
52200
|
-
artifact.container === 'zip')) !== null && _b !== void 0 ? _b : [];
|
|
52201
|
-
if (archiveArtifacts.length === 0) {
|
|
52202
|
-
return undefined;
|
|
52203
|
-
}
|
|
52204
|
-
if (archiveArtifacts.length !== 1) {
|
|
52205
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared plan must contain exactly one resource archive', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52206
|
-
}
|
|
52207
|
-
const archiveArtifact = archiveArtifacts[0];
|
|
52208
|
-
const archiveSource = yield this.openProtocolV2PreparedSource(archiveArtifact.artifact);
|
|
52209
|
-
if (archiveSource.size > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
|
|
52210
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive exceeds the total size limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52211
|
-
}
|
|
52212
|
-
let archiveBinary;
|
|
52213
|
-
try {
|
|
52214
|
-
archiveBinary = yield readFirmwareByteSourceFully(archiveSource);
|
|
52215
|
-
}
|
|
52216
|
-
finally {
|
|
52217
|
-
yield archiveSource.close();
|
|
52218
|
-
}
|
|
52219
|
-
const archiveDigest = bytesToHex(sha256.sha256(new Uint8Array(archiveBinary)));
|
|
52220
|
-
if (archiveDigest !== archiveArtifact.artifact.sha256.toLowerCase()) {
|
|
52221
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive does not match its approved receipt', { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
52222
|
-
}
|
|
52223
|
-
const verifiedArchive = yield this.prepareProtocolV2LocalResourceArchive(archiveBinary);
|
|
52224
|
-
const entries = (_c = archiveArtifact.materializedEntries) !== null && _c !== void 0 ? _c : [];
|
|
52225
|
-
const entriesByName = new Map(entries.map(entry => [entry.entryName, entry]));
|
|
52226
|
-
if (entries.length !== verifiedArchive.materializedEntries.length ||
|
|
52227
|
-
verifiedArchive.materializedEntries.some(entry => {
|
|
52228
|
-
const preparedEntry = entriesByName.get(entry.entryName);
|
|
52229
|
-
const digest = bytesToHex(sha256.sha256(new Uint8Array(entry.binary)));
|
|
52230
|
-
return (!preparedEntry ||
|
|
52231
|
-
preparedEntry.artifact.size !== entry.binary.byteLength ||
|
|
52232
|
-
preparedEntry.artifact.sha256.toLowerCase() !== digest);
|
|
52233
|
-
})) {
|
|
52234
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource entries do not match the approved archive', { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
52235
|
-
}
|
|
52236
|
-
const verifiedEntriesByName = new Map(verifiedArchive.materializedEntries.map(entry => [entry.entryName, entry.binary]));
|
|
52237
|
-
const manifestBinary = verifiedEntriesByName.get('manifest.json');
|
|
52238
|
-
if (!manifestBinary) {
|
|
52239
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive has no valid manifest.json', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52240
|
-
}
|
|
52241
|
-
let manifestValue;
|
|
52242
|
-
try {
|
|
52243
|
-
manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
|
|
52244
|
-
}
|
|
52245
|
-
catch (error) {
|
|
52246
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 prepared resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52247
|
-
}
|
|
52248
|
-
const manifest = parseProtocolV2ResourceManifest(manifestValue);
|
|
52249
|
-
const selectedFiles = selectProtocolV2ResourceManifestFiles({
|
|
52250
|
-
manifest,
|
|
52251
|
-
targetsToUpdate: (_d = this.params.targetsToUpdate) !== null && _d !== void 0 ? _d : [],
|
|
52252
|
-
});
|
|
52253
|
-
if (selectedFiles.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT) {
|
|
52254
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive contains too many files', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
52255
|
-
}
|
|
52256
|
-
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]));
|
|
52257
51661
|
const sources = [];
|
|
52258
|
-
for (const
|
|
52259
|
-
const
|
|
52260
|
-
if (!
|
|
52261
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2
|
|
52262
|
-
|
|
52263
|
-
|
|
52264
|
-
|
|
52265
|
-
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
|
+
});
|
|
52266
51669
|
}
|
|
52267
|
-
const
|
|
52268
|
-
|
|
52269
|
-
|
|
52270
|
-
:
|
|
52271
|
-
|
|
52272
|
-
|
|
52273
|
-
|
|
52274
|
-
|
|
52275
|
-
|
|
52276
|
-
|
|
52277
|
-
|
|
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}`);
|
|
52278
51683
|
}
|
|
52279
51684
|
return sources;
|
|
52280
51685
|
});
|
|
@@ -52284,7 +51689,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52284
51689
|
try {
|
|
52285
51690
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
52286
51691
|
const installSources = yield this.prepareProtocolV2InstallSources(firmwareType, features);
|
|
52287
|
-
const resourceSources = yield this.prepareProtocolV2ResourceSources();
|
|
51692
|
+
const resourceSources = yield this.prepareProtocolV2ResourceSources(firmwareType, features);
|
|
52288
51693
|
if (installSources.length === 0 && resourceSources.length === 0) {
|
|
52289
51694
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
|
|
52290
51695
|
}
|
|
@@ -52368,15 +51773,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52368
51773
|
}
|
|
52369
51774
|
}
|
|
52370
51775
|
getProtocolV2RequestedTargets() {
|
|
52371
|
-
var _a, _b, _c;
|
|
51776
|
+
var _a, _b, _c, _d;
|
|
52372
51777
|
if ((_a = this.params.targetsToUpdate) === null || _a === void 0 ? void 0 : _a.length) {
|
|
52373
51778
|
return [...new Set(this.params.targetsToUpdate)];
|
|
52374
51779
|
}
|
|
52375
|
-
if ((_b = this.params.preparedPlan) === null || _b === void 0 ? void 0 : _b.targetsToUpdate.length) {
|
|
52376
|
-
return [...new Set(this.params.preparedPlan.targetsToUpdate)];
|
|
52377
|
-
}
|
|
52378
51780
|
const targets = new Set();
|
|
52379
|
-
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
|
+
}
|
|
52380
51785
|
if (this.params.bootloaderBinary)
|
|
52381
51786
|
targets.add('boot');
|
|
52382
51787
|
if (this.params.applicationP1Binary)
|
|
@@ -52413,26 +51818,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52413
51818
|
const serialNumber = (_b = (_a = deviceInfo.hw) === null || _a === void 0 ? void 0 : _a.serial_no) === null || _b === void 0 ? void 0 : _b.trim();
|
|
52414
51819
|
return serialNumber || undefined;
|
|
52415
51820
|
}
|
|
52416
|
-
getProtocolV2PreparedPlanDeviceModel(features) {
|
|
52417
|
-
const currentDeviceType = this.device.getCurrentDeviceType();
|
|
52418
|
-
const featureDeviceType = features ? getDeviceType(features) : undefined;
|
|
52419
|
-
const deviceType = currentDeviceType === hdShared.EDeviceType.Pro2 || currentDeviceType === hdShared.EDeviceType.Neo
|
|
52420
|
-
? currentDeviceType
|
|
52421
|
-
: featureDeviceType;
|
|
52422
|
-
return deviceType === hdShared.EDeviceType.Pro2 || deviceType === hdShared.EDeviceType.Neo
|
|
52423
|
-
? String(deviceType)
|
|
52424
|
-
: undefined;
|
|
52425
|
-
}
|
|
52426
|
-
getProtocolV2ConnectionRoute() {
|
|
52427
|
-
var _a, _b, _c, _d, _e;
|
|
52428
|
-
const descriptor = this.device.originalDescriptor;
|
|
52429
|
-
return (((_a = descriptor === null || descriptor === void 0 ? void 0 : descriptor.path) === null || _a === void 0 ? void 0 : _a.trim()) ||
|
|
52430
|
-
((_d = (_c = (_b = this.device).getConnectId) === null || _c === void 0 ? void 0 : _c.call(_b)) === null || _d === void 0 ? void 0 : _d.trim()) ||
|
|
52431
|
-
((_e = descriptor === null || descriptor === void 0 ? void 0 : descriptor.id) === null || _e === void 0 ? void 0 : _e.trim()) ||
|
|
52432
|
-
undefined);
|
|
52433
|
-
}
|
|
52434
51821
|
assertProtocolV2DeviceInfoIdentity(deviceInfo) {
|
|
52435
|
-
assertProtocolV2ReconnectIdentity(this.protocolV2ExpectedSerialNumber, this.getProtocolV2SerialNumber(deviceInfo), this.protocolV2ExpectedPath, this.
|
|
51822
|
+
assertProtocolV2ReconnectIdentity(this.protocolV2ExpectedSerialNumber, this.getProtocolV2SerialNumber(deviceInfo), this.protocolV2ExpectedPath, this.device.originalDescriptor.path);
|
|
52436
51823
|
}
|
|
52437
51824
|
getProtocolV2DeviceInfoTimeout() {
|
|
52438
51825
|
var _a;
|
|
@@ -52449,20 +51836,19 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52449
51836
|
});
|
|
52450
51837
|
}
|
|
52451
51838
|
captureProtocolV2PhysicalIdentity() {
|
|
52452
|
-
var _a, _b, _c;
|
|
51839
|
+
var _a, _b, _c, _d, _e;
|
|
52453
51840
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52454
51841
|
const deviceInfo = yield this.requestProtocolV2PhysicalIdentity();
|
|
52455
51842
|
const serialNumber = this.getProtocolV2SerialNumber(deviceInfo);
|
|
52456
|
-
const path = this.
|
|
52457
|
-
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) {
|
|
52458
51845
|
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
52459
51846
|
preparedPlan: this.params.preparedPlan,
|
|
52460
51847
|
deviceIdentity: serialNumber,
|
|
52461
|
-
deviceModel: this.getProtocolV2PreparedPlanDeviceModel(this.device.features),
|
|
52462
51848
|
});
|
|
52463
51849
|
}
|
|
52464
|
-
else if ((
|
|
52465
|
-
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);
|
|
52466
51852
|
}
|
|
52467
51853
|
else {
|
|
52468
51854
|
assertProtocolV2ReconnectIdentity(serialNumber, serialNumber, path, path);
|
|
@@ -52482,15 +51868,11 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52482
51868
|
var _a;
|
|
52483
51869
|
return (_a = this.params.bootloaderBinary) !== null && _a !== void 0 ? _a : null;
|
|
52484
51870
|
}
|
|
52485
|
-
|
|
51871
|
+
hasExplicitProtocolV2Payload(fwBinaryMap) {
|
|
52486
51872
|
var _a;
|
|
52487
|
-
|
|
52488
|
-
|
|
52489
|
-
|
|
52490
|
-
}));
|
|
52491
|
-
return ((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [])
|
|
52492
|
-
.filter((target) => target !== 'resource' && target !== 'boot_resources')
|
|
52493
|
-
.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);
|
|
52494
51876
|
}
|
|
52495
51877
|
buildProtocolV2InstallItems({ bootloaderBinary, fwBinaryMap, }) {
|
|
52496
51878
|
const installItems = [];
|
|
@@ -52539,17 +51921,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52539
51921
|
if (!component.url) {
|
|
52540
51922
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Missing Protocol V2 firmware component url: ${key}/${component.target}`);
|
|
52541
51923
|
}
|
|
52542
|
-
const expectedFingerprint = normalizeProtocolV2Hex(component.fingerprint);
|
|
52543
|
-
if (!Number.isSafeInteger(component.expectedSize) ||
|
|
52544
|
-
Number(component.expectedSize) <= 0 ||
|
|
52545
|
-
!expectedFingerprint ||
|
|
52546
|
-
!/^[0-9a-f]{64}$/u.test(expectedFingerprint)) {
|
|
52547
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware component integrity metadata is invalid: ${key}/${component.target}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
|
|
52548
|
-
}
|
|
52549
51924
|
const { binary } = yield getSysResourceBinary(component.url);
|
|
52550
|
-
if (binary.byteLength !== component.expectedSize) {
|
|
52551
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware size mismatch: ${key}/${component.target}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
52552
|
-
}
|
|
52553
51925
|
if (!isProtocolV2FirmwareFingerprintValid(binary, component.fingerprint)) {
|
|
52554
51926
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware fingerprint mismatch: ${key}/${component.target}`);
|
|
52555
51927
|
}
|
|
@@ -52563,7 +51935,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52563
51935
|
return Object.assign(Object.assign({}, target), { binary });
|
|
52564
51936
|
});
|
|
52565
51937
|
}
|
|
52566
|
-
prepareRemoteProtocolV2Binaries(firmwareType, features
|
|
51938
|
+
prepareRemoteProtocolV2Binaries(firmwareType, features) {
|
|
52567
51939
|
var _a, _b;
|
|
52568
51940
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52569
51941
|
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
@@ -52571,10 +51943,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52571
51943
|
const fwBinaryMap = [];
|
|
52572
51944
|
const installItems = [];
|
|
52573
51945
|
if (!release) {
|
|
52574
|
-
const missingFirmwareTargets = this.getMissingProtocolV2FirmwareTargets(explicitInstallItems);
|
|
52575
|
-
if (missingFirmwareTargets.length > 0) {
|
|
52576
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware release is unavailable for requested targets: ${missingFirmwareTargets.join(', ')}`);
|
|
52577
|
-
}
|
|
52578
51946
|
return {
|
|
52579
51947
|
bootloaderBinary,
|
|
52580
51948
|
fwBinaryMap,
|
|
@@ -52583,8 +51951,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52583
51951
|
}
|
|
52584
51952
|
const entries = this.getRemoteComponentEntries(release);
|
|
52585
51953
|
const targetsToUpdate = new Set((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : []);
|
|
52586
|
-
const explicitInstallItemByTargetId = new Map(explicitInstallItems.map(item => [item.targetId, item]));
|
|
52587
|
-
const preparedTargets = new Set();
|
|
52588
51954
|
for (const [key, component] of entries) {
|
|
52589
51955
|
const targetName = (_b = component.target) === null || _b === void 0 ? void 0 : _b.toUpperCase();
|
|
52590
51956
|
const target = PROTOCOL_V2_REMOTE_COMPONENT_TARGETS[targetName];
|
|
@@ -52592,27 +51958,27 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52592
51958
|
? PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId)
|
|
52593
51959
|
: undefined;
|
|
52594
51960
|
if (updateTarget && targetsToUpdate.has(updateTarget)) {
|
|
52595
|
-
const
|
|
52596
|
-
|
|
52597
|
-
|
|
52598
|
-
|
|
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
|
+
});
|
|
52599
51970
|
}
|
|
52600
51971
|
else {
|
|
52601
51972
|
const binaryEntry = {
|
|
52602
|
-
fileName:
|
|
52603
|
-
binary:
|
|
52604
|
-
targetId:
|
|
51973
|
+
fileName: remoteBinary.fileName,
|
|
51974
|
+
binary: remoteBinary.binary,
|
|
51975
|
+
targetId: remoteBinary.targetId,
|
|
52605
51976
|
};
|
|
52606
51977
|
fwBinaryMap.push(binaryEntry);
|
|
51978
|
+
installItems.push(Object.assign(Object.assign({}, binaryEntry), { kind: remoteBinary.kind }));
|
|
52607
51979
|
}
|
|
52608
|
-
installItems.push(Object.assign({}, installItem));
|
|
52609
|
-
preparedTargets.add(updateTarget);
|
|
52610
51980
|
}
|
|
52611
51981
|
}
|
|
52612
|
-
const missingTarget = Array.from(targetsToUpdate).find(target => target !== 'resource' && !preparedTargets.has(target));
|
|
52613
|
-
if (missingTarget) {
|
|
52614
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 release does not contain requested target ${missingTarget}`);
|
|
52615
|
-
}
|
|
52616
51982
|
return {
|
|
52617
51983
|
bootloaderBinary,
|
|
52618
51984
|
fwBinaryMap,
|
|
@@ -52620,6 +51986,178 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52620
51986
|
};
|
|
52621
51987
|
});
|
|
52622
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
|
+
}
|
|
52623
52161
|
getProtocolV2ResourceFilePath(path) {
|
|
52624
52162
|
if (path.startsWith('vol'))
|
|
52625
52163
|
return path;
|
|
@@ -52627,7 +52165,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52627
52165
|
return `vol0:${path}`;
|
|
52628
52166
|
return `vol0:/${path}`;
|
|
52629
52167
|
}
|
|
52630
|
-
readProtocolV2DeviceFileHeader(path
|
|
52168
|
+
readProtocolV2DeviceFileHeader(path) {
|
|
52631
52169
|
var _a, _b, _c, _d;
|
|
52632
52170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52633
52171
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
@@ -52639,8 +52177,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52639
52177
|
if (!((_b = pathInfoRes.message) === null || _b === void 0 ? void 0 : _b.exist) ||
|
|
52640
52178
|
((_c = pathInfoRes.message) === null || _c === void 0 ? void 0 : _c.directory) ||
|
|
52641
52179
|
fileSize === undefined ||
|
|
52642
|
-
fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE
|
|
52643
|
-
(expectedSize !== undefined && fileSize !== expectedSize)) {
|
|
52180
|
+
fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE) {
|
|
52644
52181
|
return null;
|
|
52645
52182
|
}
|
|
52646
52183
|
const chunkSize = this.getProtocolV2FirmwareChunkSize('read');
|
|
@@ -52677,10 +52214,10 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52677
52214
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52678
52215
|
if ((_a = this.params) === null || _a === void 0 ? void 0 : _a.forcedUpdateRes)
|
|
52679
52216
|
return false;
|
|
52680
|
-
if (!bundle.
|
|
52217
|
+
if (!bundle.version && !bundle.payloadHash)
|
|
52681
52218
|
return false;
|
|
52682
52219
|
try {
|
|
52683
|
-
const header = yield this.readProtocolV2DeviceFileHeader(bundle.devicePath
|
|
52220
|
+
const header = yield this.readProtocolV2DeviceFileHeader(bundle.devicePath);
|
|
52684
52221
|
if (!header)
|
|
52685
52222
|
return false;
|
|
52686
52223
|
if (bundle.version) {
|
|
@@ -52688,12 +52225,16 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52688
52225
|
if (cmp === undefined || cmp !== 0)
|
|
52689
52226
|
return false;
|
|
52690
52227
|
}
|
|
52691
|
-
|
|
52692
|
-
|
|
52693
|
-
|
|
52694
|
-
|
|
52695
|
-
|
|
52696
|
-
|
|
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
|
+
}
|
|
52697
52238
|
return true;
|
|
52698
52239
|
}
|
|
52699
52240
|
catch (error) {
|
|
@@ -52808,6 +52349,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52808
52349
|
}
|
|
52809
52350
|
buildProtocolV2ExecutionPhases({ installSources, resourceSources, }) {
|
|
52810
52351
|
const phases = [];
|
|
52352
|
+
if (resourceSources.length > 0) {
|
|
52353
|
+
phases.push({
|
|
52354
|
+
kind: 'resource-sync',
|
|
52355
|
+
installSources: [],
|
|
52356
|
+
resourceSources,
|
|
52357
|
+
});
|
|
52358
|
+
}
|
|
52811
52359
|
const bootloaderSources = installSources.filter(source => source.kind === 'bootloader');
|
|
52812
52360
|
if (bootloaderSources.length > 0) {
|
|
52813
52361
|
phases.push({
|
|
@@ -52820,13 +52368,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52820
52368
|
resourceSources: [],
|
|
52821
52369
|
});
|
|
52822
52370
|
}
|
|
52823
|
-
if (resourceSources.length > 0) {
|
|
52824
|
-
phases.push({
|
|
52825
|
-
kind: 'resource-sync',
|
|
52826
|
-
installSources: [],
|
|
52827
|
-
resourceSources,
|
|
52828
|
-
});
|
|
52829
|
-
}
|
|
52830
52371
|
const componentSources = installSources.filter(source => source.kind !== 'bootloader');
|
|
52831
52372
|
if (componentSources.length > 0) {
|
|
52832
52373
|
phases.push({
|
|
@@ -52877,7 +52418,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52877
52418
|
});
|
|
52878
52419
|
});
|
|
52879
52420
|
}
|
|
52880
|
-
executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, }) {
|
|
52421
|
+
executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, resourceBundles, }) {
|
|
52881
52422
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52882
52423
|
const memoryInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
|
|
52883
52424
|
fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
|
|
@@ -52892,9 +52433,16 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52892
52433
|
kind: item.kind,
|
|
52893
52434
|
});
|
|
52894
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
|
+
})));
|
|
52895
52443
|
return yield this.executeProtocolV2Phases({
|
|
52896
52444
|
installSources,
|
|
52897
|
-
resourceSources
|
|
52445
|
+
resourceSources,
|
|
52898
52446
|
});
|
|
52899
52447
|
}
|
|
52900
52448
|
finally {
|
|
@@ -52918,14 +52466,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52918
52466
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
|
|
52919
52467
|
let processedSize = 0;
|
|
52920
52468
|
for (const resource of resourcesToSync) {
|
|
52921
|
-
const writePath = resolveProtocolV2ResourceWritePath(resource.devicePath);
|
|
52922
52469
|
processedSize = yield this.protocolV2SourceUpdateProcess({
|
|
52923
52470
|
source: resource.source,
|
|
52924
|
-
filePath:
|
|
52471
|
+
filePath: resource.devicePath,
|
|
52925
52472
|
processedSize,
|
|
52926
52473
|
totalSize,
|
|
52927
52474
|
});
|
|
52928
|
-
yield this.verifyProtocolV2StagedFile(
|
|
52475
|
+
yield this.verifyProtocolV2StagedFile(resource.devicePath, resource.source.size);
|
|
52929
52476
|
}
|
|
52930
52477
|
const stagedInstallTargets = [];
|
|
52931
52478
|
for (const item of installSources) {
|
|
@@ -53915,7 +53462,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
53915
53462
|
}
|
|
53916
53463
|
|
|
53917
53464
|
const FILESYSTEM_PATH_INFO_QUERY_MESSAGE_TYPE = 60802;
|
|
53918
|
-
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE
|
|
53465
|
+
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
53919
53466
|
const FILESYSTEM_DIR_LIST_MESSAGE_TYPE = 60808;
|
|
53920
53467
|
const NFT_UPDATE_MESSAGE_TYPE = 61500;
|
|
53921
53468
|
class DeviceUploadNft extends BaseMethod {
|
|
@@ -53944,7 +53491,7 @@ class DeviceUploadNft extends BaseMethod {
|
|
|
53944
53491
|
assertCapabilities() {
|
|
53945
53492
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53946
53493
|
const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
|
|
53947
|
-
const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE
|
|
53494
|
+
const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE);
|
|
53948
53495
|
const hasPathInfo = supportsProtocolV2Message(protocolInfo, FILESYSTEM_PATH_INFO_QUERY_MESSAGE_TYPE);
|
|
53949
53496
|
const hasDirList = supportsProtocolV2Message(protocolInfo, FILESYSTEM_DIR_LIST_MESSAGE_TYPE);
|
|
53950
53497
|
const hasNftUpdate = supportsProtocolV2Message(protocolInfo, NFT_UPDATE_MESSAGE_TYPE);
|
|
@@ -54079,8 +53626,6 @@ class FileWrite extends BaseMethod {
|
|
|
54079
53626
|
|
|
54080
53627
|
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
|
|
54081
53628
|
const PORTFOLIO_CHUNK_SIZE = 2048;
|
|
54082
|
-
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
54083
|
-
const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
|
|
54084
53629
|
class UploadPortfolio extends FileWrite {
|
|
54085
53630
|
init() {
|
|
54086
53631
|
const { packageBytes, timeoutMs } = this.payload;
|
|
@@ -54094,12 +53639,6 @@ class UploadPortfolio extends FileWrite {
|
|
|
54094
53639
|
run: { get: () => super.run }
|
|
54095
53640
|
});
|
|
54096
53641
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54097
|
-
const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
|
|
54098
|
-
const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE);
|
|
54099
|
-
const hasPortfolioUpdate = supportsProtocolV2Message(protocolInfo, PORTFOLIO_UPDATE_MESSAGE_TYPE);
|
|
54100
|
-
if (!hasFileWrite || !hasPortfolioUpdate) {
|
|
54101
|
-
throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
|
|
54102
|
-
}
|
|
54103
53642
|
const stagedFile = yield _super.run.call(this);
|
|
54104
53643
|
this.throwIfAborted();
|
|
54105
53644
|
yield this.device.commands.typedCall('PortfolioUpdate', 'Success', {});
|
|
@@ -65641,14 +65180,11 @@ exports.normalizeSafetyCheckLevel = normalizeSafetyCheckLevel;
|
|
|
65641
65180
|
exports.normalizeVersionArray = normalizeVersionArray;
|
|
65642
65181
|
exports.parseConnectSettings = parseConnectSettings;
|
|
65643
65182
|
exports.parseMessage = parseMessage;
|
|
65644
|
-
exports.parseProtocolV2ResourceManifest = parseProtocolV2ResourceManifest;
|
|
65645
65183
|
exports.patchFeatures = patchFeatures;
|
|
65646
65184
|
exports.preloadSessionCache = preloadSessionCache;
|
|
65647
|
-
exports.prepareFirmwareUpdateV4MemoryHost = prepareFirmwareUpdateV4MemoryHost;
|
|
65648
65185
|
exports.projectDeviceStateFeatures = projectFeatures;
|
|
65649
65186
|
exports.registerFirmwareUpdateHostBinding = registerFirmwareUpdateHostBinding;
|
|
65650
65187
|
exports.safeThrowError = safeThrowError;
|
|
65651
|
-
exports.selectProtocolV2ResourceManifestFiles = selectProtocolV2ResourceManifestFiles;
|
|
65652
65188
|
exports.setLoggerPostMessage = setLoggerPostMessage;
|
|
65653
65189
|
exports.supportInputPinOnSoftware = supportInputPinOnSoftware;
|
|
65654
65190
|
exports.switchTransport = switchTransport;
|