@onekeyfe/hd-core 1.2.0-alpha.97 → 1.2.0-alpha.99

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.
Files changed (103) hide show
  1. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +411 -86
  2. package/__tests__/check-firmware-release-protocol-v2.test.ts +199 -0
  3. package/__tests__/firmware-memory-host.test.ts +126 -0
  4. package/__tests__/firmware-update/device-update-bootloader.test.ts +14 -2
  5. package/__tests__/firmware-update/firmware-host-binding.test.ts +9 -0
  6. package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +573 -0
  7. package/__tests__/firmware-update/firmware-prepared-resource-archive.test.ts +150 -0
  8. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +65 -2
  9. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +80 -0
  10. package/__tests__/firmware-update/firmware-update-plan.test.ts +293 -71
  11. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +53 -1
  12. package/__tests__/firmware-update/firmware-update-prepared-resource-executors.test.ts +326 -0
  13. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +2 -2
  14. package/__tests__/protocol-v2-firmware-targets.test.ts +16 -0
  15. package/__tests__/protocol-v2-resources.test.ts +148 -232
  16. package/__tests__/protocol-v2.test.ts +1326 -510
  17. package/dist/api/CheckAllFirmwareRelease.d.ts +2 -3
  18. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  19. package/dist/api/CheckBLEFirmwareRelease.d.ts +3 -2
  20. package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
  21. package/dist/api/CheckBootloaderRelease.d.ts +2 -1
  22. package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
  23. package/dist/api/CheckFirmwareRelease.d.ts +3 -2
  24. package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
  25. package/dist/api/FirmwareUpdateV2.d.ts +1 -0
  26. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  27. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  28. package/dist/api/FirmwareUpdateV4.d.ts +11 -9
  29. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  30. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  31. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  32. package/dist/api/firmware/FirmwareHostBinding.d.ts +1 -1
  33. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -1
  34. package/dist/api/firmware/FirmwareMemoryHost.d.ts +22 -0
  35. package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +1 -0
  36. package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts +11 -0
  37. package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts.map +1 -0
  38. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  39. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +48 -1
  40. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
  41. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +7 -1
  42. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
  43. package/dist/api/firmware/getBinary.d.ts +0 -1
  44. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  45. package/dist/api/firmware/protocolV2Release.d.ts +33 -0
  46. package/dist/api/firmware/protocolV2Release.d.ts.map +1 -0
  47. package/dist/data-manager/DataManager.d.ts +4 -3
  48. package/dist/data-manager/DataManager.d.ts.map +1 -1
  49. package/dist/index.d.ts +108 -114
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +1825 -1006
  52. package/dist/protocols/protocol-v2/resources.d.ts +10 -28
  53. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
  54. package/dist/types/api/checkAllFirmwareRelease.d.ts +20 -8
  55. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  56. package/dist/types/api/checkBLEFirmwareRelease.d.ts +2 -13
  57. package/dist/types/api/checkBLEFirmwareRelease.d.ts.map +1 -1
  58. package/dist/types/api/checkBootloaderRelease.d.ts +2 -6
  59. package/dist/types/api/checkBootloaderRelease.d.ts.map +1 -1
  60. package/dist/types/api/checkFirmwareRelease.d.ts +2 -13
  61. package/dist/types/api/checkFirmwareRelease.d.ts.map +1 -1
  62. package/dist/types/api/checkFirmwareTypeAvailable.d.ts +2 -2
  63. package/dist/types/api/checkFirmwareTypeAvailable.d.ts.map +1 -1
  64. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  65. package/dist/types/api/export.d.ts +1 -1
  66. package/dist/types/api/export.d.ts.map +1 -1
  67. package/dist/types/api/firmwareUpdate.d.ts +4 -12
  68. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  69. package/dist/types/api/firmwareUpdatePlan.d.ts +2 -2
  70. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -1
  71. package/dist/types/settings.d.ts +35 -36
  72. package/dist/types/settings.d.ts.map +1 -1
  73. package/package.json +4 -4
  74. package/src/api/CheckAllFirmwareRelease.ts +113 -80
  75. package/src/api/CheckBLEFirmwareRelease.ts +37 -5
  76. package/src/api/CheckBootloaderRelease.ts +35 -3
  77. package/src/api/CheckFirmwareRelease.ts +35 -7
  78. package/src/api/FirmwareUpdateV2.ts +231 -138
  79. package/src/api/FirmwareUpdateV3.ts +101 -56
  80. package/src/api/FirmwareUpdateV4.ts +936 -408
  81. package/src/api/UploadPortfolio.ts +18 -0
  82. package/src/api/device/DeviceUpdateBootloader.ts +37 -11
  83. package/src/api/firmware/FirmwareHostBinding.ts +26 -3
  84. package/src/api/firmware/FirmwareMemoryHost.ts +143 -0
  85. package/src/api/firmware/FirmwarePreparedResourceArchive.ts +207 -0
  86. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +122 -73
  87. package/src/api/firmware/FirmwareUpdatePlan.ts +295 -122
  88. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +49 -12
  89. package/src/api/firmware/protocolV2Release.ts +168 -0
  90. package/src/data-manager/DataManager.ts +35 -19
  91. package/src/index.ts +10 -0
  92. package/src/protocols/protocol-v2/resources.ts +157 -341
  93. package/src/types/api/checkAllFirmwareRelease.ts +27 -12
  94. package/src/types/api/checkBLEFirmwareRelease.ts +4 -13
  95. package/src/types/api/checkBootloaderRelease.ts +2 -6
  96. package/src/types/api/checkFirmwareRelease.ts +2 -13
  97. package/src/types/api/checkFirmwareTypeAvailable.ts +2 -2
  98. package/src/types/api/deviceUpdateBootloader.ts +1 -0
  99. package/src/types/api/export.ts +6 -1
  100. package/src/types/api/firmwareUpdate.ts +12 -17
  101. package/src/types/api/firmwareUpdatePlan.ts +2 -2
  102. package/src/types/settings.ts +35 -61
  103. package/src/utils/deviceFeaturesUtils.ts +2 -2
