@onekeyfe/hd-core 1.2.0-alpha.87 → 1.2.0-alpha.89

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/dist/index.js CHANGED
@@ -836,10 +836,14 @@ const buildProtocolV2Artifacts = (release, { includeComponents = true, component
836
836
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 component ${key} duplicates target ${target}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
837
837
  }
838
838
  componentTargetSet.add(target);
839
- 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({
839
+ const integrity = asIntegrity({
840
840
  size: component.expectedSize,
841
841
  sha256: component.fingerprint,
842
- })), (asVersion(component.version) ? { targetVersion: asVersion(component.version) } : {})));
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) } : {})));
843
847
  targets.push(target);
844
848
  }
845
849
  return { artifacts, targets: [...new Set(targets)] };
@@ -893,6 +897,22 @@ const finalizeFirmwareUpdatePlan = ({ features, firmwareType, platform, artifact
893
897
  };
894
898
  return assertFirmwareUpdatePlan(Object.assign(Object.assign({}, planWithoutDigest), { planDigest: digestFirmwareUpdatePlan(planWithoutDigest) }));
895
899
  };
900
+ const buildProtocolV2LocalFirmwareUpdatePlan = ({ features, firmwareType, platform, artifacts, }) => {
901
+ if (artifacts.length === 0) {
902
+ return planError('Protocol V2 local firmware plan has no artifacts');
903
+ }
904
+ const plan = finalizeFirmwareUpdatePlan({
905
+ features,
906
+ firmwareType,
907
+ platform,
908
+ artifacts: artifacts.map(artifact => (Object.assign(Object.assign({}, artifact), { role: artifact.target === 'resource' ? 'resourceBundle' : 'component', url: `https://local-firmware.invalid/${encodeURIComponent(artifact.artifactId)}` }))),
909
+ targetsToUpdate: artifacts.map(artifact => artifact.target),
910
+ });
911
+ if (plan.executor !== 'v4') {
912
+ return planError('Protocol V2 local firmware plan requires executor v4');
913
+ }
914
+ return plan;
915
+ };
896
916
  const buildProtocolV2FirmwareUpdatePlan = ({ features, firmwareType, platform, release, targetsToUpdate, forceUpdateTargets, resourceArchive, }) => {
897
917
  const validatedForceTargets = validateFirmwareUpdatePlanForceTargets(forceUpdateTargets);
898
918
  if (validatedForceTargets.some(target => target === 'ble' || target === 'bootloader')) {
@@ -51229,6 +51249,88 @@ const INSTALLABLE_FIRMWARE_TARGET_IDS = new Set([
51229
51249
  ]);
51230
51250
  new Map(Object.entries(ProtocolV2FirmwareTargetType).flatMap(([key, value]) => INSTALLABLE_FIRMWARE_TARGET_IDS.has(value) ? [[key, value]] : []));
51231
51251
 
51252
+ let memoryHostSequence = 0;
51253
+ const createReference = (binary, prefix) => {
51254
+ const digest = utils.bytesToHex(sha256.sha256(new Uint8Array(binary)));
51255
+ return {
51256
+ artifactRef: `fwmem:${prefix}:${digest.slice(0, 32)}`,
51257
+ size: binary.byteLength,
51258
+ sha256: digest,
51259
+ };
51260
+ };
51261
+ function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }) {
51262
+ if (plan.executor !== 'v4') {
51263
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory host only supports V4 plans');
51264
+ }
51265
+ memoryHostSequence += 1;
51266
+ const hostId = `${Date.now()}:${memoryHostSequence}`;
51267
+ const binaries = new Map();
51268
+ const inputs = artifacts.map((input, artifactIndex) => {
51269
+ var _a;
51270
+ const artifactBinary = new Uint8Array(input.binary).slice();
51271
+ const artifact = createReference(artifactBinary.buffer, `${hostId}:artifact:${artifactIndex}`);
51272
+ binaries.set(artifact.artifactRef, artifactBinary);
51273
+ const materializedEntries = (_a = input.materializedEntries) === null || _a === void 0 ? void 0 : _a.map((entry, entryIndex) => {
51274
+ const entryBinary = new Uint8Array(entry.binary).slice();
51275
+ const entryArtifact = createReference(entryBinary.buffer, `${hostId}:entry:${artifactIndex}:${entryIndex}`);
51276
+ binaries.set(entryArtifact.artifactRef, entryBinary);
51277
+ return {
51278
+ entryName: entry.entryName,
51279
+ artifact: entryArtifact,
51280
+ };
51281
+ });
51282
+ return Object.assign({ artifactId: input.artifactId, artifact }, ((materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length) ? { materializedEntries } : {}));
51283
+ });
51284
+ const preparedPlan = sdk.prepareFirmwareUpdatePlan({
51285
+ plan,
51286
+ leaseRef: `fwmemlease:${hostId}`,
51287
+ artifacts: inputs,
51288
+ });
51289
+ const readers = new Map();
51290
+ let readerSequence = 0;
51291
+ const artifactReader = {
51292
+ open({ artifactRef }) {
51293
+ const binary = binaries.get(artifactRef);
51294
+ if (!binary) {
51295
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory artifact is unavailable');
51296
+ }
51297
+ readerSequence += 1;
51298
+ const readerId = `fwmemreader:${hostId}:${readerSequence}`;
51299
+ readers.set(readerId, binary);
51300
+ return Promise.resolve({ readerId, size: binary.byteLength });
51301
+ },
51302
+ read({ readerId, offset, length }) {
51303
+ const binary = readers.get(readerId);
51304
+ if (!binary || offset < 0 || length <= 0 || offset + length > binary.byteLength) {
51305
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory artifact read is invalid');
51306
+ }
51307
+ const data = binary.slice(offset, offset + length).buffer;
51308
+ return Promise.resolve({
51309
+ data,
51310
+ bytesRead: data.byteLength,
51311
+ eof: offset + length === binary.byteLength,
51312
+ });
51313
+ },
51314
+ close({ readerId }) {
51315
+ readers.delete(readerId);
51316
+ return Promise.resolve();
51317
+ },
51318
+ };
51319
+ const hostBindingGeneration = sdk.registerFirmwareUpdateHostBinding({
51320
+ artifactReader,
51321
+ preparedPlanDigest: preparedPlan.preparedPlanDigest,
51322
+ });
51323
+ return {
51324
+ preparedPlan,
51325
+ hostBindingGeneration,
51326
+ release: () => {
51327
+ sdk.unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
51328
+ readers.clear();
51329
+ binaries.clear();
51330
+ },
51331
+ };
51332
+ }
51333
+
51232
51334
  const Log$6 = getLogger(exports.LoggerNames.Method);
