@onekeyfe/hd-core 1.2.0-alpha.87 → 1.2.0-alpha.88
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__/firmware-memory-host.test.ts +5 -2
- package/__tests__/protocol-v2.test.ts +353 -0
- package/dist/api/FirmwareUpdateV4.d.ts +1 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareMemoryHost.d.ts +0 -5
- package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/index.js +170 -49
- package/dist/types/api/firmwareUpdate.d.ts +1 -0
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +276 -28
- package/src/api/firmware/FirmwareMemoryHost.ts +0 -37
- package/src/types/api/firmwareUpdate.ts +2 -0
|
@@ -90,9 +90,12 @@ describe('prepareFirmwareUpdateV4MemoryHost', () => {
|
|
|
90
90
|
expect(sdk.registerFirmwareUpdateHostBinding).toHaveBeenCalledWith(
|
|
91
91
|
expect.objectContaining({ preparedPlanDigest: host.preparedPlan.preparedPlanDigest })
|
|
92
92
|
);
|
|
93
|
-
|
|
93
|
+
const componentArtifact = host.preparedPlan.artifacts.find(
|
|
94
|
+
artifact => artifact.target === 'boot'
|
|
95
|
+
)?.artifact;
|
|
96
|
+
expect(componentArtifact?.size).toBe(componentBinary.byteLength);
|
|
94
97
|
const opened = await artifactReader!.open({
|
|
95
|
-
artifactRef:
|
|
98
|
+
artifactRef: componentArtifact!.artifactRef,
|
|
96
99
|
});
|
|
97
100
|
const chunk = await artifactReader!.read({
|
|
98
101
|
readerId: opened.readerId,
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { EFirmwareType, ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
3
|
+
import { bytesToHex } from '@noble/hashes/utils';
|
|
4
|
+
import JSZip from 'jszip';
|
|
2
5
|
import {
|
|
3
6
|
DeviceRebootType,
|
|
4
7
|
DeviceSessionPinType,
|
|
@@ -6329,6 +6332,356 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6329
6332
|
}
|
|
6330
6333
|
});
|
|
6331
6334
|
|
|
6335
|
+
test('executes a prepared component plan without duplicated component inputs', async () => {
|
|
6336
|
+
const componentBinary = new Uint8Array([1, 2, 3]).buffer;
|
|
6337
|
+
const componentArtifact = {
|
|
6338
|
+
artifactRef: 'prepared-bootloader',
|
|
6339
|
+
size: componentBinary.byteLength,
|
|
6340
|
+
sha256: 'a'.repeat(64),
|
|
6341
|
+
};
|
|
6342
|
+
const planWithoutDigest = {
|
|
6343
|
+
schemaVersion: 2 as const,
|
|
6344
|
+
executor: 'v4' as const,
|
|
6345
|
+
deviceIdentity: 'PRO2-SERIAL',
|
|
6346
|
+
deviceModel: 'pro2',
|
|
6347
|
+
firmwareType: EFirmwareType.Universal,
|
|
6348
|
+
platform: 'web' as const,
|
|
6349
|
+
targetsToUpdate: ['boot' as const],
|
|
6350
|
+
artifacts: [
|
|
6351
|
+
{
|
|
6352
|
+
artifactId: 'component:boot',
|
|
6353
|
+
role: 'component' as const,
|
|
6354
|
+
target: 'boot' as const,
|
|
6355
|
+
url: 'https://example.com/bootloader.bin',
|
|
6356
|
+
container: 'raw' as const,
|
|
6357
|
+
logicalName: 'bootloader',
|
|
6358
|
+
targetVersion: '1.2.3',
|
|
6359
|
+
},
|
|
6360
|
+
],
|
|
6361
|
+
};
|
|
6362
|
+
const preparedPlan = prepareFirmwareUpdatePlan({
|
|
6363
|
+
plan: {
|
|
6364
|
+
...planWithoutDigest,
|
|
6365
|
+
planDigest: digestFirmwareUpdateContract(planWithoutDigest),
|
|
6366
|
+
},
|
|
6367
|
+
leaseRef: 'prepared-component-test',
|
|
6368
|
+
artifacts: [{ artifactId: 'component:boot', artifact: componentArtifact }],
|
|
6369
|
+
});
|
|
6370
|
+
const artifactReader = {
|
|
6371
|
+
open: jest.fn(() =>
|
|
6372
|
+
Promise.resolve({
|
|
6373
|
+
readerId: 'prepared-component-reader',
|
|
6374
|
+
size: componentBinary.byteLength,
|
|
6375
|
+
})
|
|
6376
|
+
),
|
|
6377
|
+
read: jest.fn(({ offset, length }: { offset: number; length: number }) => {
|
|
6378
|
+
const data = componentBinary.slice(offset, offset + length);
|
|
6379
|
+
return Promise.resolve({
|
|
6380
|
+
data,
|
|
6381
|
+
bytesRead: data.byteLength,
|
|
6382
|
+
eof: offset + length === componentBinary.byteLength,
|
|
6383
|
+
});
|
|
6384
|
+
}),
|
|
6385
|
+
close: jest.fn(() => Promise.resolve()),
|
|
6386
|
+
};
|
|
6387
|
+
const hostBindingGeneration = registerFirmwareUpdateHostBinding({
|
|
6388
|
+
preparedPlanDigest: preparedPlan.preparedPlanDigest,
|
|
6389
|
+
artifactReader,
|
|
6390
|
+
});
|
|
6391
|
+
const releaseSpy = jest
|
|
6392
|
+
.spyOn(DataManager, 'getFirmwareLatestRelease')
|
|
6393
|
+
.mockReturnValue(undefined);
|
|
6394
|
+
|
|
6395
|
+
try {
|
|
6396
|
+
const method = new FirmwareUpdateV4({
|
|
6397
|
+
id: 1,
|
|
6398
|
+
payload: {
|
|
6399
|
+
method: 'firmwareUpdateV4',
|
|
6400
|
+
platform: 'web',
|
|
6401
|
+
preparedPlan,
|
|
6402
|
+
hostBindingGeneration,
|
|
6403
|
+
},
|
|
6404
|
+
});
|
|
6405
|
+
|
|
6406
|
+
expect(() => method.init()).not.toThrow();
|
|
6407
|
+
expect((method as any).params.targetsToUpdate).toEqual(['boot']);
|
|
6408
|
+
expect((method as any).params.expectedTargetVersions).toEqual({ boot: '1.2.3' });
|
|
6409
|
+
expect((method as any).params.componentArtifacts).toBeUndefined();
|
|
6410
|
+
(method as any).postTipMessage = jest.fn();
|
|
6411
|
+
(method as any).prepareProtocolV2ResourceSources = jest.fn().mockResolvedValue([]);
|
|
6412
|
+
(method as any).executeProtocolV2SourceUpdate = jest
|
|
6413
|
+
.fn()
|
|
6414
|
+
.mockResolvedValue('prepared-result');
|
|
6415
|
+
|
|
6416
|
+
await expect(
|
|
6417
|
+
(method as any).runProtocolV2PreparedArtifacts({} as Features, EFirmwareType.Universal)
|
|
6418
|
+
).resolves.toBe('prepared-result');
|
|
6419
|
+
expect(releaseSpy).not.toHaveBeenCalled();
|
|
6420
|
+
expect(artifactReader.open).toHaveBeenCalledWith({ artifactRef: 'prepared-bootloader' });
|
|
6421
|
+
expect((method as any).executeProtocolV2SourceUpdate).toHaveBeenCalledWith({
|
|
6422
|
+
installSources: [
|
|
6423
|
+
expect.objectContaining({
|
|
6424
|
+
fileName: 'bootloader.bin',
|
|
6425
|
+
kind: 'bootloader',
|
|
6426
|
+
}),
|
|
6427
|
+
],
|
|
6428
|
+
resourceSources: [],
|
|
6429
|
+
});
|
|
6430
|
+
} finally {
|
|
6431
|
+
releaseSpy.mockRestore();
|
|
6432
|
+
unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
|
|
6433
|
+
}
|
|
6434
|
+
});
|
|
6435
|
+
|
|
6436
|
+
test('executes a resource-only prepared plan without a live firmware release', async () => {
|
|
6437
|
+
const planWithoutDigest = {
|
|
6438
|
+
schemaVersion: 2 as const,
|
|
6439
|
+
executor: 'v4' as const,
|
|
6440
|
+
deviceIdentity: 'PRO2-SERIAL',
|
|
6441
|
+
deviceModel: 'pro2',
|
|
6442
|
+
firmwareType: EFirmwareType.Universal,
|
|
6443
|
+
platform: 'web' as const,
|
|
6444
|
+
targetsToUpdate: ['resource' as const],
|
|
6445
|
+
artifacts: [
|
|
6446
|
+
{
|
|
6447
|
+
artifactId: 'resource:archive',
|
|
6448
|
+
role: 'resourceBundle' as const,
|
|
6449
|
+
target: 'resource' as const,
|
|
6450
|
+
url: 'https://example.com/resource.zip',
|
|
6451
|
+
container: 'zip' as const,
|
|
6452
|
+
logicalName: 'protocol-v2-resource-archive',
|
|
6453
|
+
},
|
|
6454
|
+
],
|
|
6455
|
+
};
|
|
6456
|
+
const preparedPlan = prepareFirmwareUpdatePlan({
|
|
6457
|
+
plan: {
|
|
6458
|
+
...planWithoutDigest,
|
|
6459
|
+
planDigest: digestFirmwareUpdateContract(planWithoutDigest),
|
|
6460
|
+
},
|
|
6461
|
+
leaseRef: 'prepared-resource-only-test',
|
|
6462
|
+
artifacts: [
|
|
6463
|
+
{
|
|
6464
|
+
artifactId: 'resource:archive',
|
|
6465
|
+
artifact: {
|
|
6466
|
+
artifactRef: 'prepared-resource-archive',
|
|
6467
|
+
size: 3,
|
|
6468
|
+
sha256: 'a'.repeat(64),
|
|
6469
|
+
},
|
|
6470
|
+
materializedEntries: [
|
|
6471
|
+
{
|
|
6472
|
+
entryName: 'manifest.json',
|
|
6473
|
+
artifact: {
|
|
6474
|
+
artifactRef: 'prepared-resource-manifest',
|
|
6475
|
+
size: 2,
|
|
6476
|
+
sha256: 'b'.repeat(64),
|
|
6477
|
+
},
|
|
6478
|
+
},
|
|
6479
|
+
],
|
|
6480
|
+
},
|
|
6481
|
+
],
|
|
6482
|
+
});
|
|
6483
|
+
const hostBindingGeneration = registerFirmwareUpdateHostBinding({
|
|
6484
|
+
preparedPlanDigest: preparedPlan.preparedPlanDigest,
|
|
6485
|
+
artifactReader: {
|
|
6486
|
+
open: jest.fn(),
|
|
6487
|
+
read: jest.fn(),
|
|
6488
|
+
close: jest.fn(),
|
|
6489
|
+
},
|
|
6490
|
+
});
|
|
6491
|
+
const releaseSpy = jest
|
|
6492
|
+
.spyOn(DataManager, 'getFirmwareLatestRelease')
|
|
6493
|
+
.mockReturnValue(undefined);
|
|
6494
|
+
|
|
6495
|
+
try {
|
|
6496
|
+
const method = new FirmwareUpdateV4({
|
|
6497
|
+
id: 1,
|
|
6498
|
+
payload: {
|
|
6499
|
+
method: 'firmwareUpdateV4',
|
|
6500
|
+
platform: 'web',
|
|
6501
|
+
preparedPlan,
|
|
6502
|
+
hostBindingGeneration,
|
|
6503
|
+
},
|
|
6504
|
+
});
|
|
6505
|
+
|
|
6506
|
+
expect(() => method.init()).not.toThrow();
|
|
6507
|
+
(method as any).postTipMessage = jest.fn();
|
|
6508
|
+
const resourceSources = [{ kind: 'resource' }];
|
|
6509
|
+
(method as any).prepareProtocolV2ResourceSources = jest
|
|
6510
|
+
.fn()
|
|
6511
|
+
.mockResolvedValue(resourceSources);
|
|
6512
|
+
(method as any).executeProtocolV2SourceUpdate = jest
|
|
6513
|
+
.fn()
|
|
6514
|
+
.mockResolvedValue('resource-result');
|
|
6515
|
+
|
|
6516
|
+
await expect(
|
|
6517
|
+
(method as any).runProtocolV2PreparedArtifacts({} as Features, EFirmwareType.Universal)
|
|
6518
|
+
).resolves.toBe('resource-result');
|
|
6519
|
+
expect(releaseSpy).not.toHaveBeenCalled();
|
|
6520
|
+
expect((method as any).executeProtocolV2SourceUpdate).toHaveBeenCalledWith({
|
|
6521
|
+
installSources: [],
|
|
6522
|
+
resourceSources,
|
|
6523
|
+
});
|
|
6524
|
+
} finally {
|
|
6525
|
+
releaseSpy.mockRestore();
|
|
6526
|
+
unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
|
|
6527
|
+
}
|
|
6528
|
+
});
|
|
6529
|
+
|
|
6530
|
+
test('executes a local resource ZIP without creating or matching a remote Plan', async () => {
|
|
6531
|
+
const imagesBinary = new Uint8Array([1, 2, 3]).buffer;
|
|
6532
|
+
const bootResourceBinary = new Uint8Array([4, 5, 6]).buffer;
|
|
6533
|
+
const manifest = {
|
|
6534
|
+
schema: 1,
|
|
6535
|
+
artifact_name: 'pro2-resource',
|
|
6536
|
+
release_name: 'local-development',
|
|
6537
|
+
variant: 'resource',
|
|
6538
|
+
commit: 'local',
|
|
6539
|
+
short_sha: 'local',
|
|
6540
|
+
timestamp_utc: '2026-08-09T00:00:00Z',
|
|
6541
|
+
core_version: '1.0.0',
|
|
6542
|
+
key_set: 'development',
|
|
6543
|
+
device_root: 'vol0:',
|
|
6544
|
+
restore_mode: 'bootloader_update',
|
|
6545
|
+
trees: [{ path: 'bundles', device: 'pro2' }],
|
|
6546
|
+
files: [
|
|
6547
|
+
{
|
|
6548
|
+
archive_path: 'bundles/images/images.okpkg',
|
|
6549
|
+
original_name: 'images.okpkg',
|
|
6550
|
+
device_path: 'vol0:/bundles/images/images.okpkg',
|
|
6551
|
+
size: imagesBinary.byteLength,
|
|
6552
|
+
sha256: bytesToHex(sha256(new Uint8Array(imagesBinary))),
|
|
6553
|
+
signed: true,
|
|
6554
|
+
sig_algo: 'ed25519',
|
|
6555
|
+
payload_version: '1.0.0',
|
|
6556
|
+
},
|
|
6557
|
+
{
|
|
6558
|
+
archive_path: 'loaders/bootloader/boot_resource.okpkg',
|
|
6559
|
+
original_name: 'boot_resource.okpkg',
|
|
6560
|
+
device_path: 'vol0:/loaders/bootloader/boot_resource.okpkg',
|
|
6561
|
+
size: bootResourceBinary.byteLength,
|
|
6562
|
+
sha256: bytesToHex(sha256(new Uint8Array(bootResourceBinary))),
|
|
6563
|
+
signed: true,
|
|
6564
|
+
sig_algo: 'ed25519',
|
|
6565
|
+
payload_version: '1.0.0',
|
|
6566
|
+
},
|
|
6567
|
+
],
|
|
6568
|
+
};
|
|
6569
|
+
const zip = new JSZip();
|
|
6570
|
+
zip.file('manifest.json', JSON.stringify(manifest));
|
|
6571
|
+
zip.file('bundles/images/images.okpkg', imagesBinary);
|
|
6572
|
+
zip.file('loaders/bootloader/boot_resource.okpkg', bootResourceBinary);
|
|
6573
|
+
const resourceArchiveBinary = await zip.generateAsync({ type: 'arraybuffer' });
|
|
6574
|
+
const method = new FirmwareUpdateV4({
|
|
6575
|
+
id: 1,
|
|
6576
|
+
payload: {
|
|
6577
|
+
method: 'firmwareUpdateV4',
|
|
6578
|
+
platform: 'web',
|
|
6579
|
+
targetsToUpdate: ['resource'],
|
|
6580
|
+
resourceArchiveBinary,
|
|
6581
|
+
},
|
|
6582
|
+
});
|
|
6583
|
+
method.init();
|
|
6584
|
+
(method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
|
|
6585
|
+
(method as any).postTipMessage = jest.fn();
|
|
6586
|
+
(method as any).device = stubDevice({
|
|
6587
|
+
originalDescriptor: { protocolType: 'V2' },
|
|
6588
|
+
features: { deviceType: 'pro2', firmwareVersion: '1.0.0', capabilities: [] },
|
|
6589
|
+
getCurrentDeviceType: () => 'pro2',
|
|
6590
|
+
});
|
|
6591
|
+
(method as any).executeProtocolV2Update = jest.fn().mockResolvedValue('local-resource-result');
|
|
6592
|
+
const releaseSpy = jest.spyOn(DataManager, 'getFirmwareLatestRelease');
|
|
6593
|
+
const reloadSpy = jest.spyOn(DataManager, 'forceReloadData');
|
|
6594
|
+
|
|
6595
|
+
try {
|
|
6596
|
+
await expect(method.run()).resolves.toBe('local-resource-result');
|
|
6597
|
+
expect(releaseSpy).not.toHaveBeenCalled();
|
|
6598
|
+
expect(reloadSpy).not.toHaveBeenCalled();
|
|
6599
|
+
expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith(
|
|
6600
|
+
expect.objectContaining({
|
|
6601
|
+
resourceBundles: [
|
|
6602
|
+
expect.objectContaining({
|
|
6603
|
+
name: 'images.okpkg',
|
|
6604
|
+
binary: imagesBinary,
|
|
6605
|
+
devicePath: 'vol0:/bundles/images/images.okpkg',
|
|
6606
|
+
}),
|
|
6607
|
+
expect.objectContaining({
|
|
6608
|
+
name: 'boot_resource.okpkg',
|
|
6609
|
+
binary: bootResourceBinary,
|
|
6610
|
+
devicePath: 'vol0:/loaders/bootloader/boot_resource.okpkg',
|
|
6611
|
+
}),
|
|
6612
|
+
],
|
|
6613
|
+
})
|
|
6614
|
+
);
|
|
6615
|
+
} finally {
|
|
6616
|
+
releaseSpy.mockRestore();
|
|
6617
|
+
reloadSpy.mockRestore();
|
|
6618
|
+
}
|
|
6619
|
+
});
|
|
6620
|
+
|
|
6621
|
+
test('rejects a local resource ZIP whose file hash does not match its manifest', async () => {
|
|
6622
|
+
const resourceBinary = new Uint8Array([1, 2, 3]).buffer;
|
|
6623
|
+
const bootResourceBinary = new Uint8Array([4, 5, 6]).buffer;
|
|
6624
|
+
const zip = new JSZip();
|
|
6625
|
+
zip.file(
|
|
6626
|
+
'manifest.json',
|
|
6627
|
+
JSON.stringify({
|
|
6628
|
+
schema: 1,
|
|
6629
|
+
artifact_name: 'pro2-resource',
|
|
6630
|
+
release_name: 'local-development',
|
|
6631
|
+
variant: 'resource',
|
|
6632
|
+
commit: 'local',
|
|
6633
|
+
short_sha: 'local',
|
|
6634
|
+
timestamp_utc: '2026-08-09T00:00:00Z',
|
|
6635
|
+
core_version: '1.0.0',
|
|
6636
|
+
key_set: 'development',
|
|
6637
|
+
device_root: 'vol0:',
|
|
6638
|
+
restore_mode: 'bootloader_update',
|
|
6639
|
+
trees: [{ path: 'bundles', device: 'pro2' }],
|
|
6640
|
+
files: [
|
|
6641
|
+
{
|
|
6642
|
+
archive_path: 'bundles/images/images.okpkg',
|
|
6643
|
+
original_name: 'images.okpkg',
|
|
6644
|
+
device_path: 'vol0:/bundles/images/images.okpkg',
|
|
6645
|
+
size: resourceBinary.byteLength,
|
|
6646
|
+
sha256: '0'.repeat(64),
|
|
6647
|
+
signed: true,
|
|
6648
|
+
sig_algo: 'ed25519',
|
|
6649
|
+
payload_version: '1.0.0',
|
|
6650
|
+
},
|
|
6651
|
+
{
|
|
6652
|
+
archive_path: 'loaders/bootloader/boot_resource.okpkg',
|
|
6653
|
+
original_name: 'boot_resource.okpkg',
|
|
6654
|
+
device_path: 'vol0:/loaders/bootloader/boot_resource.okpkg',
|
|
6655
|
+
size: bootResourceBinary.byteLength,
|
|
6656
|
+
sha256: bytesToHex(sha256(new Uint8Array(bootResourceBinary))),
|
|
6657
|
+
signed: true,
|
|
6658
|
+
sig_algo: 'ed25519',
|
|
6659
|
+
payload_version: '1.0.0',
|
|
6660
|
+
},
|
|
6661
|
+
],
|
|
6662
|
+
})
|
|
6663
|
+
);
|
|
6664
|
+
zip.file('bundles/images/images.okpkg', resourceBinary);
|
|
6665
|
+
zip.file('loaders/bootloader/boot_resource.okpkg', bootResourceBinary);
|
|
6666
|
+
const method = new FirmwareUpdateV4({
|
|
6667
|
+
id: 1,
|
|
6668
|
+
payload: {
|
|
6669
|
+
method: 'firmwareUpdateV4',
|
|
6670
|
+
platform: 'web',
|
|
6671
|
+
targetsToUpdate: ['resource'],
|
|
6672
|
+
},
|
|
6673
|
+
});
|
|
6674
|
+
method.init();
|
|
6675
|
+
|
|
6676
|
+
await expect(
|
|
6677
|
+
(method as any).prepareProtocolV2LocalResourceArchive(
|
|
6678
|
+
await zip.generateAsync({ type: 'arraybuffer' })
|
|
6679
|
+
)
|
|
6680
|
+
).rejects.toThrow(
|
|
6681
|
+
'Protocol V2 local resource file does not match manifest: bundles/images/images.okpkg'
|
|
6682
|
+
);
|
|
6683
|
+
});
|
|
6684
|
+
|
|
6332
6685
|
test('keeps the legacy componentArtifacts and artifactReader path without a prepared Plan', async () => {
|
|
6333
6686
|
const artifactReader = {
|
|
6334
6687
|
open: jest.fn(),
|
|
@@ -25,6 +25,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
25
25
|
private openProtocolV2MemorySource;
|
|
26
26
|
private closeProtocolV2PreparedSources;
|
|
27
27
|
private prepareProtocolV2InstallSources;
|
|
28
|
+
private prepareProtocolV2LocalResourceArchive;
|
|
28
29
|
private prepareProtocolV2ResourceSources;
|
|
29
30
|
private prepareProtocolV2ResourceArchiveSources;
|
|
30
31
|
private runProtocolV2PreparedArtifacts;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkD,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkD,MAAM,qBAAqB,CAAC;AAyBlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AA2B/E,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AAgDrC,wBAAgB,wCAAwC,CACtD,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,EAC5C,MAAM,EAAE,sBAAsB,QAgB/B;AAqVD,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,iBACZ,MAAM,eACR,MAAM,SAsBpB,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,OAAO,CAAC,sBAAsB,CAAC,CAAS;IAExC,qBAAqB;IAIrB,OAAO,CAAC,yBAAyB,CAA4B;IAE7D,OAAO,CAAC,2BAA2B,CAAS;IAE5C,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,6BAA6B,CAAC,CAAW;IAEjD,OAAO,CAAC,6BAA6B,CAAS;IAE9C,IAAI;IAyJJ,OAAO,CAAC,8BAA8B;IAwBhC,GAAG;;;;;YAKK,aAAa;YAkHb,4BAA4B;YAkB5B,0BAA0B;YAY1B,8BAA8B;YAK9B,+BAA+B;YAqG/B,qCAAqC;YA8GrC,gCAAgC;YAgBhC,uCAAuC;YAwHvC,8BAA8B;IAsB5C,OAAO,CAAC,8BAA8B;IA0BtC,OAAO,CAAC,kCAAkC;IAc1C,OAAO,CAAC,gCAAgC;IAsDxC,OAAO,CAAC,6BAA6B;YAsBvB,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,kCAAkC;IAS1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAkBjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,mCAAmC;IAY3C,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YAmCjC,+BAA+B;IA6E7C,OAAO,CAAC,6BAA6B;YAMvB,8BAA8B;YA+C9B,kCAAkC;IA+BhD,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAc3B,6BAA6B;YAgCrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;IAkCrC,OAAO,CAAC,8BAA8B;YA8CxB,uBAAuB;YAiCvB,6BAA6B;YAa7B,uBAAuB;YA6CvB,8BAA8B;YA8D9B,6BAA6B;IAuE3C,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAyGpC,OAAO,CAAC,6BAA6B;YAcvB,uCAAuC;YA0JvC,gCAAgC;YAehC,yBAAyB;YAQzB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAkBpB,mCAAmC;YAWnC,qCAAqC;YAgDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAQ5B,cAAc;YAuCd,6BAA6B;YAW7B,0BAA0B;YAS1B,6BAA6B;YAmB7B,gBAAgB;IAiB9B,OAAO,CAAC,qBAAqB;CAM9B"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { CoreApi } from '../../types/api';
|
|
2
|
-
import type { FirmwareArtifactReference, FirmwareUpdateV4Target } from '../../types/api/firmwareUpdate';
|
|
3
2
|
import type { FirmwareUpdatePlan } from '../../types/api/firmwareUpdatePlan';
|
|
4
3
|
export type FirmwareMemoryArtifactEntry = {
|
|
5
4
|
entryName: string;
|
|
@@ -13,10 +12,6 @@ export type FirmwareMemoryArtifact = {
|
|
|
13
12
|
export type FirmwareUpdateV4MemoryHost = {
|
|
14
13
|
preparedPlan: ReturnType<CoreApi['prepareFirmwareUpdatePlan']>;
|
|
15
14
|
hostBindingGeneration: number;
|
|
16
|
-
targetsToUpdate: FirmwareUpdateV4Target[];
|
|
17
|
-
expectedDeviceId: string;
|
|
18
|
-
expectedTargetVersions: Partial<Record<FirmwareUpdateV4Target, string>>;
|
|
19
|
-
componentArtifacts: Partial<Record<Exclude<FirmwareUpdateV4Target, 'resource'>, FirmwareArtifactReference>>;
|
|
20
15
|
release: () => void;
|
|
21
16
|
};
|
|
22
17
|
export declare function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareMemoryHost.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareMemoryHost.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"FirmwareMemoryHost.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareMemoryHost.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAK/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,MAAM,MAAM,2BAA2B,GAAG;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,mBAAmB,CAAC,EAAE,2BAA2B,EAAE,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,YAAY,EAAE,UAAU,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAC/D,qBAAqB,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAaF,wBAAgB,iCAAiC,CAAC,EAChD,GAAG,EACH,IAAI,EACJ,SAAS,GACV,EAAE;IACD,GAAG,EAAE,IAAI,CACP,OAAO,EACL,2BAA2B,GAC3B,mCAAmC,GACnC,qCAAqC,CACxC,CAAC;IACF,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,sBAAsB,EAAE,CAAC;CACrC,GAAG,0BAA0B,CAoF7B"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1433,6 +1433,8 @@ interface FirmwareUpdateV4Params {
|
|
|
1433
1433
|
se02Binary?: ArrayBuffer;
|
|
1434
1434
|
se03Binary?: ArrayBuffer;
|
|
1435
1435
|
se04Binary?: ArrayBuffer;
|
|
1436
|
+
/** Complete Protocol V2 resource ZIP for local development; never bound to a remote Plan. */
|
|
1437
|
+
resourceArchiveBinary?: ArrayBuffer;
|
|
1436
1438
|
forcedUpdateRes?: boolean;
|
|
1437
1439
|
artifactReader?: FirmwareArtifactReader;
|
|
1438
1440
|
componentArtifacts?: Partial<Record<Exclude<FirmwareUpdateV4Target, 'resource'>, FirmwareArtifactReference>>;
|
|
@@ -4883,10 +4885,6 @@ type FirmwareMemoryArtifact = {
|
|
|
4883
4885
|
type FirmwareUpdateV4MemoryHost = {
|
|
4884
4886
|
preparedPlan: ReturnType<CoreApi['prepareFirmwareUpdatePlan']>;
|
|
4885
4887
|
hostBindingGeneration: number;
|
|
4886
|
-
targetsToUpdate: FirmwareUpdateV4Target[];
|
|
4887
|
-
expectedDeviceId: string;
|
|
4888
|
-
expectedTargetVersions: Partial<Record<FirmwareUpdateV4Target, string>>;
|
|
4889
|
-
componentArtifacts: Partial<Record<Exclude<FirmwareUpdateV4Target, 'resource'>, FirmwareArtifactReference>>;
|
|
4890
4888
|
release: () => void;
|
|
4891
4889
|
};
|
|
4892
4890
|
declare function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }: {
|
package/dist/index.js
CHANGED
|
@@ -51347,6 +51347,10 @@ const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map([
|
|
|
51347
51347
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03, 'se03'],
|
|
51348
51348
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, 'se04'],
|
|
51349
51349
|
]);
|
|
51350
|
+
const PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET = new Map(Object.values(PROTOCOL_V2_REMOTE_COMPONENT_TARGETS).map(target => [
|
|
51351
|
+
PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId),
|
|
51352
|
+
target,
|
|
51353
|
+
]));
|
|
51350
51354
|
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
51355
|
const PROTOCOL_V2_TARGET_ID_BY_DECODED_NAME = new Map(Object.entries(ProtocolV2FirmwareTargetType).map(([key, value]) => [key, value]));
|
|
51352
51356
|
const PROTOCOL_V2_TARGET_STATUS_BY_DECODED_NAME = new Map([
|
|
@@ -51542,6 +51546,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51542
51546
|
{ name: 'se02Binary', type: 'buffer' },
|
|
51543
51547
|
{ name: 'se03Binary', type: 'buffer' },
|
|
51544
51548
|
{ name: 'se04Binary', type: 'buffer' },
|
|
51549
|
+
{ name: 'resourceArchiveBinary', type: 'buffer' },
|
|
51545
51550
|
{ name: 'firmwareType', type: 'string' },
|
|
51546
51551
|
{ name: 'targetsToUpdate', type: 'array', allowEmpty: true },
|
|
51547
51552
|
{ name: 'platform', type: 'string' },
|
|
@@ -51554,28 +51559,59 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51554
51559
|
const preparedPlan = payload.preparedPlan
|
|
51555
51560
|
? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
|
|
51556
51561
|
: undefined;
|
|
51562
|
+
const hasLocalArtifacts = [
|
|
51563
|
+
payload.bootloaderBinary,
|
|
51564
|
+
payload.romloaderBinary,
|
|
51565
|
+
payload.applicationP1Binary,
|
|
51566
|
+
payload.applicationP2Binary,
|
|
51567
|
+
payload.coprocessorBinary,
|
|
51568
|
+
payload.se01Binary,
|
|
51569
|
+
payload.se02Binary,
|
|
51570
|
+
payload.se03Binary,
|
|
51571
|
+
payload.se04Binary,
|
|
51572
|
+
payload.resourceArchiveBinary,
|
|
51573
|
+
].some(Boolean);
|
|
51574
|
+
if (preparedPlan && hasLocalArtifacts) {
|
|
51575
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Prepared firmware plans cannot be combined with local firmware or resource binaries');
|
|
51576
|
+
}
|
|
51557
51577
|
const hostBinding = payload.hostBindingGeneration !== undefined
|
|
51558
51578
|
? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration, preparedPlan === null || preparedPlan === void 0 ? void 0 : preparedPlan.preparedPlanDigest)
|
|
51559
51579
|
: undefined;
|
|
51560
51580
|
if (preparedPlan) {
|
|
51561
|
-
const componentArtifacts = ((_a = payload.componentArtifacts) !== null && _a !== void 0 ? _a : {});
|
|
51562
51581
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
51563
51582
|
preparedPlan,
|
|
51564
51583
|
executor: 'v4',
|
|
51565
51584
|
platform: payload.platform,
|
|
51566
|
-
scopeTargets: [
|
|
51567
|
-
bindings: [
|
|
51568
|
-
...Object.entries(componentArtifacts).flatMap(([target, artifact]) => artifact
|
|
51569
|
-
? [
|
|
51570
|
-
{
|
|
51571
|
-
target: target,
|
|
51572
|
-
artifact,
|
|
51573
|
-
},
|
|
51574
|
-
]
|
|
51575
|
-
: []),
|
|
51576
|
-
],
|
|
51585
|
+
scopeTargets: [],
|
|
51586
|
+
bindings: [],
|
|
51577
51587
|
});
|
|
51588
|
+
if (payload.componentArtifacts) {
|
|
51589
|
+
const componentBindings = Object.entries(payload.componentArtifacts).flatMap(([target, artifact]) => artifact
|
|
51590
|
+
? [
|
|
51591
|
+
{
|
|
51592
|
+
target: target,
|
|
51593
|
+
artifact: artifact,
|
|
51594
|
+
},
|
|
51595
|
+
]
|
|
51596
|
+
: []);
|
|
51597
|
+
assertFirmwareUpdatePreparedPlanBinding({
|
|
51598
|
+
preparedPlan,
|
|
51599
|
+
executor: 'v4',
|
|
51600
|
+
platform: payload.platform,
|
|
51601
|
+
scopeTargets: componentBindings.map(binding => binding.target),
|
|
51602
|
+
bindings: componentBindings,
|
|
51603
|
+
});
|
|
51604
|
+
}
|
|
51578
51605
|
}
|
|
51606
|
+
const preparedExpectedTargetVersions = preparedPlan === null || preparedPlan === void 0 ? void 0 : preparedPlan.artifacts.reduce((result, artifact) => {
|
|
51607
|
+
if (artifact.role === 'component' &&
|
|
51608
|
+
artifact.target !== 'resource' &&
|
|
51609
|
+
artifact.targetVersion &&
|
|
51610
|
+
PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.has(artifact.target)) {
|
|
51611
|
+
result[artifact.target] = artifact.targetVersion;
|
|
51612
|
+
}
|
|
51613
|
+
return result;
|
|
51614
|
+
}, {});
|
|
51579
51615
|
this.params = {
|
|
51580
51616
|
preparedPlan,
|
|
51581
51617
|
chunkSize: payload.chunkSize,
|
|
@@ -51589,13 +51625,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51589
51625
|
se02Binary: payload.se02Binary,
|
|
51590
51626
|
se03Binary: payload.se03Binary,
|
|
51591
51627
|
se04Binary: payload.se04Binary,
|
|
51592
|
-
|
|
51593
|
-
|
|
51594
|
-
|
|
51628
|
+
resourceArchiveBinary: payload.resourceArchiveBinary,
|
|
51629
|
+
firmwareType: (_a = preparedPlan === null || preparedPlan === void 0 ? void 0 : preparedPlan.firmwareType) !== null && _a !== void 0 ? _a : payload.firmwareType,
|
|
51630
|
+
targetsToUpdate: preparedPlan
|
|
51631
|
+
? [...preparedPlan.targetsToUpdate]
|
|
51632
|
+
: payload.targetsToUpdate,
|
|
51633
|
+
expectedTargetVersions: preparedPlan
|
|
51634
|
+
? preparedExpectedTargetVersions
|
|
51635
|
+
: payload.expectedTargetVersions,
|
|
51595
51636
|
platform: payload.platform,
|
|
51596
51637
|
expectedDeviceId: payload.expectedDeviceId,
|
|
51597
51638
|
artifactReader: (_b = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _b !== void 0 ? _b : payload.artifactReader,
|
|
51598
|
-
componentArtifacts: payload.componentArtifacts,
|
|
51639
|
+
componentArtifacts: preparedPlan ? undefined : payload.componentArtifacts,
|
|
51599
51640
|
};
|
|
51600
51641
|
}
|
|
51601
51642
|
getProtocolV2FirmwareChunkSize(direction, filePath) {
|
|
@@ -51646,6 +51687,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51646
51687
|
let fwBinaryMap = [];
|
|
51647
51688
|
let bootloaderBinary = null;
|
|
51648
51689
|
let installItems;
|
|
51690
|
+
let resourceBundles = [];
|
|
51649
51691
|
try {
|
|
51650
51692
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
51651
51693
|
fwBinaryMap = this.collectExplicitTargetBinaries();
|
|
@@ -51659,9 +51701,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51659
51701
|
? missingFirmwareTargets.length > 0
|
|
51660
51702
|
: explicitInstallItems.length === 0;
|
|
51661
51703
|
if (wantsResources) {
|
|
51662
|
-
|
|
51663
|
-
|
|
51664
|
-
|
|
51704
|
+
if (!this.params.resourceArchiveBinary) {
|
|
51705
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive must be provided for a local resource update', {
|
|
51706
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51707
|
+
});
|
|
51708
|
+
}
|
|
51709
|
+
resourceBundles = yield this.prepareProtocolV2LocalResourceArchive(this.params.resourceArchiveBinary);
|
|
51665
51710
|
}
|
|
51666
51711
|
if (needsRemoteFirmware &&
|
|
51667
51712
|
(this.params.artifactReader ||
|
|
@@ -51693,11 +51738,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51693
51738
|
}
|
|
51694
51739
|
throw normalizeFirmwarePreparationError(err);
|
|
51695
51740
|
}
|
|
51696
|
-
if (!bootloaderBinary &&
|
|
51741
|
+
if (!bootloaderBinary &&
|
|
51742
|
+
fwBinaryMap.length === 0 &&
|
|
51743
|
+
!(installItems === null || installItems === void 0 ? void 0 : installItems.length) &&
|
|
51744
|
+
resourceBundles.length === 0) {
|
|
51697
51745
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
|
|
51698
51746
|
}
|
|
51699
|
-
return this.executeProtocolV2Update(Object.assign({ fwBinaryMap,
|
|
51700
|
-
bootloaderBinary }, (installItems ? { installItems } : undefined)));
|
|
51747
|
+
return this.executeProtocolV2Update(Object.assign(Object.assign({ fwBinaryMap,
|
|
51748
|
+
bootloaderBinary }, (installItems ? { installItems } : undefined)), (resourceBundles.length > 0 ? { resourceBundles } : undefined)));
|
|
51701
51749
|
});
|
|
51702
51750
|
}
|
|
51703
51751
|
openProtocolV2PreparedSource(artifact) {
|
|
@@ -51734,6 +51782,34 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51734
51782
|
prepareProtocolV2InstallSources(firmwareType, features) {
|
|
51735
51783
|
var _a, _b;
|
|
51736
51784
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51785
|
+
if (this.params.preparedPlan) {
|
|
51786
|
+
const requestedTargets = new Set(this.params.preparedPlan.targetsToUpdate.filter((target) => target !== 'resource'));
|
|
51787
|
+
const installSources = [];
|
|
51788
|
+
const preparedTargets = new Set();
|
|
51789
|
+
for (const artifact of this.params.preparedPlan.artifacts) {
|
|
51790
|
+
if (artifact.target !== 'resource') {
|
|
51791
|
+
const target = artifact.target;
|
|
51792
|
+
const installTarget = PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.get(target);
|
|
51793
|
+
if (!requestedTargets.has(target) ||
|
|
51794
|
+
artifact.role !== 'component' ||
|
|
51795
|
+
artifact.container !== 'raw' ||
|
|
51796
|
+
!installTarget ||
|
|
51797
|
+
preparedTargets.has(target)) {
|
|
51798
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 prepared component artifact is invalid: ${artifact.artifactId}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51799
|
+
}
|
|
51800
|
+
installSources.push(Object.assign(Object.assign({}, installTarget), { source: yield this.openProtocolV2PreparedSource(artifact.artifact) }));
|
|
51801
|
+
preparedTargets.add(target);
|
|
51802
|
+
}
|
|
51803
|
+
}
|
|
51804
|
+
const missingTarget = Array.from(requestedTargets).find(target => !preparedTargets.has(target));
|
|
51805
|
+
if (missingTarget) {
|
|
51806
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 ${missingTarget} artifact is not prepared`, {
|
|
51807
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
51808
|
+
artifactName: missingTarget,
|
|
51809
|
+
});
|
|
51810
|
+
}
|
|
51811
|
+
return installSources;
|
|
51812
|
+
}
|
|
51737
51813
|
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
51738
51814
|
if (!release) {
|
|
51739
51815
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware release is unavailable');
|
|
@@ -51764,6 +51840,73 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
51764
51840
|
return installSources;
|
|
51765
51841
|
});
|
|
51766
51842
|
}
|
|
51843
|
+
prepareProtocolV2LocalResourceArchive(binary) {
|
|
51844
|
+
var _a;
|
|
51845
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51846
|
+
const zip = yield JSZip__default["default"].loadAsync(binary);
|
|
51847
|
+
const entries = Object.values(zip.files).filter(entry => !entry.dir);
|
|
51848
|
+
if (entries.length === 0 || entries.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT + 1) {
|
|
51849
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP entry set is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51850
|
+
}
|
|
51851
|
+
const manifestEntry = zip.file('manifest.json');
|
|
51852
|
+
if (!manifestEntry) {
|
|
51853
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP has no manifest.json', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51854
|
+
}
|
|
51855
|
+
const manifestBinary = yield manifestEntry.async('arraybuffer');
|
|
51856
|
+
if (manifestBinary.byteLength <= 0 ||
|
|
51857
|
+
manifestBinary.byteLength > PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
|
|
51858
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51859
|
+
}
|
|
51860
|
+
let manifestValue;
|
|
51861
|
+
try {
|
|
51862
|
+
manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
|
|
51863
|
+
}
|
|
51864
|
+
catch (error) {
|
|
51865
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51866
|
+
}
|
|
51867
|
+
const manifest = parseProtocolV2ResourceManifest(manifestValue);
|
|
51868
|
+
const selectedFiles = selectProtocolV2ResourceManifestFiles({
|
|
51869
|
+
manifest,
|
|
51870
|
+
targetsToUpdate: (_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [],
|
|
51871
|
+
});
|
|
51872
|
+
const expectedEntryNames = new Set([
|
|
51873
|
+
'manifest.json',
|
|
51874
|
+
...selectedFiles.map(file => file.archive_path),
|
|
51875
|
+
]);
|
|
51876
|
+
if (entries.length !== expectedEntryNames.size ||
|
|
51877
|
+
entries.some(entry => !expectedEntryNames.has(entry.name))) {
|
|
51878
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unexpected entry', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51879
|
+
}
|
|
51880
|
+
let totalSize = 0;
|
|
51881
|
+
const resourceBundles = [];
|
|
51882
|
+
for (const [index, file] of selectedFiles.entries()) {
|
|
51883
|
+
const entry = zip.file(file.archive_path);
|
|
51884
|
+
if (!entry) {
|
|
51885
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP is missing ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51886
|
+
}
|
|
51887
|
+
const fileBinary = yield entry.async('arraybuffer');
|
|
51888
|
+
const digest = bytesToHex(sha256.sha256(new Uint8Array(fileBinary)));
|
|
51889
|
+
if (fileBinary.byteLength !== file.size || digest !== file.sha256.toLowerCase()) {
|
|
51890
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file does not match manifest: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
|
|
51891
|
+
}
|
|
51892
|
+
totalSize += fileBinary.byteLength;
|
|
51893
|
+
if (totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
|
|
51894
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP exceeds the total size limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
|
|
51895
|
+
}
|
|
51896
|
+
const header = fileBinary.byteLength >= PROTOCOL_V2_OKPP_HEADER_SIZE
|
|
51897
|
+
? parseProtocolV2OkppHeader(new Uint8Array(fileBinary))
|
|
51898
|
+
: null;
|
|
51899
|
+
resourceBundles.push(Object.assign({ name: file.original_name || `resource-${index}`, binary: fileBinary, devicePath: file.device_path }, (header
|
|
51900
|
+
? {
|
|
51901
|
+
version: header.version,
|
|
51902
|
+
payloadHash: header.payloadHash,
|
|
51903
|
+
headerHash: header.headerHash,
|
|
51904
|
+
}
|
|
51905
|
+
: {})));
|
|
51906
|
+
}
|
|
51907
|
+
return resourceBundles;
|
|
51908
|
+
});
|
|
51909
|
+
}
|
|
51767
51910
|
prepareProtocolV2ResourceSources() {
|
|
51768
51911
|
var _a, _b;
|
|
51769
51912
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -52416,7 +52559,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52416
52559
|
});
|
|
52417
52560
|
});
|
|
52418
52561
|
}
|
|
52419
|
-
executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, }) {
|
|
52562
|
+
executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, resourceBundles = [], }) {
|
|
52420
52563
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52421
52564
|
const memoryInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
|
|
52422
52565
|
fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
|
|
@@ -52431,9 +52574,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52431
52574
|
kind: item.kind,
|
|
52432
52575
|
});
|
|
52433
52576
|
})));
|
|
52577
|
+
const resourceSources = yield Promise.all(resourceBundles.map((resource) => __awaiter(this, void 0, void 0, function* () {
|
|
52578
|
+
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 } : {})));
|
|
52579
|
+
})));
|
|
52434
52580
|
return yield this.executeProtocolV2Phases({
|
|
52435
52581
|
installSources,
|
|
52436
|
-
resourceSources
|
|
52582
|
+
resourceSources,
|
|
52437
52583
|
});
|
|
52438
52584
|
}
|
|
52439
52585
|
finally {
|
|
@@ -65047,17 +65193,6 @@ const switchTransport = ({ env, Transport, plugin, }) => {
|
|
|
65047
65193
|
};
|
|
65048
65194
|
|
|
65049
65195
|
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
65196
|
const createReference = (binary, prefix) => {
|
|
65062
65197
|
const digest = utils.bytesToHex(sha256.sha256(new Uint8Array(binary)));
|
|
65063
65198
|
return {
|
|
@@ -65126,23 +65261,9 @@ function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }) {
|
|
|
65126
65261
|
artifactReader,
|
|
65127
65262
|
preparedPlanDigest: preparedPlan.preparedPlanDigest,
|
|
65128
65263
|
});
|
|
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
65264
|
return {
|
|
65140
65265
|
preparedPlan,
|
|
65141
65266
|
hostBindingGeneration,
|
|
65142
|
-
targetsToUpdate: [...preparedPlan.targetsToUpdate],
|
|
65143
|
-
expectedDeviceId: preparedPlan.deviceIdentity,
|
|
65144
|
-
expectedTargetVersions,
|
|
65145
|
-
componentArtifacts,
|
|
65146
65267
|
release: () => {
|
|
65147
65268
|
sdk.unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
|
|
65148
65269
|
readers.clear();
|
|
@@ -113,6 +113,7 @@ export interface FirmwareUpdateV4Params {
|
|
|
113
113
|
se02Binary?: ArrayBuffer;
|
|
114
114
|
se03Binary?: ArrayBuffer;
|
|
115
115
|
se04Binary?: ArrayBuffer;
|
|
116
|
+
resourceArchiveBinary?: ArrayBuffer;
|
|
116
117
|
forcedUpdateRes?: boolean;
|
|
117
118
|
artifactReader?: FirmwareArtifactReader;
|
|
118
119
|
componentArtifacts?: Partial<Record<Exclude<FirmwareUpdateV4Target, 'resource'>, FirmwareArtifactReference>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firmwareUpdate.d.ts","sourceRoot":"","sources":["../../../src/types/api/firmwareUpdate.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"firmwareUpdate.d.ts","sourceRoot":"","sources":["../../../src/types/api/firmwareUpdate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.88",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.88",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.88",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"bytebuffer": "^5.0.1",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@types/w3c-web-usb": "^1.0.10",
|
|
45
45
|
"@types/web-bluetooth": "^0.0.21"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "004b8385657f82848f58fd91f25bd3d12d7e33c7"
|
|
48
48
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EDeviceType, ERRORS, HardwareError, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
|
|
2
|
+
import JSZip from 'jszip';
|
|
2
3
|
import {
|
|
3
4
|
DeviceRebootType,
|
|
4
5
|
PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
|
|
@@ -178,6 +179,10 @@ type ProtocolV2ResourceBundleSource = {
|
|
|
178
179
|
headerHash?: string;
|
|
179
180
|
};
|
|
180
181
|
|
|
182
|
+
type ProtocolV2ResourceBundleBinary = Omit<ProtocolV2ResourceBundleSource, 'source'> & {
|
|
183
|
+
binary: ArrayBuffer;
|
|
184
|
+
};
|
|
185
|
+
|
|
181
186
|
type ProtocolV2ExecutionPhaseKind =
|
|
182
187
|
| 'resource-sync'
|
|
183
188
|
| 'bootloader-install'
|
|
@@ -270,6 +275,19 @@ const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map<number, FirmwareUpdateV4T
|
|
|
270
275
|
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, 'se04'],
|
|
271
276
|
]);
|
|
272
277
|
|
|
278
|
+
const PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET = new Map<
|
|
279
|
+
Exclude<FirmwareUpdateV4Target, 'resource'>,
|
|
280
|
+
ProtocolV2RemoteComponentTarget
|
|
281
|
+
>(
|
|
282
|
+
Object.values(PROTOCOL_V2_REMOTE_COMPONENT_TARGETS).map(target => [
|
|
283
|
+
PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId) as Exclude<
|
|
284
|
+
FirmwareUpdateV4Target,
|
|
285
|
+
'resource'
|
|
286
|
+
>,
|
|
287
|
+
target,
|
|
288
|
+
])
|
|
289
|
+
);
|
|
290
|
+
|
|
273
291
|
const PROTOCOL_V2_ROMLOADER_UNSUPPORTED_MESSAGE =
|
|
274
292
|
'FW_MGMT_TARGET_ROMLOADER is not accepted by the current Pro2 bootloader update request. Flash romloader with the loader-specific flow instead of firmwareUpdateV4.';
|
|
275
293
|
|
|
@@ -541,6 +559,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
541
559
|
{ name: 'se02Binary', type: 'buffer' },
|
|
542
560
|
{ name: 'se03Binary', type: 'buffer' },
|
|
543
561
|
{ name: 'se04Binary', type: 'buffer' },
|
|
562
|
+
{ name: 'resourceArchiveBinary', type: 'buffer' },
|
|
544
563
|
{ name: 'firmwareType', type: 'string' },
|
|
545
564
|
{ name: 'targetsToUpdate', type: 'array', allowEmpty: true },
|
|
546
565
|
{ name: 'platform', type: 'string' },
|
|
@@ -558,6 +577,24 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
558
577
|
const preparedPlan = payload.preparedPlan
|
|
559
578
|
? validateFirmwareUpdatePreparedPlan(payload.preparedPlan)
|
|
560
579
|
: undefined;
|
|
580
|
+
const hasLocalArtifacts = [
|
|
581
|
+
payload.bootloaderBinary,
|
|
582
|
+
payload.romloaderBinary,
|
|
583
|
+
payload.applicationP1Binary,
|
|
584
|
+
payload.applicationP2Binary,
|
|
585
|
+
payload.coprocessorBinary,
|
|
586
|
+
payload.se01Binary,
|
|
587
|
+
payload.se02Binary,
|
|
588
|
+
payload.se03Binary,
|
|
589
|
+
payload.se04Binary,
|
|
590
|
+
payload.resourceArchiveBinary,
|
|
591
|
+
].some(Boolean);
|
|
592
|
+
if (preparedPlan && hasLocalArtifacts) {
|
|
593
|
+
throw ERRORS.TypedError(
|
|
594
|
+
HardwareErrorCode.CallMethodInvalidParameter,
|
|
595
|
+
'Prepared firmware plans cannot be combined with local firmware or resource binaries'
|
|
596
|
+
);
|
|
597
|
+
}
|
|
561
598
|
const hostBinding =
|
|
562
599
|
payload.hostBindingGeneration !== undefined
|
|
563
600
|
? resolveFirmwareUpdateHostBinding(
|
|
@@ -566,29 +603,53 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
566
603
|
)
|
|
567
604
|
: undefined;
|
|
568
605
|
if (preparedPlan) {
|
|
569
|
-
const componentArtifacts = (payload.componentArtifacts ?? {}) as NonNullable<
|
|
570
|
-
FirmwareUpdateV4Params['componentArtifacts']
|
|
571
|
-
>;
|
|
572
606
|
assertFirmwareUpdatePreparedPlanBinding({
|
|
573
607
|
preparedPlan,
|
|
574
608
|
executor: 'v4',
|
|
575
609
|
platform: payload.platform,
|
|
576
|
-
scopeTargets: [
|
|
577
|
-
bindings: [
|
|
578
|
-
...Object.entries(componentArtifacts).flatMap(([target, artifact]) =>
|
|
579
|
-
artifact
|
|
580
|
-
? [
|
|
581
|
-
{
|
|
582
|
-
target: target as Exclude<FirmwareUpdateV4Target, 'resource'>,
|
|
583
|
-
artifact,
|
|
584
|
-
},
|
|
585
|
-
]
|
|
586
|
-
: []
|
|
587
|
-
),
|
|
588
|
-
],
|
|
610
|
+
scopeTargets: [],
|
|
611
|
+
bindings: [],
|
|
589
612
|
});
|
|
613
|
+
if (payload.componentArtifacts) {
|
|
614
|
+
const componentBindings: Array<{
|
|
615
|
+
target: Exclude<FirmwareUpdateV4Target, 'resource'>;
|
|
616
|
+
artifact: FirmwareArtifactReference;
|
|
617
|
+
}> = Object.entries(payload.componentArtifacts).flatMap(([target, artifact]) =>
|
|
618
|
+
artifact
|
|
619
|
+
? [
|
|
620
|
+
{
|
|
621
|
+
target: target as Exclude<FirmwareUpdateV4Target, 'resource'>,
|
|
622
|
+
artifact: artifact as FirmwareArtifactReference,
|
|
623
|
+
},
|
|
624
|
+
]
|
|
625
|
+
: []
|
|
626
|
+
);
|
|
627
|
+
assertFirmwareUpdatePreparedPlanBinding({
|
|
628
|
+
preparedPlan,
|
|
629
|
+
executor: 'v4',
|
|
630
|
+
platform: payload.platform,
|
|
631
|
+
scopeTargets: componentBindings.map(binding => binding.target),
|
|
632
|
+
bindings: componentBindings,
|
|
633
|
+
});
|
|
634
|
+
}
|
|
590
635
|
}
|
|
591
636
|
|
|
637
|
+
const preparedExpectedTargetVersions = preparedPlan?.artifacts.reduce<
|
|
638
|
+
NonNullable<FirmwareUpdateV4Params['expectedTargetVersions']>
|
|
639
|
+
>((result, artifact) => {
|
|
640
|
+
if (
|
|
641
|
+
artifact.role === 'component' &&
|
|
642
|
+
artifact.target !== 'resource' &&
|
|
643
|
+
artifact.targetVersion &&
|
|
644
|
+
PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.has(
|
|
645
|
+
artifact.target as Exclude<FirmwareUpdateV4Target, 'resource'>
|
|
646
|
+
)
|
|
647
|
+
) {
|
|
648
|
+
result[artifact.target as FirmwareUpdateV4Target] = artifact.targetVersion;
|
|
649
|
+
}
|
|
650
|
+
return result;
|
|
651
|
+
}, {});
|
|
652
|
+
|
|
592
653
|
this.params = {
|
|
593
654
|
preparedPlan,
|
|
594
655
|
chunkSize: payload.chunkSize,
|
|
@@ -602,13 +663,18 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
602
663
|
se02Binary: payload.se02Binary,
|
|
603
664
|
se03Binary: payload.se03Binary,
|
|
604
665
|
se04Binary: payload.se04Binary,
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
666
|
+
resourceArchiveBinary: payload.resourceArchiveBinary,
|
|
667
|
+
firmwareType: preparedPlan?.firmwareType ?? payload.firmwareType,
|
|
668
|
+
targetsToUpdate: preparedPlan
|
|
669
|
+
? ([...preparedPlan.targetsToUpdate] as FirmwareUpdateV4Target[])
|
|
670
|
+
: payload.targetsToUpdate,
|
|
671
|
+
expectedTargetVersions: preparedPlan
|
|
672
|
+
? preparedExpectedTargetVersions
|
|
673
|
+
: payload.expectedTargetVersions,
|
|
608
674
|
platform: payload.platform,
|
|
609
675
|
expectedDeviceId: payload.expectedDeviceId,
|
|
610
676
|
artifactReader: hostBinding?.artifactReader ?? payload.artifactReader,
|
|
611
|
-
componentArtifacts: payload.componentArtifacts,
|
|
677
|
+
componentArtifacts: preparedPlan ? undefined : payload.componentArtifacts,
|
|
612
678
|
};
|
|
613
679
|
}
|
|
614
680
|
|
|
@@ -665,6 +731,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
665
731
|
let fwBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
666
732
|
let bootloaderBinary: ArrayBuffer | null = null;
|
|
667
733
|
let installItems: ProtocolV2InstallItem[] | undefined;
|
|
734
|
+
let resourceBundles: ProtocolV2ResourceBundleBinary[] = [];
|
|
668
735
|
try {
|
|
669
736
|
this.postTipMessage(FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
670
737
|
fwBinaryMap = this.collectExplicitTargetBinaries();
|
|
@@ -678,12 +745,17 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
678
745
|
? missingFirmwareTargets.length > 0
|
|
679
746
|
: explicitInstallItems.length === 0;
|
|
680
747
|
if (wantsResources) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
748
|
+
if (!this.params.resourceArchiveBinary) {
|
|
749
|
+
throw ERRORS.TypedError(
|
|
750
|
+
HardwareErrorCode.RuntimeError,
|
|
751
|
+
'Protocol V2 resource archive must be provided for a local resource update',
|
|
752
|
+
{
|
|
753
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
754
|
+
}
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
resourceBundles = await this.prepareProtocolV2LocalResourceArchive(
|
|
758
|
+
this.params.resourceArchiveBinary
|
|
687
759
|
);
|
|
688
760
|
}
|
|
689
761
|
if (
|
|
@@ -729,7 +801,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
729
801
|
throw normalizeFirmwarePreparationError(err);
|
|
730
802
|
}
|
|
731
803
|
|
|
732
|
-
if (
|
|
804
|
+
if (
|
|
805
|
+
!bootloaderBinary &&
|
|
806
|
+
fwBinaryMap.length === 0 &&
|
|
807
|
+
!installItems?.length &&
|
|
808
|
+
resourceBundles.length === 0
|
|
809
|
+
) {
|
|
733
810
|
throw ERRORS.TypedError(
|
|
734
811
|
HardwareErrorCode.FirmwareUpdateDownloadFailed,
|
|
735
812
|
'No firmware to update'
|
|
@@ -740,6 +817,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
740
817
|
fwBinaryMap,
|
|
741
818
|
bootloaderBinary,
|
|
742
819
|
...(installItems ? { installItems } : undefined),
|
|
820
|
+
...(resourceBundles.length > 0 ? { resourceBundles } : undefined),
|
|
743
821
|
});
|
|
744
822
|
}
|
|
745
823
|
|
|
@@ -782,6 +860,54 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
782
860
|
firmwareType: EFirmwareType,
|
|
783
861
|
features: Features
|
|
784
862
|
): Promise<ProtocolV2InstallSource[]> {
|
|
863
|
+
if (this.params.preparedPlan) {
|
|
864
|
+
const requestedTargets = new Set(
|
|
865
|
+
this.params.preparedPlan.targetsToUpdate.filter(
|
|
866
|
+
(target): target is Exclude<FirmwareUpdateV4Target, 'resource'> => target !== 'resource'
|
|
867
|
+
)
|
|
868
|
+
);
|
|
869
|
+
const installSources: ProtocolV2InstallSource[] = [];
|
|
870
|
+
const preparedTargets = new Set<Exclude<FirmwareUpdateV4Target, 'resource'>>();
|
|
871
|
+
for (const artifact of this.params.preparedPlan.artifacts) {
|
|
872
|
+
if (artifact.target !== 'resource') {
|
|
873
|
+
const target = artifact.target as Exclude<FirmwareUpdateV4Target, 'resource'>;
|
|
874
|
+
const installTarget = PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.get(target);
|
|
875
|
+
if (
|
|
876
|
+
!requestedTargets.has(target) ||
|
|
877
|
+
artifact.role !== 'component' ||
|
|
878
|
+
artifact.container !== 'raw' ||
|
|
879
|
+
!installTarget ||
|
|
880
|
+
preparedTargets.has(target)
|
|
881
|
+
) {
|
|
882
|
+
throw ERRORS.TypedError(
|
|
883
|
+
HardwareErrorCode.RuntimeError,
|
|
884
|
+
`Protocol V2 prepared component artifact is invalid: ${artifact.artifactId}`,
|
|
885
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
installSources.push({
|
|
889
|
+
...installTarget,
|
|
890
|
+
source: await this.openProtocolV2PreparedSource(artifact.artifact),
|
|
891
|
+
});
|
|
892
|
+
preparedTargets.add(target);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
const missingTarget = Array.from(requestedTargets).find(
|
|
896
|
+
target => !preparedTargets.has(target)
|
|
897
|
+
);
|
|
898
|
+
if (missingTarget) {
|
|
899
|
+
throw ERRORS.TypedError(
|
|
900
|
+
HardwareErrorCode.RuntimeError,
|
|
901
|
+
`Protocol V2 ${missingTarget} artifact is not prepared`,
|
|
902
|
+
{
|
|
903
|
+
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
904
|
+
artifactName: missingTarget,
|
|
905
|
+
}
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
return installSources;
|
|
909
|
+
}
|
|
910
|
+
|
|
785
911
|
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
786
912
|
if (!release) {
|
|
787
913
|
throw ERRORS.TypedError(
|
|
@@ -831,6 +957,116 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
831
957
|
return installSources;
|
|
832
958
|
}
|
|
833
959
|
|
|
960
|
+
private async prepareProtocolV2LocalResourceArchive(
|
|
961
|
+
binary: ArrayBuffer
|
|
962
|
+
): Promise<ProtocolV2ResourceBundleBinary[]> {
|
|
963
|
+
const zip = await JSZip.loadAsync(binary);
|
|
964
|
+
const entries = Object.values(zip.files).filter(entry => !entry.dir);
|
|
965
|
+
if (entries.length === 0 || entries.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT + 1) {
|
|
966
|
+
throw ERRORS.TypedError(
|
|
967
|
+
HardwareErrorCode.RuntimeError,
|
|
968
|
+
'Protocol V2 local resource ZIP entry set is invalid',
|
|
969
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
970
|
+
);
|
|
971
|
+
}
|
|
972
|
+
const manifestEntry = zip.file('manifest.json');
|
|
973
|
+
if (!manifestEntry) {
|
|
974
|
+
throw ERRORS.TypedError(
|
|
975
|
+
HardwareErrorCode.RuntimeError,
|
|
976
|
+
'Protocol V2 local resource ZIP has no manifest.json',
|
|
977
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
const manifestBinary = await manifestEntry.async('arraybuffer');
|
|
981
|
+
if (
|
|
982
|
+
manifestBinary.byteLength <= 0 ||
|
|
983
|
+
manifestBinary.byteLength > PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES
|
|
984
|
+
) {
|
|
985
|
+
throw ERRORS.TypedError(
|
|
986
|
+
HardwareErrorCode.RuntimeError,
|
|
987
|
+
'Protocol V2 local resource manifest size is invalid',
|
|
988
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
let manifestValue: unknown;
|
|
993
|
+
try {
|
|
994
|
+
manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
|
|
995
|
+
} catch (error) {
|
|
996
|
+
throw ERRORS.TypedError(
|
|
997
|
+
HardwareErrorCode.RuntimeError,
|
|
998
|
+
`Protocol V2 local resource manifest is invalid: ${String(error)}`,
|
|
999
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
const manifest = parseProtocolV2ResourceManifest(manifestValue);
|
|
1003
|
+
const selectedFiles = selectProtocolV2ResourceManifestFiles({
|
|
1004
|
+
manifest,
|
|
1005
|
+
targetsToUpdate: this.params.targetsToUpdate ?? [],
|
|
1006
|
+
});
|
|
1007
|
+
const expectedEntryNames = new Set([
|
|
1008
|
+
'manifest.json',
|
|
1009
|
+
...selectedFiles.map(file => file.archive_path),
|
|
1010
|
+
]);
|
|
1011
|
+
if (
|
|
1012
|
+
entries.length !== expectedEntryNames.size ||
|
|
1013
|
+
entries.some(entry => !expectedEntryNames.has(entry.name))
|
|
1014
|
+
) {
|
|
1015
|
+
throw ERRORS.TypedError(
|
|
1016
|
+
HardwareErrorCode.RuntimeError,
|
|
1017
|
+
'Protocol V2 local resource ZIP contains an unexpected entry',
|
|
1018
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
1019
|
+
);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
let totalSize = 0;
|
|
1023
|
+
const resourceBundles: ProtocolV2ResourceBundleBinary[] = [];
|
|
1024
|
+
for (const [index, file] of selectedFiles.entries()) {
|
|
1025
|
+
const entry = zip.file(file.archive_path);
|
|
1026
|
+
if (!entry) {
|
|
1027
|
+
throw ERRORS.TypedError(
|
|
1028
|
+
HardwareErrorCode.RuntimeError,
|
|
1029
|
+
`Protocol V2 local resource ZIP is missing ${file.archive_path}`,
|
|
1030
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
1033
|
+
const fileBinary = await entry.async('arraybuffer');
|
|
1034
|
+
const digest = bytesToHex(sha256(new Uint8Array(fileBinary)));
|
|
1035
|
+
if (fileBinary.byteLength !== file.size || digest !== file.sha256.toLowerCase()) {
|
|
1036
|
+
throw ERRORS.TypedError(
|
|
1037
|
+
HardwareErrorCode.RuntimeError,
|
|
1038
|
+
`Protocol V2 local resource file does not match manifest: ${file.archive_path}`,
|
|
1039
|
+
{ firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' }
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
totalSize += fileBinary.byteLength;
|
|
1043
|
+
if (totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
|
|
1044
|
+
throw ERRORS.TypedError(
|
|
1045
|
+
HardwareErrorCode.RuntimeError,
|
|
1046
|
+
'Protocol V2 local resource ZIP exceeds the total size limit',
|
|
1047
|
+
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
1048
|
+
);
|
|
1049
|
+
}
|
|
1050
|
+
const header =
|
|
1051
|
+
fileBinary.byteLength >= PROTOCOL_V2_OKPP_HEADER_SIZE
|
|
1052
|
+
? parseProtocolV2OkppHeader(new Uint8Array(fileBinary))
|
|
1053
|
+
: null;
|
|
1054
|
+
resourceBundles.push({
|
|
1055
|
+
name: file.original_name || `resource-${index}`,
|
|
1056
|
+
binary: fileBinary,
|
|
1057
|
+
devicePath: file.device_path,
|
|
1058
|
+
...(header
|
|
1059
|
+
? {
|
|
1060
|
+
version: header.version,
|
|
1061
|
+
payloadHash: header.payloadHash,
|
|
1062
|
+
headerHash: header.headerHash,
|
|
1063
|
+
}
|
|
1064
|
+
: {}),
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
return resourceBundles;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
834
1070
|
private async prepareProtocolV2ResourceSources(): Promise<ProtocolV2ResourceBundleSource[]> {
|
|
835
1071
|
const resourceRequested = this.params.targetsToUpdate?.includes('resource') ?? false;
|
|
836
1072
|
if (!resourceRequested) {
|
|
@@ -1672,10 +1908,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1672
1908
|
fwBinaryMap,
|
|
1673
1909
|
bootloaderBinary,
|
|
1674
1910
|
installItems,
|
|
1911
|
+
resourceBundles = [],
|
|
1675
1912
|
}: {
|
|
1676
1913
|
fwBinaryMap?: ProtocolV2TargetBinary[];
|
|
1677
1914
|
bootloaderBinary?: ArrayBuffer | null;
|
|
1678
1915
|
installItems?: ProtocolV2InstallItem[];
|
|
1916
|
+
resourceBundles?: ProtocolV2ResourceBundleBinary[];
|
|
1679
1917
|
}) {
|
|
1680
1918
|
const memoryInstallItems =
|
|
1681
1919
|
installItems ??
|
|
@@ -1692,9 +1930,19 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1692
1930
|
kind: item.kind,
|
|
1693
1931
|
}))
|
|
1694
1932
|
);
|
|
1933
|
+
const resourceSources = await Promise.all(
|
|
1934
|
+
resourceBundles.map(async resource => ({
|
|
1935
|
+
name: resource.name,
|
|
1936
|
+
source: await this.openProtocolV2MemorySource(resource.binary),
|
|
1937
|
+
devicePath: resource.devicePath,
|
|
1938
|
+
...(resource.version ? { version: resource.version } : {}),
|
|
1939
|
+
...(resource.payloadHash ? { payloadHash: resource.payloadHash } : {}),
|
|
1940
|
+
...(resource.headerHash ? { headerHash: resource.headerHash } : {}),
|
|
1941
|
+
}))
|
|
1942
|
+
);
|
|
1695
1943
|
return await this.executeProtocolV2Phases({
|
|
1696
1944
|
installSources,
|
|
1697
|
-
resourceSources
|
|
1945
|
+
resourceSources,
|
|
1698
1946
|
});
|
|
1699
1947
|
} finally {
|
|
1700
1948
|
await this.closeProtocolV2PreparedSources();
|
|
@@ -6,7 +6,6 @@ import type { CoreApi } from '../../types/api';
|
|
|
6
6
|
import type {
|
|
7
7
|
FirmwareArtifactReader,
|
|
8
8
|
FirmwareArtifactReference,
|
|
9
|
-
FirmwareUpdateV4Target,
|
|
10
9
|
} from '../../types/api/firmwareUpdate';
|
|
11
10
|
import type { FirmwareUpdatePlan } from '../../types/api/firmwareUpdatePlan';
|
|
12
11
|
|
|
@@ -24,33 +23,11 @@ export type FirmwareMemoryArtifact = {
|
|
|
24
23
|
export type FirmwareUpdateV4MemoryHost = {
|
|
25
24
|
preparedPlan: ReturnType<CoreApi['prepareFirmwareUpdatePlan']>;
|
|
26
25
|
hostBindingGeneration: number;
|
|
27
|
-
targetsToUpdate: FirmwareUpdateV4Target[];
|
|
28
|
-
expectedDeviceId: string;
|
|
29
|
-
expectedTargetVersions: Partial<Record<FirmwareUpdateV4Target, string>>;
|
|
30
|
-
componentArtifacts: Partial<
|
|
31
|
-
Record<Exclude<FirmwareUpdateV4Target, 'resource'>, FirmwareArtifactReference>
|
|
32
|
-
>;
|
|
33
26
|
release: () => void;
|
|
34
27
|
};
|
|
35
28
|
|
|
36
29
|
let memoryHostSequence = 0;
|
|
37
30
|
|
|
38
|
-
const FIRMWARE_UPDATE_V4_COMPONENT_TARGETS = new Set<Exclude<FirmwareUpdateV4Target, 'resource'>>([
|
|
39
|
-
'boot',
|
|
40
|
-
'app_v1',
|
|
41
|
-
'app_v2',
|
|
42
|
-
'coprocessor',
|
|
43
|
-
'se01',
|
|
44
|
-
'se02',
|
|
45
|
-
'se03',
|
|
46
|
-
'se04',
|
|
47
|
-
]);
|
|
48
|
-
|
|
49
|
-
const isFirmwareUpdateV4ComponentTarget = (
|
|
50
|
-
target: string
|
|
51
|
-
): target is Exclude<FirmwareUpdateV4Target, 'resource'> =>
|
|
52
|
-
FIRMWARE_UPDATE_V4_COMPONENT_TARGETS.has(target as Exclude<FirmwareUpdateV4Target, 'resource'>);
|
|
53
|
-
|
|
54
31
|
const createReference = (binary: ArrayBuffer, prefix: string): FirmwareArtifactReference => {
|
|
55
32
|
const digest = bytesToHex(sha256(new Uint8Array(binary)));
|
|
56
33
|
return {
|
|
@@ -148,23 +125,9 @@ export function prepareFirmwareUpdateV4MemoryHost({
|
|
|
148
125
|
artifactReader,
|
|
149
126
|
preparedPlanDigest: preparedPlan.preparedPlanDigest,
|
|
150
127
|
});
|
|
151
|
-
const componentArtifacts: FirmwareUpdateV4MemoryHost['componentArtifacts'] = {};
|
|
152
|
-
const expectedTargetVersions: FirmwareUpdateV4MemoryHost['expectedTargetVersions'] = {};
|
|
153
|
-
for (const artifact of preparedPlan.artifacts) {
|
|
154
|
-
if (artifact.role === 'component' && isFirmwareUpdateV4ComponentTarget(artifact.target)) {
|
|
155
|
-
componentArtifacts[artifact.target] = artifact.artifact;
|
|
156
|
-
}
|
|
157
|
-
if (artifact.targetVersion) {
|
|
158
|
-
expectedTargetVersions[artifact.target as FirmwareUpdateV4Target] = artifact.targetVersion;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
128
|
return {
|
|
162
129
|
preparedPlan,
|
|
163
130
|
hostBindingGeneration,
|
|
164
|
-
targetsToUpdate: [...preparedPlan.targetsToUpdate] as FirmwareUpdateV4Target[],
|
|
165
|
-
expectedDeviceId: preparedPlan.deviceIdentity,
|
|
166
|
-
expectedTargetVersions,
|
|
167
|
-
componentArtifacts,
|
|
168
131
|
release: () => {
|
|
169
132
|
sdk.unregisterFirmwareUpdateHostBinding(hostBindingGeneration);
|
|
170
133
|
readers.clear();
|
|
@@ -154,6 +154,8 @@ export interface FirmwareUpdateV4Params {
|
|
|
154
154
|
se02Binary?: ArrayBuffer;
|
|
155
155
|
se03Binary?: ArrayBuffer;
|
|
156
156
|
se04Binary?: ArrayBuffer;
|
|
157
|
+
/** Complete Protocol V2 resource ZIP for local development; never bound to a remote Plan. */
|
|
158
|
+
resourceArchiveBinary?: ArrayBuffer;
|
|
157
159
|
forcedUpdateRes?: boolean;
|
|
158
160
|
artifactReader?: FirmwareArtifactReader;
|
|
159
161
|
componentArtifacts?: Partial<
|