@@ -278,7 +278,14 @@ export const validateFirmwareUpdatePreparedPlan = (value: unknown): FirmwareUpda
278
278
  artifactIds.add(artifact.artifactId);
279
279
  artifactTargets.add(artifact.target);
280
280
  assertFirmwareArtifactReference(artifact.artifact);
281
- artifact.materializedEntries?.forEach(assertPreparedEntry);
281
+ const materializedEntryNames =
282
+ artifact.materializedEntries?.map(entry => {
283
+ assertPreparedEntry(entry);
284
+ return getFirmwareUpdateResourceName(entry.entryName).toLowerCase();
285
+ }) ?? [];
286
+ if (new Set(materializedEntryNames).size !== materializedEntryNames.length) {
287
+ return preparedPlanError('Firmware prepared plan contains duplicate entry names');
288
+ }
282
289
  }
283
290
  if (
284
291
  preparedPlan.targetsToUpdate.some(target => !FIRMWARE_UPDATE_PLAN_TARGETS.has(target)) ||
@@ -295,25 +302,53 @@ export const validateFirmwareUpdatePreparedPlan = (value: unknown): FirmwareUpda
295
302
  return preparedPlan;
296
303
  };
297
304
 
305
+ export const getFirmwareUpdatePreparedRawArtifact = ({
306
+ preparedPlan: value,
307
+ target,
308
+ role,
309
+ }: {
310
+ preparedPlan: unknown;
311
+ target: FirmwareUpdatePreparedArtifact['target'];
312
+ role: FirmwareUpdatePreparedArtifact['role'];
313
+ }): FirmwareUpdatePreparedArtifact => {
314
+ const preparedPlan = validateFirmwareUpdatePreparedPlan(value);
315
+ const artifacts = preparedPlan.artifacts.filter(artifact => artifact.target === target);
316
+ if (artifacts.length !== 1 || artifacts[0].role !== role || artifacts[0].container !== 'raw') {
317
+ return preparedPlanError(`Firmware prepared plan ${target} artifact is invalid`);
318
+ }
319
+ return artifacts[0];
320
+ };
321
+
298
322
  /**
299
323
  * Identity observed on the live device while a degraded recovery plan runs, keyed by
300
- * the plan's opaque lease. Bootloader recovery starts with no serial and the device
301
- * reports one only after the firmware phase reboots it, so the later phases of the
302
- * SAME workflow must be allowed to continue — but only for the device that first
303
- * answered, never for a second one that appears mid-recovery.
324
+ * the approved prepared-plan digest. Bootloader recovery starts with no serial and
325
+ * the device reports one only after the firmware phase reboots it, so the later
326
+ * phases of the SAME workflow must be allowed to continue — but only for the device
327
+ * that first answered, never for a second one that appears mid-recovery.
304
328
  */
305
329
  const degradedPlanIdentityPins = new Map<string, string>();