51233
51335
  const SESSION_ERROR$1 = 'session not found';
51234
51336
  const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 90 * 1000;
@@ -51259,6 +51361,20 @@ const PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES = 1024 * 1024;
51259
51361
  const PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT = 512;
51260
51362
  const PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES = 256 * 1024 * 1024;
51261
51363
  const PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS = new Set(['se03', 'se04']);
51364
+ const getProtocolV2ZipEntrySizes = (entry) => {
51365
+ var _a;
51366
+ const { compressedSize, uncompressedSize } = (_a = entry._data) !== null && _a !== void 0 ? _a : {};
51367
+ if (!Number.isSafeInteger(compressedSize) ||
51368
+ Number(compressedSize) < 0 ||
51369
+ !Number.isSafeInteger(uncompressedSize) ||
51370
+ Number(uncompressedSize) <= 0) {
51371
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP entry size is invalid: ${entry.name}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
51372
+ }
51373
+ return {
51374
+ compressedSize: Number(compressedSize),
51375
+ uncompressedSize: Number(uncompressedSize),
51376
+ };
51377
+ };
51262
51378
  function assertProtocolV2FirmwareTargetsSupported(deviceType, params) {
51263
51379
  var _a;
51264
51380
  const unsupportedTargets = new Set(((_a = params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter(target => PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS.has(target)));
@@ -51347,6 +51463,10 @@ const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map([
51347
51463
  [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03, 'se03'],
51348
51464
  [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, 'se04'],
51349
51465
  ]);
51466
+ const PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET = new Map(Object.values(PROTOCOL_V2_REMOTE_COMPONENT_TARGETS).map(target => [
51467
+ PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId),
51468
+ target,
51469
+ ]));
51350
51470
  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.';
51351
51471
  const PROTOCOL_V2_TARGET_ID_BY_DECODED_NAME = new Map(Object.entries(ProtocolV2FirmwareTargetType).map(([key, value]) => [key, value]));
51352
51472
  const PROTOCOL_V2_TARGET_STATUS_BY_DECODED_NAME = new Map([
@@ -51511,7 +51631,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51511
51631
  return ['V2'];
51512
51632
  }
51513
51633
  init() {
51514
- var _a, _b;
51634
+ var _a, _b, _c, _d, _e;
51515
51635
  this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
51516
51636
  this.requireDeviceMode = [];
51517
51637
  this.unlockPolicy = 'unlock-before-run';
@@ -51542,6 +51662,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51542
51662
  { name: 'se02Binary', type: 'buffer' },
51543
51663
  { name: 'se03Binary', type: 'buffer' },
51544
51664
  { name: 'se04Binary', type: 'buffer' },
51665
+ { name: 'resourceArchiveBinary', type: 'buffer' },
51666
+ { name: 'resourceFiles', type: 'array', allowEmpty: true },
51667
+ { name: 'resourceBundleArtifacts', type: 'array', allowEmpty: true },
51545
51668
  { name: 'firmwareType', type: 'string' },
51546
51669
  { name: 'targetsToUpdate', type: 'array', allowEmpty: true },
51547
51670
  { name: 'platform', type: 'string' },
@@ -51551,31 +51674,65 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51551
51674
  (payload.expectedDeviceId.length === 0 || payload.expectedDeviceId.length > 160)) {
51552
51675
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 expected device identity is invalid');
51553
51676
  }
51677
+ if (((_a = payload.resourceFiles) === null || _a === void 0 ? void 0 : _a.length) || ((_b = payload.resourceBundleArtifacts) === null || _b === void 0 ? void 0 : _b.length)) {
51678
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 resourceFiles and resourceBundleArtifacts are deprecated; provide a complete signed resource ZIP through resourceArchiveBinary or preparedPlan');
51679
+ }
51554
51680
  const preparedPlan = payload.preparedPlan
51555
51681
  ? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
51556
51682
  : undefined;
51683
+ const hasLocalArtifacts = [
51684
+ payload.bootloaderBinary,
51685
+ payload.romloaderBinary,
51686
+ payload.applicationP1Binary,
51687
+ payload.applicationP2Binary,
51688
+ payload.coprocessorBinary,
51689
+ payload.se01Binary,
51690
+ payload.se02Binary,
51691
+ payload.se03Binary,
51692
+ payload.se04Binary,
51693
+ payload.resourceArchiveBinary,
51694
+ ].some(Boolean);
51695
+ if (preparedPlan && hasLocalArtifacts) {
51696
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Prepared firmware plans cannot be combined with local firmware or resource binaries');
51697
+ }
51557
51698
  const hostBinding = payload.hostBindingGeneration !== undefined
51558
51699
  ? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan === null || preparedPlan === void 0 ? void 0 : preparedPlan.preparedPlanDigest)
51559
51700
  : undefined;
51560
51701
  if (preparedPlan) {
51561
- const componentArtifacts = ((_a = payload.componentArtifacts) !== null && _a !== void 0 ? _a : {});
51562
51702
  assertFirmwareUpdatePreparedPlanBinding({
51563
51703
  preparedPlan,
51564
51704
  executor: 'v4',
51565
51705
  platform: payload.platform,
51566
- scopeTargets: ['boot', 'app_v1', 'app_v2', 'coprocessor', 'se01', 'se02', 'se03', 'se04'],
51567
- bindings: [
51568
- ...Object.entries(componentArtifacts).flatMap(([target, artifact]) => artifact
51569
- ? [
51570
- {
51571
- target: target,
51572
- artifact,
51573
- },
51574
- ]
51575
- : []),
51576
- ],
51706
+ scopeTargets: [],
51707
+ bindings: [],
51577
51708
  });
51709
+ if (payload.componentArtifacts) {
51710
+ const componentBindings = Object.entries(payload.componentArtifacts).flatMap(([target, artifact]) => artifact
51711
+ ? [
51712
+ {
51713
+ target: target,
51714
+ artifact: artifact,
51715
+ },
51716
+ ]
51717
+ : []);
51718
+ assertFirmwareUpdatePreparedPlanBinding({
51719
+ preparedPlan,
51720
+ executor: 'v4',
51721
+ platform: payload.platform,
51722
+ scopeTargets: componentBindings.map(binding => binding.target),
51723
+ bindings: componentBindings,
51724
+ });
51725
+ }
51578
51726
  }
51727
+ const preparedExpectedTargetVersions = preparedPlan === null || preparedPlan === void 0 ? void 0 : preparedPlan.artifacts.reduce((result, artifact) => {
51728
+ if (artifact.role === 'component' &&
51729
+ artifact.target !== 'resource' &&
51730
+ artifact.targetVersion &&
51731
+ PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.has(artifact.target)) {
51732
+ result[artifact.target] = artifact.targetVersion;
51733
+ }
51734
+ return result;
51735
+ }, {});
51579
51736
  this.params = {
51580
51737
  preparedPlan,
51581
51738
  chunkSize: payload.chunkSize,
@@ -51589,13 +51746,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51589
51746
  se02Binary: payload.se02Binary,
51590
51747
  se03Binary: payload.se03Binary,
51591
51748
  se04Binary: payload.se04Binary,
51592
- firmwareType: payload.firmwareType,
51593
- targetsToUpdate: payload.targetsToUpdate,
51594
- expectedTargetVersions: payload.expectedTargetVersions,
51749
+ resourceArchiveBinary: payload.resourceArchiveBinary,
51750
+ firmwareType: (_c = preparedPlan === null || preparedPlan === void 0 ? void 0 : preparedPlan.firmwareType) !== null && _c !== void 0 ? _c : payload.firmwareType,
51751
+ targetsToUpdate: preparedPlan
51752
+ ? [...preparedPlan.targetsToUpdate]
51753
+ : (_d = payload.targetsToUpdate) === null || _d === void 0 ? void 0 : _d.map((target) => target === 'boot_resources' ? 'resource' : target),
51754
+ expectedTargetVersions: preparedPlan
51755
+ ? preparedExpectedTargetVersions
51756
+ : payload.expectedTargetVersions,
51595
51757
  platform: payload.platform,
51596
51758
  expectedDeviceId: payload.expectedDeviceId,
51597
- artifactReader: (_b = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _b !== void 0 ? _b : payload.artifactReader,
51598
- componentArtifacts: payload.componentArtifacts,
51759
+ artifactReader: (_e = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _e !== void 0 ? _e : payload.artifactReader,
51760
+ componentArtifacts: preparedPlan ? undefined : payload.componentArtifacts,
51599
51761
  };
51600
51762
  }
51601
51763
  getProtocolV2FirmwareChunkSize(direction, filePath) {
@@ -51626,7 +51788,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51626
51788
  });
51627
51789
  }
51628
51790
  runProtocolV2() {
51629
- var _a, _b, _c, _d, _e;
51791
+ var _a, _b, _c, _d, _e, _f;
51630
51792
  return __awaiter(this, void 0, void 0, function* () {
51631
51793
  yield this.captureProtocolV2PhysicalIdentity();
51632
51794
  const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
@@ -51638,11 +51800,25 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51638
51800
  const deviceFirmwareType = getFirmwareType(deviceFeatures);
51639
51801
  const firmwareType = (_a = this.params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
51640
51802
  this.validateExpectedTargetVersions();
51641
- const hasPreparedComponentArtifacts = Object.values((_b = this.params.componentArtifacts) !== null && _b !== void 0 ? _b : {}).some(Boolean);
51803
+ if (!this.params.preparedPlan &&
51804
+ this.params.resourceArchiveBinary &&
51805
+ ((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource'))) {
51806
+ const localMemoryHost = yield this.prepareProtocolV2LocalMemoryHost({
51807
+ features: deviceFeatures,
51808
+ firmwareType,
51809
+ });
51810
+ try {
51811
+ return yield this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
51812
+ }
51813
+ finally {
51814
+ localMemoryHost.release();
51815
+ }
51816
+ }
51817
+ const hasPreparedComponentArtifacts = Object.values((_c = this.params.componentArtifacts) !== null && _c !== void 0 ? _c : {}).some(Boolean);
51642
51818
  if (this.params.preparedPlan || hasPreparedComponentArtifacts) {
51643
51819
  return this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
51644
51820
  }
51645
- const wantsResources = !!((_c = this.params.targetsToUpdate) === null || _c === void 0 ? void 0 : _c.includes('resource'));
51821
+ const wantsResources = !!((_d = this.params.targetsToUpdate) === null || _d === void 0 ? void 0 : _d.includes('resource'));
51646
51822
  let fwBinaryMap = [];
51647
51823
  let bootloaderBinary = null;
51648
51824
  let installItems;
@@ -51655,11 +51831,11 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51655
51831
  fwBinaryMap,
51656
51832
  });
51657
51833
  const missingFirmwareTargets = this.getMissingProtocolV2FirmwareTargets(explicitInstallItems);
51658
- const needsRemoteFirmware = ((_d = this.params.targetsToUpdate) === null || _d === void 0 ? void 0 : _d.length)
51834
+ const needsRemoteFirmware = ((_e = this.params.targetsToUpdate) === null || _e === void 0 ? void 0 : _e.length)
51659
51835
  ? missingFirmwareTargets.length > 0
51660
51836
  : explicitInstallItems.length === 0;
51661
51837
  if (wantsResources) {
51662
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource manifest must be prepared by the external firmware host', {
51838
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive must be provided through a local or external PreparedPlan', {
51663
51839
  firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
51664
51840
  });
51665
51841
  }
@@ -51685,7 +51861,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51685
51861
  if (typeof err === 'object' &&
51686
51862
  err !== null &&
51687
51863
  'params' in err &&
51688
- ((_e = err.params) === null || _e === void 0 ? void 0 : _e.firmwareUpdateCode) === 'FirmwareArtifactsNotPrepared') {
51864
+ ((_f = err.params) === null || _f === void 0 ? void 0 : _f.firmwareUpdateCode) === 'FirmwareArtifactsNotPrepared') {
51689
51865
  throw err;
51690
51866
  }
51691
51867
  if (err instanceof hdShared.HardwareError && err.errorCode === hdShared.HardwareErrorCode.NetworkError) {
@@ -51734,6 +51910,34 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51734
51910
  prepareProtocolV2InstallSources(firmwareType, features) {
51735
51911
  var _a, _b;
51736
51912
  return __awaiter(this, void 0, void 0, function* () {
51913
+ if (this.params.preparedPlan) {
51914
+ const requestedTargets = new Set(this.params.preparedPlan.targetsToUpdate.filter((target) => target !== 'resource'));
51915
+ const installSources = [];
51916
+ const preparedTargets = new Set();
51917
+ for (const artifact of this.params.preparedPlan.artifacts) {
51918
+ if (artifact.target !== 'resource') {
51919
+ const target = artifact.target;
51920
+ const installTarget = PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.get(target);
51921
+ if (!requestedTargets.has(target) ||
51922
+ artifact.role !== 'component' ||
51923
+ artifact.container !== 'raw' ||
51924
+ !installTarget ||
51925
+ preparedTargets.has(target)) {
51926
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 prepared component artifact is invalid: ${artifact.artifactId}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
51927
+ }
51928
+ installSources.push(Object.assign(Object.assign({}, installTarget), { source: yield this.openProtocolV2PreparedSource(artifact.artifact) }));
51929
+ preparedTargets.add(target);
51930
+ }
51931
+ }
51932
+ const missingTarget = Array.from(requestedTargets).find(target => !preparedTargets.has(target));
51933
+ if (missingTarget) {
51934
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 ${missingTarget} artifact is not prepared`, {
51935
+ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
51936
+ artifactName: missingTarget,
51937
+ });
51938
+ }
51939
+ return installSources;
51940
+ }
51737
51941
  const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
51738
51942
  if (!release) {
51739
51943
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware release is unavailable');
@@ -51764,6 +51968,180 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51764
51968
  return installSources;
51765
51969
  });
51766
51970
  }
51971
+ prepareProtocolV2LocalMemoryHost({ features, firmwareType, }) {
51972
+ var _a, _b;
51973
+ return __awaiter(this, void 0, void 0, function* () {
51974
+ const installItems = this.buildProtocolV2InstallItems({
51975
+ bootloaderBinary: this.prepareBootloaderBinary(),
51976
+ fwBinaryMap: this.collectExplicitTargetBinaries(),
51977
+ });
51978
+ const requestedComponentTargets = new Set(((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter((target) => target !== 'resource' && target !== 'boot_resources'));
51979
+ const localComponentTargets = new Set(installItems.flatMap(item => {
51980
+ const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
51981
+ return target ? [target] : [];
51982
+ }));
51983
+ const missingTarget = Array.from(requestedComponentTargets).find(target => !localComponentTargets.has(target));
51984
+ if (missingTarget) {
51985
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local update has no binary for requested target ${missingTarget}`, {
51986
+ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
51987
+ artifactName: missingTarget,
51988
+ });
51989
+ }
51990
+ const planArtifacts = [];
51991
+ const memoryArtifacts = [];
51992
+ for (const item of installItems) {
51993
+ const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
51994
+ if (!target || item.binary.byteLength <= 0) {
51995
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local firmware artifact is invalid: ${item.fileName}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
51996
+ }
51997
+ const artifactId = `component:${target}`;
51998
+ planArtifacts.push(Object.assign({ artifactId,
51999
+ 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])
52000
+ ? { targetVersion: this.params.expectedTargetVersions[target] }
52001
+ : {})));
52002
+ memoryArtifacts.push({ artifactId, binary: item.binary });
52003
+ }
52004
+ const resourceArchive = yield this.prepareProtocolV2LocalResourceArchive(this.params.resourceArchiveBinary);
52005
+ const resourceArtifactId = 'resource:archive';
52006
+ planArtifacts.push({
52007
+ artifactId: resourceArtifactId,
52008
+ target: 'resource',
52009
+ container: 'zip',
52010
+ logicalName: 'protocol-v2-local-resource-archive',
52011
+ expectedSize: resourceArchive.binary.byteLength,
52012
+ expectedSha256: bytesToHex(sha256.sha256(new Uint8Array(resourceArchive.binary))),
52013
+ });
52014
+ memoryArtifacts.push({
52015
+ artifactId: resourceArtifactId,
52016
+ binary: resourceArchive.binary,
52017
+ materializedEntries: resourceArchive.materializedEntries,
52018
+ });
52019
+ const plan = buildProtocolV2LocalFirmwareUpdatePlan({
52020
+ features,
52021
+ firmwareType,
52022
+ platform: this.params.platform,
52023
+ artifacts: planArtifacts,
52024
+ });
52025
+ let memoryHost;
52026
+ try {
52027
+ memoryHost = prepareFirmwareUpdateV4MemoryHost({
52028
+ sdk: {
52029
+ prepareFirmwareUpdatePlan,
52030
+ registerFirmwareUpdateHostBinding,
52031
+ unregisterFirmwareUpdateHostBinding,
52032
+ },
52033
+ plan,
52034
+ artifacts: memoryArtifacts,
52035
+ });
52036
+ const preparedPlan = validateFirmwareUpdatePreparedPlan(memoryHost.preparedPlan);
52037
+ assertFirmwareUpdatePreparedPlanBinding({
52038
+ preparedPlan,
52039
+ executor: 'v4',
52040
+ platform: this.params.platform,
52041
+ scopeTargets: [],
52042
+ bindings: [],
52043
+ });
52044
+ assertFirmwareUpdatePreparedPlanDeviceIdentity({
52045
+ preparedPlan,
52046
+ deviceIdentity: this.protocolV2ExpectedSerialNumber,
52047
+ });
52048
+ const hostBinding = resolveFirmwareUpdateHostBinding(memoryHost.hostBindingGeneration, preparedPlan.preparedPlanDigest);
52049
+ this.params.preparedPlan = preparedPlan;
52050
+ this.params.targetsToUpdate = [...preparedPlan.targetsToUpdate];
52051
+ this.params.artifactReader = hostBinding.artifactReader;
52052
+ this.params.componentArtifacts = undefined;
52053
+ return memoryHost;
52054
+ }
52055
+ catch (error) {
52056
+ memoryHost === null || memoryHost === void 0 ? void 0 : memoryHost.release();
52057
+ throw error;
52058
+ }
52059
+ });
52060
+ }
52061
+ prepareProtocolV2LocalResourceArchive(binary) {
52062
+ var _a;
52063
+ return __awaiter(this, void 0, void 0, function* () {
52064
+ if (binary.byteLength <= 0 || binary.byteLength > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
52065
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP archive size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52066
+ }
52067
+ const zip = yield JSZip__default["default"].loadAsync(binary);
52068
+ const zipEntries = Object.values(zip.files);
52069
+ if (zipEntries.some(entry => entry.unsafeOriginalName && entry.unsafeOriginalName !== entry.name)) {
52070
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unsafe entry path', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52071
+ }
52072
+ const entries = zipEntries.filter(entry => !entry.dir);
52073
+ if (entries.length === 0 || entries.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT + 1) {
52074
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP entry set is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52075
+ }
52076
+ let declaredUncompressedSize = 0;
52077
+ let declaredCompressedSize = 0;
52078
+ for (const entry of entries) {
52079
+ const sizes = getProtocolV2ZipEntrySizes(entry);
52080
+ declaredCompressedSize += sizes.compressedSize;
52081
+ declaredUncompressedSize += sizes.uncompressedSize;
52082
+ const entryLimit = entry.name === 'manifest.json'
52083
+ ? PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES
52084
+ : PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES;
52085
+ if (sizes.uncompressedSize > entryLimit ||
52086
+ declaredCompressedSize > binary.byteLength ||
52087
+ declaredUncompressedSize >
52088
+ PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES + PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
52089
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP declared size exceeds the allowed limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52090
+ }
52091
+ }
52092
+ const manifestEntry = zip.file('manifest.json');
52093
+ if (!manifestEntry) {
52094
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP has no manifest.json', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52095
+ }
52096
+ const manifestBinary = yield manifestEntry.async('arraybuffer');
52097
+ if (manifestBinary.byteLength <= 0 ||
52098
+ manifestBinary.byteLength > PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
52099
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52100
+ }
52101
+ let manifestValue;
52102
+ try {
52103
+ manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
52104
+ }
52105
+ catch (error) {
52106
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52107
+ }
52108
+ const manifest = parseProtocolV2ResourceManifest(manifestValue);
52109
+ const selectedFiles = selectProtocolV2ResourceManifestFiles({
52110
+ manifest,
52111
+ targetsToUpdate: (_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [],
52112
+ });
52113
+ const expectedEntryNames = new Set([
52114
+ 'manifest.json',
52115
+ ...selectedFiles.map(file => file.archive_path),
52116
+ ]);
52117
+ if (entries.length !== expectedEntryNames.size ||
52118
+ entries.some(entry => !expectedEntryNames.has(entry.name))) {
52119
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unexpected entry', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52120
+ }
52121
+ let totalSize = 0;
52122
+ const materializedEntries = [
52123
+ { entryName: 'manifest.json', binary: manifestBinary },
52124
+ ];
52125
+ for (const file of selectedFiles) {
52126
+ const entry = zip.file(file.archive_path);
52127
+ if (!entry) {
52128
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP is missing ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52129
+ }
52130
+ const { uncompressedSize } = getProtocolV2ZipEntrySizes(entry);
52131
+ totalSize += uncompressedSize;
52132
+ if (uncompressedSize !== file.size || totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
52133
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file declared size is invalid: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52134
+ }
52135
+ const fileBinary = yield entry.async('arraybuffer');
52136
+ const digest = bytesToHex(sha256.sha256(new Uint8Array(fileBinary)));
52137
+ if (fileBinary.byteLength !== file.size || digest !== file.sha256.toLowerCase()) {
52138
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file does not match manifest: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52139
+ }
52140
+ materializedEntries.push({ entryName: file.archive_path, binary: fileBinary });
52141
+ }
52142
+ return { binary, materializedEntries };
52143
+ });
52144
+ }
51767
52145
  prepareProtocolV2ResourceSources() {
51768
52146
  var _a, _b;
51769
52147
  return __awaiter(this, void 0, void 0, function* () {
@@ -52039,7 +52417,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52039
52417
  const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
52040
52418
  return target ? [target] : [];
52041
52419
  }));
52042
- return ((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter(target => target !== 'resource' && !preparedTargets.has(target));
52420
+ return ((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [])
52421
+ .filter((target) => target !== 'resource' && target !== 'boot_resources')
52422
+ .filter(target => !preparedTargets.has(target));
52043
52423
  }
52044
52424
  buildProtocolV2InstallItems({ bootloaderBinary, fwBinaryMap, }) {
52045
52425
  const installItems = [];
@@ -52088,7 +52468,17 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52088
52468
  if (!component.url) {
52089
52469
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Missing Protocol V2 firmware component url: ${key}/${component.target}`);
52090
52470
  }
52471
+ const expectedFingerprint = normalizeProtocolV2Hex(component.fingerprint);
52472
+ if (!Number.isSafeInteger(component.expectedSize) ||
52473
+ Number(component.expectedSize) <= 0 ||
52474
+ !expectedFingerprint ||
52475
+ !/^[0-9a-f]{64}$/u.test(expectedFingerprint)) {
52476
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware component integrity metadata is invalid: ${key}/${component.target}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
52477
+ }
52091
52478
  const { binary } = yield getSysResourceBinary(component.url);
52479
+ if (binary.byteLength !== component.expectedSize) {
52480
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware size mismatch: ${key}/${component.target}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52481
+ }
52092
52482
  if (!isProtocolV2FirmwareFingerprintValid(binary, component.fingerprint)) {
52093
52483
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware fingerprint mismatch: ${key}/${component.target}`);
52094
52484
  }
@@ -52416,7 +52806,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52416
52806
  });
52417
52807
  });
52418
52808
  }