306
330
  /** Keep the pin map from growing without bound across many workflows. */
307
331
  const DEGRADED_PLAN_IDENTITY_PIN_LIMIT = 32;
308
332
 
309
- const pinDegradedPlanIdentity = (leaseRef: string, deviceIdentity: string) => {
310
- if (degradedPlanIdentityPins.size >= DEGRADED_PLAN_IDENTITY_PIN_LIMIT) {
333
+ const pinDegradedPlanIdentity = (preparedPlanDigest: string, deviceIdentity: string) => {
334
+ const key = preparedPlanDigest.toLowerCase();
335
+ if (
336
+ !degradedPlanIdentityPins.has(key) &&
337
+ degradedPlanIdentityPins.size >= DEGRADED_PLAN_IDENTITY_PIN_LIMIT
338
+ ) {
311
339
  const oldest = degradedPlanIdentityPins.keys().next();
312
340
  if (!oldest.done) {
313
341
  degradedPlanIdentityPins.delete(oldest.value);
314
342
  }
315
343
  }
316
- degradedPlanIdentityPins.set(leaseRef, deviceIdentity);
344
+ degradedPlanIdentityPins.set(key, deviceIdentity);
345
+ };
346
+
347
+ /** Release recovery identity state when its digest-bound host workflow ends. */
348
+ export const clearFirmwareUpdatePreparedPlanDeviceIdentityPin = (
349
+ preparedPlanDigest: string
350
+ ): void => {
351
+ degradedPlanIdentityPins.delete(preparedPlanDigest.toLowerCase());
317
352
  };
318
353
 
319
354
  export const assertFirmwareUpdatePreparedPlanDeviceIdentity = ({
@@ -340,10 +375,12 @@ export const assertFirmwareUpdatePreparedPlanDeviceIdentity = ({
340
375
  if (deviceModel === undefined || preparedPlan.deviceModel !== deviceModel) {
341
376
  throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
342
377
  }
343
- const pinnedIdentity = degradedPlanIdentityPins.get(preparedPlan.leaseRef);
378
+ const pinnedIdentity = degradedPlanIdentityPins.get(
379
+ preparedPlan.preparedPlanDigest.toLowerCase()
380
+ );
344
381
  if (!deviceIdentity) {
345
- // Still identity-less: only legitimate while the device sits in bootloader.
346
- if (bootloaderMode !== true) {
382
+ // V4 设备可能尚未写入序列号;V2 则只允许 bootloader 恢复流程缺少身份。
383
+ if (preparedPlan.executor !== 'v4' && bootloaderMode !== true) {
347
384
  throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
348
385
  }
349
386
  return preparedPlan;
@@ -351,7 +388,7 @@ export const assertFirmwareUpdatePreparedPlanDeviceIdentity = ({
351
388
  // The recovered device now reports a serial: bind this recovery to it, and hold
352
389
  // every later phase to the same one.
353
390
  if (!pinnedIdentity) {
354
- pinDegradedPlanIdentity(preparedPlan.leaseRef, deviceIdentity);
391
+ pinDegradedPlanIdentity(preparedPlan.preparedPlanDigest, deviceIdentity);
355
392
  return preparedPlan;
356
393
  }
357
394
  if (pinnedIdentity !== deviceIdentity) {
@@ -0,0 +1,168 @@
1
+ import { EFirmwareType, ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
2
+
3
+ import { DataManager } from '../../data-manager';
4
+
5
+ import type { EDeviceType } from '@onekeyfe/hd-shared';
6
+ import type { Device } from '../../device/Device';
7
+ import type {
8
+ DeviceState,
9
+ Features,
10
+ IFirmwareReleaseInfo,
11
+ IProtocolV2FirmwareComponentTarget,
12
+ } from '../../types';
13
+ import type {
14
+ FirmwareReleaseCheckResult,
15
+ ProtocolV2ComponentReleaseInfo,
16
+ ProtocolV2FirmwareReleaseStatus,
17
+ } from '../../types/api/checkAllFirmwareRelease';
18
+ import type { ProtocolV2FirmwareReleasePlan } from '../CheckAllFirmwareRelease';
19
+
20
+ export const PROTOCOL_V2_MAIN_FIRMWARE_TARGETS: readonly IProtocolV2FirmwareComponentTarget[] = [
21
+ 'APPLICATION_P1',
22
+ 'APPLICATION_P2',
23
+ 'SE01',
24
+ 'SE02',
25
+ 'SE03',
26
+ 'SE04',
27
+ ];
28
+
29
+ export const PROTOCOL_V2_BLE_TARGETS: readonly IProtocolV2FirmwareComponentTarget[] = [
30
+ 'COPROCESSOR',
31
+ ];
32
+
33
+ export const PROTOCOL_V2_BOOTLOADER_TARGETS: readonly IProtocolV2FirmwareComponentTarget[] = [
34
+ 'BOOTLOADER',
35
+ ];
36
+
37
+ export type ProtocolV2FirmwareReleaseContext = {
38
+ state: Omit<DeviceState, 'identity'> & {
39
+ identity: Omit<DeviceState['identity'], 'deviceType'> & {
40
+ deviceType: EDeviceType.Pro2 | EDeviceType.Neo;
41
+ };
42
+ };
43
+ features: Features;
44
+ firmwareType: EFirmwareType;
45
+ release: IFirmwareReleaseInfo | undefined;
46
+ };
47
+
48
+ export async function loadProtocolV2FirmwareReleaseContext({
49
+ device,
50
+ firmwareType: firmwareTypeParam,
51
+ checkFirmwareHash = false,
52
+ methodName,
53
+ }: {
54
+ device: Device;
55
+ firmwareType?: EFirmwareType;
56
+ checkFirmwareHash?: boolean;
57
+ methodName: string;
58
+ }): Promise<ProtocolV2FirmwareReleaseContext> {
59
+ const state = await device.getDeviceState({
60
+ refreshSections: checkFirmwareHash
61
+ ? ['identity', 'versions', 'verification']
62
+ : ['identity', 'versions'],
63
+ });
64
+ if (state.identity.deviceType !== 'pro2' && state.identity.deviceType !== 'neo') {
65
+ throw ERRORS.TypedError(
66
+ HardwareErrorCode.DeviceNotSupportMethod,
67
+ `${methodName} requires a Pro2 or Neo device for Protocol V2`
68
+ );
69
+ }
70
+
71
+ const { features } = device;
72
+ if (!features) {
73
+ throw ERRORS.TypedError(
74
+ HardwareErrorCode.RuntimeError,
75
+ `${methodName} requires initialized device features`
76
+ );
77
+ }
78
+
79
+ const firmwareType = firmwareTypeParam ?? state.identity.firmwareType ?? EFirmwareType.Universal;
80
+ return {
81
+ state: state as ProtocolV2FirmwareReleaseContext['state'],
82
+ features,
83
+ firmwareType,
84
+ release: DataManager.getFirmwareLatestRelease(features, firmwareType),
85
+ };
86
+ }
87
+
88
+ export function summarizeProtocolV2FirmwareRelease(
89
+ plan: ProtocolV2FirmwareReleasePlan,
90
+ componentTargets: readonly IProtocolV2FirmwareComponentTarget[]
91
+ ): ProtocolV2FirmwareReleasePlan {
92
+ const targetSet = new Set<IProtocolV2FirmwareComponentTarget>(componentTargets);
93
+ const components = plan.components.filter(component => targetSet.has(component.componentTarget));
94
+ const targetsToUpdate = Array.from(
95
+ new Set(
96
+ components.flatMap(component =>
97
+ component.status === 'outdated' && component.updateTarget ? [component.updateTarget] : []
98
+ )
99
+ )
100
+ );
101
+ const hasUpgrade = targetsToUpdate.length > 0;
102
+ const required = !!plan.release?.required && hasUpgrade;
103
+ let status: ProtocolV2FirmwareReleaseStatus = 'valid';
104
+ if (!plan.release || components.length === 0) {
105
+ status = 'unavailable';
106
+ } else if (required) {
107
+ status = 'required';
108
+ } else if (hasUpgrade) {
109
+ status = 'outdated';
110
+ } else if (components.some(component => component.status === 'unknown')) {
111
+ status = 'unknown';
112
+ } else if (components.every(component => component.status === 'unsupported')) {
113
+ status = 'unavailable';
114
+ }
115
+
116
+ return {
117
+ ...plan,
118
+ status,
119
+ hasUpgrade,
120
+ required,
121
+ components,
122
+ targetsToUpdate,
123
+ };
124
+ }
125
+
126
+ export function toProtocolV2FirmwareReleaseInfo({
127
+ plan,
128
+ state,
129
+ release,
130
+ }: {
131
+ plan: ProtocolV2FirmwareReleasePlan;
132
+ state: DeviceState;
133
+ release: FirmwareReleaseCheckResult['release'];
134
+ }): FirmwareReleaseCheckResult {
135
+ return {
136
+ shouldUpdate: plan.hasUpgrade,
137
+ status: plan.status === 'unavailable' ? 'unknown' : plan.status,
138
+ // Protocol V2 components share package-set release notes. The optional
139
+ // bootloaderChangelog field belongs to the legacy Protocol V1 release model.
140
+ changelog: plan.release ? [plan.release.changelog] : [],
141
+ release,
142
+ bootloaderMode: state.status.mode === 'bootloader' || state.status.mode === 'romloader',
143
+ };
144
+ }
145
+
146
+ export function getProtocolV2ComponentReleaseInfo(
147
+ plan: ProtocolV2FirmwareReleasePlan,
148
+ componentTarget: IProtocolV2FirmwareComponentTarget
149
+ ): ProtocolV2ComponentReleaseInfo | undefined {
150
+ const componentRelease = plan.components.find(
151
+ component => component.componentTarget === componentTarget
152
+ );
153
+ if (!componentRelease || !plan.release) {
154
+ return undefined;
155
+ }
156
+ const component = plan.release.components?.[componentRelease.configKey];
157
+ if (!component) {
158
+ return undefined;
159
+ }
160
+ return {
161
+ ...component,
162
+ protocol: 'V2',
163
+ configKey: componentRelease.configKey,
164
+ componentTarget,
165
+ required: plan.release.required,
166
+ changelog: plan.release.changelog,
167
+ };
168
+ }
@@ -94,12 +94,10 @@ export default class DataManager {
94
94
  ble: [],
95
95
  },
96
96
  [EDeviceType.Pro2]: {
97
- firmware: [],
98
- ble: [],
97
+ 'firmware-v1': [],
99
98
  },
100
99
  [EDeviceType.Neo]: {
101
- firmware: [],
102
- ble: [],
100
+ 'firmware-v1': [],
103
101
  },
104
102
  [EDeviceType.ClassicPure]: {
105
103
  firmware: [],
@@ -121,6 +119,8 @@ export default class DataManager {
121
119
 
122
120
  static protocolV2ResourcesConfigError: Error | undefined;
123
121
 
122
+ private static protocolV2NeoResourcesConfigError: Error | undefined;
123
+
124
124
  static getFirmwareStatus = (
125
125
  features: Features,
126
126
  firmwareType: EFirmwareType
@@ -410,6 +410,7 @@ export default class DataManager {
410
410
  static async load(settings: ConnectSettings): Promise<boolean> {
411
411
  this.settings = settings;
412
412
  this.protocolV2ResourcesConfigError = undefined;
413
+ this.protocolV2NeoResourcesConfigError = undefined;
413
414
  const manifestMode =
414
415
  settings.firmwareManifestMode ?? (settings.fetchConfig ? 'sdk-managed' : undefined);
415
416
  if (settings.preloadedConfig) {
@@ -476,15 +477,21 @@ export default class DataManager {
476
477
  pro2Resources = parseProtocolV2Resources(
477
478
  (data.pro2 as { resources?: unknown } | undefined)?.resources
478
479
  );
479
- neoResources = parseProtocolV2Resources(
480
- (data.neo as { resources?: unknown } | undefined)?.resources
481
- );
482
480
  } catch (error) {
483
481
  // Firmware resource metadata is not required for base communication. If the
484
482
  // remote config is temporarily incomplete, disable this resource update only.
485
483
  this.protocolV2ResourcesConfigError =
486
484
  error instanceof Error ? error : new Error(String(error));
487
- Log.warn('[DataConfig] Ignoring invalid Protocol V2 resources config:', error);
485
+ Log.warn('[DataConfig] Ignoring invalid Pro2 resources config:', error);
486
+ }
487
+ try {
488
+ neoResources = parseProtocolV2Resources(
489
+ (data.neo as { resources?: unknown } | undefined)?.resources
490
+ );
491
+ } catch (error) {
492
+ this.protocolV2NeoResourcesConfigError =
493
+ error instanceof Error ? error : new Error(String(error));
494
+ Log.warn('[DataConfig] Ignoring invalid Neo resources config:', error);
488
495
  }
489
496
  const enrichedPro2Config = this.enrichFirmwareReleaseInfo(data.pro2);
490
497
  const enrichedNeoConfig = this.enrichFirmwareReleaseInfo(data.neo);
@@ -537,7 +544,12 @@ export default class DataManager {
537
544
  /** Force a fresh remote config before an update is allowed to mutate the device. */
538
545
  static async forceReloadData({
539
546
  requireResources = false,
540
- }: { requireResources?: boolean } = {}): Promise<void> {
547
+ resourceDeviceType = EDeviceType.Pro2,
548
+ }: {
549
+ requireResources?: boolean;
550
+ resourceDeviceType?: EDeviceType.Pro2 | EDeviceType.Neo;
551
+ } = {}): Promise<void> {
552
+ const resourceDeviceName = resourceDeviceType === EDeviceType.Pro2 ? 'Pro2' : 'Neo';
541
553
  if (!this.settings) {
542
554
  throw new Error('Remote config settings are not initialized');
543
555
  }
@@ -545,10 +557,14 @@ export default class DataManager {
545
557
  this.lastCheckTimestamp > 0 &&
546
558
  getTimeStamp() - this.lastCheckTimestamp <= FIRMWARE_UPDATE_CONFIG_FRESHNESS_MS;
547
559
  if (hasFreshConfig) {
548
- if (requireResources && this.protocolV2ResourcesConfigError) {
560
+ const resourcesConfigError =
561
+ resourceDeviceType === EDeviceType.Pro2
562
+ ? this.protocolV2ResourcesConfigError
563
+ : this.protocolV2NeoResourcesConfigError;
564
+ if (requireResources && resourcesConfigError) {
549
565
  throw ERRORS.TypedError(
550
566
  HardwareErrorCode.FirmwareUpdateDownloadFailed,
551
- `Invalid Pro2 resources config: ${this.protocolV2ResourcesConfigError.message}`
567
+ `Invalid ${resourceDeviceName} resources config: ${resourcesConfigError.message}`
552
568
  );
553
569
  }
554
570
  return;
@@ -560,23 +576,23 @@ export default class DataManager {
560
576
  'Unable to refresh the latest remote config'
561
577
  );
562
578
  }
563
- if (requireResources && this.protocolV2ResourcesConfigError) {
579
+ const resourcesConfigError =
580
+ resourceDeviceType === EDeviceType.Pro2
581
+ ? this.protocolV2ResourcesConfigError
582
+ : this.protocolV2NeoResourcesConfigError;
583
+ if (requireResources && resourcesConfigError) {
564
584
  throw ERRORS.TypedError(
565
585
  HardwareErrorCode.FirmwareUpdateDownloadFailed,
566
- `Invalid Pro2 resources config: ${this.protocolV2ResourcesConfigError.message}`
586
+ `Invalid ${resourceDeviceName} resources config: ${resourcesConfigError.message}`
567
587
  );
568
588
  }
569
589
  this.lastCheckTimestamp = getTimeStamp();
570
590
  }
571
591
 
572
- static getProtocolV2Resources(deviceType: EDeviceType.Pro2 | EDeviceType.Neo = EDeviceType.Pro2) {
573
- return this.deviceMap[deviceType]?.resources?.stable;
574
- }
575
-
576
- static getProtocolV2BootResources(
592
+ static getProtocolV2ResourceSource(
577
593
  deviceType: EDeviceType.Pro2 | EDeviceType.Neo = EDeviceType.Pro2
578
594
  ) {
579
- return this.deviceMap[deviceType]?.resources?.boot;
595
+ return this.deviceMap[deviceType]?.resources?.source;
580
596
  }
581
597
 
582
598
  static getProtobufMessages(schema: ProtobufMessageSchema = 'v1CurrentSchema'): JSON {
package/src/index.ts CHANGED
@@ -21,6 +21,16 @@ export { executeCallback, cleanupCallback };
21
21
  export { preloadSessionCache } from './device/Device';
22
22
  export { projectFeatures as projectDeviceStateFeatures } from './device/DeviceStateProjector';
23
23
  export { getMethodSupportedProtocols } from './api/utils';
24
+ export {
25
+ parseProtocolV2ResourceManifest,
26
+ selectProtocolV2ResourceManifestFiles,
27
+ } from './protocols/protocol-v2/resources';
28
+ export { prepareFirmwareUpdateV4MemoryHost } from './api/firmware/FirmwareMemoryHost';
29
+ export type {
30
+ FirmwareMemoryArtifact,
31
+ FirmwareMemoryArtifactEntry,
32
+ FirmwareUpdateV4MemoryHost,
33
+ } from './api/firmware/FirmwareMemoryHost';
24
34
  export {
25
35
  getFirmwareUpdateHostBindingGeneration,
26
36
  registerFirmwareUpdateHostBinding,