52419
- executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, }) {
52809
+ executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, resourceBundles = [], }) {
52420
52810
  return __awaiter(this, void 0, void 0, function* () {
52421
52811
  const memoryInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
52422
52812
  fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
@@ -52431,9 +52821,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52431
52821
  kind: item.kind,
52432
52822
  });
52433
52823
  })));
52824
+ const resourceSources = yield Promise.all(resourceBundles.map((resource) => __awaiter(this, void 0, void 0, function* () {
52825
+ return (Object.assign(Object.assign(Object.assign({ name: resource.name, source: yield this.openProtocolV2MemorySource(resource.binary), devicePath: resource.devicePath }, (resource.version ? { version: resource.version } : {})), (resource.payloadHash ? { payloadHash: resource.payloadHash } : {})), (resource.headerHash ? { headerHash: resource.headerHash } : {})));
52826
+ })));
52434
52827
  return yield this.executeProtocolV2Phases({
52435
52828
  installSources,
52436
- resourceSources: [],
52829
+ resourceSources,
52437
52830
  });
52438
52831
  }
52439
52832
  finally {
@@ -65046,111 +65439,6 @@ const switchTransport = ({ env, Transport, plugin, }) => {
65046
65439
  initConnector();
65047
65440
  };
65048
65441
 
65049
- let memoryHostSequence = 0;
65050
- const FIRMWARE_UPDATE_V4_COMPONENT_TARGETS = new Set([
65051
- 'boot',
65052
- 'app_v1',
65053
- 'app_v2',
65054
- 'coprocessor',
65055
- 'se01',
65056
- 'se02',
65057
- 'se03',
65058
- 'se04',
65059
- ]);
65060
- const isFirmwareUpdateV4ComponentTarget = (target) => FIRMWARE_UPDATE_V4_COMPONENT_TARGETS.has(target);
65061
- const createReference = (binary, prefix) => {
65062
- const digest = utils.bytesToHex(sha256.sha256(new Uint8Array(binary)));
65063
- return {
65064
- artifactRef: `fwmem:${prefix}:${digest.slice(0, 32)}`,
65065
- size: binary.byteLength,
65066
- sha256: digest,
65067
- };
65068
- };
65069
- function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }) {
65070
- if (plan.executor !== 'v4') {
65071
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory host only supports V4 plans');
65072
- }
65073
- memoryHostSequence += 1;
65074
- const hostId = `${Date.now()}:${memoryHostSequence}`;
65075
- const binaries = new Map();
65076
- const inputs = artifacts.map((input, artifactIndex) => {
65077
- var _a;
65078
- const artifact = createReference(input.binary, `${hostId}:artifact:${artifactIndex}`);
65079
- binaries.set(artifact.artifactRef, new Uint8Array(input.binary));
65080
- const materializedEntries = (_a = input.materializedEntries) === null || _a === void 0 ? void 0 : _a.map((entry, entryIndex) => {
65081
- const entryArtifact = createReference(entry.binary, `${hostId}:entry:${artifactIndex}:${entryIndex}`);
65082
- binaries.set(entryArtifact.artifactRef, new Uint8Array(entry.binary));
65083
- return {
65084
- entryName: entry.entryName,
65085
- artifact: entryArtifact,
65086
- };
65087
- });
65088
- return Object.assign({ artifactId: input.artifactId, artifact }, ((materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length) ? { materializedEntries } : {}));
65089
- });
65090
- const preparedPlan = sdk.prepareFirmwareUpdatePlan({
65091
- plan,
65092
- leaseRef: `fwmemlease:${hostId}`,
65093
- artifacts: inputs,
65094
- });
65095
- const readers = new Map();
65096
- let readerSequence = 0;
65097
- const artifactReader = {
65098
- open({ artifactRef }) {
65099
- const binary = binaries.get(artifactRef);
65100
- if (!binary) {
65101
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory artifact is unavailable');
65102
- }
65103
- readerSequence += 1;
65104
- const readerId = `fwmemreader:${hostId}:${readerSequence}`;
65105
- readers.set(readerId, binary);
65106
- return Promise.resolve({ readerId, size: binary.byteLength });
65107
- },
65108
- read({ readerId, offset, length }) {
65109
- const binary = readers.get(readerId);
65110
- if (!binary || offset < 0 || length <= 0 || offset + length > binary.byteLength) {
65111
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware memory artifact read is invalid');
65112
- }
65113
- const data = binary.slice(offset, offset + length).buffer;
65114
- return Promise.resolve({
65115
- data,
65116
- bytesRead: data.byteLength,
65117
- eof: offset + length === binary.byteLength,
65118
- });
65119
- },
65120
- close({ readerId }) {
65121
- readers.delete(readerId);
65122
- return Promise.resolve();
65123
- },
65124
- };
65125
- const hostBindingGeneration = sdk.registerFirmwareUpdateHostBinding({
65126
- artifactReader,
65127
- preparedPlanDigest: preparedPlan.preparedPlanDigest,
65128
- });
65129
- const componentArtifacts = {};
65130
- const expectedTargetVersions = {};
65131
- for (const artifact of preparedPlan.artifacts) {
65132
- if (artifact.role === 'component' && isFirmwareUpdateV4ComponentTarget(artifact.target)) {
65133
- componentArtifacts[artifact.target] = artifact.artifact;
65134
- }
65135
- if (artifact.targetVersion) {
65136
- expectedTargetVersions[artifact.target] = artifact.targetVersion;
65137
- }
65138
- }
65139
- return {
65140
- preparedPlan,
65141
- hostBindingGeneration,
65142
- targetsToUpdate: [...preparedPlan.targetsToUpdate],
65143
- expectedDeviceId: preparedPlan.deviceIdentity,
65144
- expectedTargetVersions,
65145
- componentArtifacts,
65146
- release: () => {
65147
- sdk.unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
65148
- readers.clear();
65149
- binaries.clear();
65150
- },
65151
- };
65152
- }
65153
-
65154
65442
  const HardwareSdk = ({ init, call, dispose, eventEmitter, uiResponse, cancel, updateSettings, switchTransport, }) => inject({
65155
65443
  init,
65156
65444
  call,