@onekeyfe/hd-core 1.2.0-alpha.68 → 1.2.0-alpha.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +28 -0
- package/__tests__/connectSettings.test.ts +5 -47
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
- package/__tests__/protocol-v2-firmware-targets.test.ts +33 -1
- package/__tests__/protocol-v2-resources.test.ts +9 -6
- package/__tests__/protocol-v2.test.ts +174 -383
- package/__tests__/protocolV2FileWrite.test.ts +48 -7
- package/dist/api/CheckAllFirmwareRelease.d.ts +2 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +0 -10
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +3 -7
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +6 -25
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -8
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +0 -7
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/updateBootloader.d.ts +0 -2
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +1 -9
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/data-manager/DataManager.d.ts +0 -1
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +0 -1
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/index.d.ts +2 -180
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1041 -3037
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/resources.d.ts +1 -1
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +0 -4
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +1 -4
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +0 -68
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +1 -9
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/settings.d.ts +1 -14
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +0 -1
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +25 -61
- package/src/api/FirmwareUpdate.ts +1 -13
- package/src/api/FirmwareUpdateV2.ts +121 -296
- package/src/api/FirmwareUpdateV3.ts +57 -263
- package/src/api/FirmwareUpdateV4.ts +287 -865
- package/src/api/device/DeviceUpdateBootloader.ts +6 -125
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +1 -72
- package/src/api/firmware/updateBootloader.ts +4 -19
- package/src/api/firmware/uploadFirmware.ts +22 -140
- package/src/api/helpers/protocolV2FileWrite.ts +54 -4
- package/src/data-manager/DataManager.ts +54 -59
- package/src/data-manager/connectSettings.ts +0 -11
- package/src/device/Device.ts +1 -6
- package/src/index.ts +0 -5
- package/src/inject.ts +2 -22
- package/src/lowLevelInject.ts +1 -5
- package/src/protocols/protocol-v2/resources.ts +5 -1
- package/src/topLevelInject.ts +1 -5
- package/src/types/api/checkAllFirmwareRelease.ts +0 -4
- package/src/types/api/deviceUpdateBootloader.ts +0 -6
- package/src/types/api/export.ts +0 -18
- package/src/types/api/firmwareUpdate.ts +0 -75
- package/src/types/api/index.ts +0 -14
- package/src/types/settings.ts +2 -14
- package/src/utils/deviceFeaturesCompat.ts +0 -6
- package/__tests__/device-initialize-timeout.test.ts +0 -56
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
- package/__tests__/firmware-update/device-update-bootloader.test.ts +0 -87
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
- package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
- package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +0 -200
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +0 -394
- package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -231
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -63
- package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
- package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
- package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -32
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
- package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
- package/src/api/firmware/FirmwareHostBinding.ts +0 -100
- package/src/api/firmware/FirmwarePreparationError.ts +0 -12
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
- package/src/api/firmware/FirmwareUpdatePlan.ts +0 -772
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -449
- package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
- package/src/types/api/firmwareUpdatePlan.ts +0 -38
- package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
|
@@ -35,7 +35,10 @@ import ProtocolInfoRequest from '../src/api/protocol-v2/ProtocolInfoRequest';
|
|
|
35
35
|
import EVMSignTypedData from '../src/api/evm/EVMSignTypedData';
|
|
36
36
|
import EVMSignMessageEIP712 from '../src/api/evm/EVMSignMessageEIP712';
|
|
37
37
|
import FirmwareUpdateV3 from '../src/api/FirmwareUpdateV3';
|
|
38
|
-
import FirmwareUpdateV4, {
|
|
38
|
+
import FirmwareUpdateV4, {
|
|
39
|
+
assertProtocolV2FirmwareTargetsSupported,
|
|
40
|
+
assertProtocolV2ReconnectIdentity,
|
|
41
|
+
} from '../src/api/FirmwareUpdateV4';
|
|
39
42
|
import GetPassphraseState from '../src/api/GetPassphraseState';
|
|
40
43
|
import GetOnekeyFeatures from '../src/api/GetOnekeyFeatures';
|
|
41
44
|
import { batchGetPublickeys } from '../src/api/helpers/batchGetPublickeys';
|
|
@@ -98,7 +101,6 @@ import {
|
|
|
98
101
|
getMethodVersionRange,
|
|
99
102
|
} from '../src/utils';
|
|
100
103
|
import { getDeviceFirmwareVersion } from '../src/utils/deviceVersionUtils';
|
|
101
|
-
import { openFirmwareByteSource } from '../src/api/firmware/FirmwareArtifactSource';
|
|
102
104
|
import {
|
|
103
105
|
getPassphraseState,
|
|
104
106
|
getPassphraseStateWithRefreshDeviceInfo,
|
|
@@ -255,7 +257,10 @@ describe('UploadPortfolio', () => {
|
|
|
255
257
|
'FilesystemFileWrite',
|
|
256
258
|
'FilesystemFile',
|
|
257
259
|
expect.any(Object),
|
|
258
|
-
{
|
|
260
|
+
expect.objectContaining({
|
|
261
|
+
timeoutMs: undefined,
|
|
262
|
+
onWriteCompleted: expect.any(Function),
|
|
263
|
+
})
|
|
259
264
|
);
|
|
260
265
|
expect(typedCall).toHaveBeenNthCalledWith(2, 'PortfolioUpdate', 'Success', {});
|
|
261
266
|
});
|
|
@@ -298,7 +303,10 @@ describe('UploadPortfolio', () => {
|
|
|
298
303
|
append: false,
|
|
299
304
|
ui_percentage: 100,
|
|
300
305
|
},
|
|
301
|
-
{
|
|
306
|
+
expect.objectContaining({
|
|
307
|
+
timeoutMs: undefined,
|
|
308
|
+
onWriteCompleted: expect.any(Function),
|
|
309
|
+
})
|
|
302
310
|
);
|
|
303
311
|
expect(typedCall).toHaveBeenNthCalledWith(2, 'PortfolioUpdate', 'Success', {});
|
|
304
312
|
expect(method.postMessage).not.toHaveBeenCalled();
|
|
@@ -3793,6 +3801,7 @@ describe('API compatibility handling', () => {
|
|
|
3793
3801
|
});
|
|
3794
3802
|
|
|
3795
3803
|
describe('Protocol V2 firmware update targets', () => {
|
|
3804
|
+
const OKPP_HEADER_SIZE = 0x52a0;
|
|
3796
3805
|
let forceReloadDataSpy: jest.SpyInstance;
|
|
3797
3806
|
|
|
3798
3807
|
beforeEach(() => {
|
|
@@ -3803,6 +3812,38 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3803
3812
|
jest.restoreAllMocks();
|
|
3804
3813
|
});
|
|
3805
3814
|
|
|
3815
|
+
const buildOkppHeader = ({
|
|
3816
|
+
type = 'RESC',
|
|
3817
|
+
version = [1, 0, 0],
|
|
3818
|
+
payloadHash = 'ab'.repeat(64),
|
|
3819
|
+
headerHash = 'cd'.repeat(64),
|
|
3820
|
+
}: {
|
|
3821
|
+
type?: string;
|
|
3822
|
+
version?: [number, number, number];
|
|
3823
|
+
payloadHash?: string;
|
|
3824
|
+
headerHash?: string;
|
|
3825
|
+
} = {}) => {
|
|
3826
|
+
const header = new Uint8Array(OKPP_HEADER_SIZE);
|
|
3827
|
+
const view = new DataView(header.buffer);
|
|
3828
|
+
'OKPP'.split('').forEach((char, index) => {
|
|
3829
|
+
header[index] = char.charCodeAt(0);
|
|
3830
|
+
});
|
|
3831
|
+
view.setUint32(0x04, 1, true);
|
|
3832
|
+
type.split('').forEach((char, index) => {
|
|
3833
|
+
header[0x08 + index] = char.charCodeAt(0);
|
|
3834
|
+
});
|
|
3835
|
+
view.setUint32(0x0c, OKPP_HEADER_SIZE, true);
|
|
3836
|
+
view.setUint32(0x10, version[0] * 0x10000 + version[1] * 0x100 + version[2], true);
|
|
3837
|
+
const writeHex = (offset: number, hex: string) => {
|
|
3838
|
+
for (let i = 0; i < hex.length / 2; i++) {
|
|
3839
|
+
header[offset + i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
3840
|
+
}
|
|
3841
|
+
};
|
|
3842
|
+
writeHex(0x200, payloadHash);
|
|
3843
|
+
writeHex(0x240, headerHash);
|
|
3844
|
+
return header;
|
|
3845
|
+
};
|
|
3846
|
+
|
|
3806
3847
|
test('keeps Protocol V2 firmware updates off the firmwareUpdateV3 path', () => {
|
|
3807
3848
|
const method = new FirmwareUpdateV3({
|
|
3808
3849
|
id: 1,
|
|
@@ -3910,7 +3951,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3910
3951
|
});
|
|
3911
3952
|
});
|
|
3912
3953
|
|
|
3913
|
-
test('
|
|
3954
|
+
test('enters Protocol V2 bootloader before upload', async () => {
|
|
3914
3955
|
const method = new FirmwareUpdateV4({
|
|
3915
3956
|
id: 1,
|
|
3916
3957
|
payload: {
|
|
@@ -3945,7 +3986,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3945
3986
|
|
|
3946
3987
|
await method.run();
|
|
3947
3988
|
|
|
3948
|
-
expect((method as any).enterProtocolV2BootloaderMode).
|
|
3989
|
+
expect((method as any).enterProtocolV2BootloaderMode).toHaveBeenCalledTimes(1);
|
|
3949
3990
|
expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith({
|
|
3950
3991
|
fwBinaryMap: [
|
|
3951
3992
|
{
|
|
@@ -3956,6 +3997,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3956
3997
|
],
|
|
3957
3998
|
bootloaderBinary: null,
|
|
3958
3999
|
});
|
|
4000
|
+
expect(method.postTipMessage).toHaveBeenCalledWith('SwitchFirmwareReconnectDevice');
|
|
3959
4001
|
});
|
|
3960
4002
|
|
|
3961
4003
|
test('enters Protocol V2 bootloader before reading and downloading remote resources', async () => {
|
|
@@ -3989,6 +4031,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3989
4031
|
});
|
|
3990
4032
|
|
|
3991
4033
|
const order: string[] = [];
|
|
4034
|
+
(method as any).prepareProtocolV2BootResources = jest.fn().mockImplementation(() => {
|
|
4035
|
+
order.push('prepare-startup-resources');
|
|
4036
|
+
return Promise.resolve([]);
|
|
4037
|
+
});
|
|
3992
4038
|
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockImplementation(() => {
|
|
3993
4039
|
order.push('enter-bootloader');
|
|
3994
4040
|
return Promise.resolve(true);
|
|
@@ -4017,7 +4063,12 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4017
4063
|
|
|
4018
4064
|
await method.run();
|
|
4019
4065
|
|
|
4020
|
-
expect(order).toEqual([
|
|
4066
|
+
expect(order).toEqual([
|
|
4067
|
+
'prepare-startup-resources',
|
|
4068
|
+
'enter-bootloader',
|
|
4069
|
+
'prepare-resources',
|
|
4070
|
+
'execute-update',
|
|
4071
|
+
]);
|
|
4021
4072
|
});
|
|
4022
4073
|
|
|
4023
4074
|
test('reboots Protocol V2 normal-mode device to bootloader before transfer', async () => {
|
|
@@ -4261,6 +4312,41 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4261
4312
|
expect(typedCall.mock.calls.map(call => call[0])).toEqual(['DeviceInfoGet']);
|
|
4262
4313
|
});
|
|
4263
4314
|
|
|
4315
|
+
test('polls again when Protocol V2 bootloader serial is temporarily unavailable', async () => {
|
|
4316
|
+
const method = new FirmwareUpdateV4({
|
|
4317
|
+
id: 1,
|
|
4318
|
+
payload: {
|
|
4319
|
+
method: 'firmwareUpdateV4',
|
|
4320
|
+
},
|
|
4321
|
+
});
|
|
4322
|
+
const typedCall = jest
|
|
4323
|
+
.fn()
|
|
4324
|
+
.mockResolvedValueOnce({
|
|
4325
|
+
type: 'DeviceInfo',
|
|
4326
|
+
message: { protocol_version: 1, hw: {} },
|
|
4327
|
+
})
|
|
4328
|
+
.mockResolvedValueOnce({
|
|
4329
|
+
type: 'DeviceInfo',
|
|
4330
|
+
message: protocolV2BootloaderDeviceInfo,
|
|
4331
|
+
});
|
|
4332
|
+
const reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
4333
|
+
(method as any).device = stubDevice({
|
|
4334
|
+
originalDescriptor: { id: 'ble-id', protocolType: 'V2' },
|
|
4335
|
+
getCommands: () => ({ typedCall }),
|
|
4336
|
+
probeProtocolV2RuntimeState: jest.fn().mockResolvedValue({
|
|
4337
|
+
mode: 'bootloader',
|
|
4338
|
+
bootloaderMode: true,
|
|
4339
|
+
}),
|
|
4340
|
+
});
|
|
4341
|
+
(method as any).reconnectProtocolV2Device = reconnectProtocolV2Device;
|
|
4342
|
+
(method as any).protocolV2ExpectedSerialNumber = 'PR9999999999';
|
|
4343
|
+
|
|
4344
|
+
await (method as any).waitForProtocolV2BootloaderMode(60 * 1000, 0);
|
|
4345
|
+
|
|
4346
|
+
expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(2);
|
|
4347
|
+
expect(typedCall).toHaveBeenCalledTimes(2);
|
|
4348
|
+
});
|
|
4349
|
+
|
|
4264
4350
|
test('does not run generic initialize during Protocol V2 USB firmware reconnect', async () => {
|
|
4265
4351
|
const method = new FirmwareUpdateV4({
|
|
4266
4352
|
id: 1,
|
|
@@ -4688,9 +4774,9 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4688
4774
|
const typedCall = jest
|
|
4689
4775
|
.fn()
|
|
4690
4776
|
.mockRejectedValue(
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4777
|
+
new DOMException(
|
|
4778
|
+
"Failed to execute 'open' on 'USBDevice': The device was disconnected",
|
|
4779
|
+
'NotFoundError'
|
|
4694
4780
|
)
|
|
4695
4781
|
);
|
|
4696
4782
|
|
|
@@ -4911,181 +4997,6 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4911
4997
|
expect((method as any).probeProtocolV2NormalMode).toHaveBeenCalledWith(deviceInfo);
|
|
4912
4998
|
});
|
|
4913
4999
|
|
|
4914
|
-
test('rejects a finished target whose payload version conflicts with the plan', () => {
|
|
4915
|
-
const method = new FirmwareUpdateV4({
|
|
4916
|
-
id: 1,
|
|
4917
|
-
payload: {
|
|
4918
|
-
method: 'firmwareUpdateV4',
|
|
4919
|
-
platform: 'desktop',
|
|
4920
|
-
expectedTargetVersions: {
|
|
4921
|
-
app_v1: '2.0.0',
|
|
4922
|
-
},
|
|
4923
|
-
},
|
|
4924
|
-
});
|
|
4925
|
-
method.init();
|
|
4926
|
-
method.postProgressMessage = jest.fn();
|
|
4927
|
-
|
|
4928
|
-
expect(() =>
|
|
4929
|
-
(method as any).assertProtocolV2TargetStatus(
|
|
4930
|
-
[{ target_id: 4, status: 2, payload_version: 0x010000 }],
|
|
4931
|
-
new Set([4])
|
|
4932
|
-
)
|
|
4933
|
-
).toThrow('expected 131072');
|
|
4934
|
-
});
|
|
4935
|
-
|
|
4936
|
-
test('fails install polling immediately with the original firmware verification error', async () => {
|
|
4937
|
-
const method = new FirmwareUpdateV4({
|
|
4938
|
-
id: 1,
|
|
4939
|
-
payload: {
|
|
4940
|
-
method: 'firmwareUpdateV4',
|
|
4941
|
-
platform: 'desktop',
|
|
4942
|
-
expectedTargetVersions: {
|
|
4943
|
-
app_v1: '2.0.0',
|
|
4944
|
-
},
|
|
4945
|
-
},
|
|
4946
|
-
});
|
|
4947
|
-
method.init();
|
|
4948
|
-
const typedCall = jest.fn().mockResolvedValue({
|
|
4949
|
-
type: 'DeviceFirmwareUpdateStatus',
|
|
4950
|
-
message: {
|
|
4951
|
-
records: [{ target_id: 4, status: 2, payload_version: 0x010000 }],
|
|
4952
|
-
},
|
|
4953
|
-
});
|
|
4954
|
-
const dateNowSpy = jest
|
|
4955
|
-
.spyOn(Date, 'now')
|
|
4956
|
-
.mockReturnValueOnce(0)
|
|
4957
|
-
.mockReturnValueOnce(0)
|
|
4958
|
-
.mockReturnValue(300_001);
|
|
4959
|
-
const setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(((
|
|
4960
|
-
callback: () => void
|
|
4961
|
-
) => {
|
|
4962
|
-
callback();
|
|
4963
|
-
return 0 as any;
|
|
4964
|
-
}) as typeof setTimeout);
|
|
4965
|
-
|
|
4966
|
-
(method as any).device = stubDevice({
|
|
4967
|
-
getCommands: () => ({ typedCall }),
|
|
4968
|
-
});
|
|
4969
|
-
(method as any).reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
4970
|
-
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(undefined);
|
|
4971
|
-
|
|
4972
|
-
try {
|
|
4973
|
-
await expect(
|
|
4974
|
-
(method as any).waitForProtocolV2FirmwareUpdateComplete([
|
|
4975
|
-
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
4976
|
-
])
|
|
4977
|
-
).rejects.toMatchObject({
|
|
4978
|
-
errorCode: HardwareErrorCode.FirmwareVerificationFailed,
|
|
4979
|
-
message: expect.stringContaining('reached payload version 65536, expected 131072'),
|
|
4980
|
-
});
|
|
4981
|
-
} finally {
|
|
4982
|
-
dateNowSpy.mockRestore();
|
|
4983
|
-
setTimeoutSpy.mockRestore();
|
|
4984
|
-
}
|
|
4985
|
-
|
|
4986
|
-
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
4987
|
-
});
|
|
4988
|
-
|
|
4989
|
-
test('fails install polling immediately with the original status conflict error', async () => {
|
|
4990
|
-
const method = new FirmwareUpdateV4({
|
|
4991
|
-
id: 1,
|
|
4992
|
-
payload: {
|
|
4993
|
-
method: 'firmwareUpdateV4',
|
|
4994
|
-
},
|
|
4995
|
-
});
|
|
4996
|
-
const typedCall = jest.fn().mockResolvedValue({
|
|
4997
|
-
type: 'DeviceFirmwareUpdateStatus',
|
|
4998
|
-
message: {
|
|
4999
|
-
records: [{ target_id: 4, status: 2, path: 'vol0:/unexpected.bin' }],
|
|
5000
|
-
},
|
|
5001
|
-
});
|
|
5002
|
-
const dateNowSpy = jest
|
|
5003
|
-
.spyOn(Date, 'now')
|
|
5004
|
-
.mockReturnValueOnce(0)
|
|
5005
|
-
.mockReturnValueOnce(0)
|
|
5006
|
-
.mockReturnValue(300_001);
|
|
5007
|
-
const setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(((
|
|
5008
|
-
callback: () => void
|
|
5009
|
-
) => {
|
|
5010
|
-
callback();
|
|
5011
|
-
return 0 as any;
|
|
5012
|
-
}) as typeof setTimeout);
|
|
5013
|
-
|
|
5014
|
-
(method as any).device = stubDevice({
|
|
5015
|
-
getCommands: () => ({ typedCall }),
|
|
5016
|
-
});
|
|
5017
|
-
(method as any).reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
5018
|
-
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(undefined);
|
|
5019
|
-
|
|
5020
|
-
try {
|
|
5021
|
-
await expect(
|
|
5022
|
-
(method as any).waitForProtocolV2FirmwareUpdateComplete([
|
|
5023
|
-
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
5024
|
-
])
|
|
5025
|
-
).rejects.toMatchObject({
|
|
5026
|
-
errorCode: HardwareErrorCode.RuntimeError,
|
|
5027
|
-
message: 'Protocol V2 install status conflicts with target 4',
|
|
5028
|
-
params: {
|
|
5029
|
-
firmwareUpdateCode: 'FirmwareInstallStatusConflict',
|
|
5030
|
-
},
|
|
5031
|
-
});
|
|
5032
|
-
} finally {
|
|
5033
|
-
dateNowSpy.mockRestore();
|
|
5034
|
-
setTimeoutSpy.mockRestore();
|
|
5035
|
-
}
|
|
5036
|
-
|
|
5037
|
-
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
5038
|
-
});
|
|
5039
|
-
|
|
5040
|
-
test('does not fail a completed multi-app install when final app versions are unobservable', () => {
|
|
5041
|
-
const method = new FirmwareUpdateV4({
|
|
5042
|
-
id: 1,
|
|
5043
|
-
payload: {
|
|
5044
|
-
method: 'firmwareUpdateV4',
|
|
5045
|
-
platform: 'desktop',
|
|
5046
|
-
targetsToUpdate: ['app_v1', 'app_v2'],
|
|
5047
|
-
expectedTargetVersions: {
|
|
5048
|
-
app_v1: '1.0.0',
|
|
5049
|
-
app_v2: '2.0.0',
|
|
5050
|
-
},
|
|
5051
|
-
},
|
|
5052
|
-
});
|
|
5053
|
-
method.init();
|
|
5054
|
-
(method as any).protocolV2LatestFinalFeatures = {
|
|
5055
|
-
major_version: 3,
|
|
5056
|
-
minor_version: 0,
|
|
5057
|
-
patch_version: 0,
|
|
5058
|
-
};
|
|
5059
|
-
(method as any).protocolV2FinalStatusVerified = true;
|
|
5060
|
-
|
|
5061
|
-
expect(() => (method as any).assertExpectedProtocolV2Versions()).not.toThrow();
|
|
5062
|
-
});
|
|
5063
|
-
|
|
5064
|
-
test('rejects unobservable final versions after the status endpoint fallback', () => {
|
|
5065
|
-
const method = new FirmwareUpdateV4({
|
|
5066
|
-
id: 1,
|
|
5067
|
-
payload: {
|
|
5068
|
-
method: 'firmwareUpdateV4',
|
|
5069
|
-
platform: 'desktop',
|
|
5070
|
-
targetsToUpdate: ['app_v1', 'app_v2'],
|
|
5071
|
-
expectedTargetVersions: {
|
|
5072
|
-
app_v1: '1.0.0',
|
|
5073
|
-
app_v2: '2.0.0',
|
|
5074
|
-
},
|
|
5075
|
-
},
|
|
5076
|
-
});
|
|
5077
|
-
method.init();
|
|
5078
|
-
(method as any).protocolV2LatestFinalFeatures = {
|
|
5079
|
-
major_version: 3,
|
|
5080
|
-
minor_version: 0,
|
|
5081
|
-
patch_version: 0,
|
|
5082
|
-
};
|
|
5083
|
-
|
|
5084
|
-
expect(() => (method as any).assertExpectedProtocolV2Versions()).toThrow(
|
|
5085
|
-
'has no observable final version after status fallback'
|
|
5086
|
-
);
|
|
5087
|
-
});
|
|
5088
|
-
|
|
5089
5000
|
test('polls target status after update ACK and finishes when all targets complete', async () => {
|
|
5090
5001
|
const method = new FirmwareUpdateV4({
|
|
5091
5002
|
id: 1,
|
|
@@ -5307,7 +5218,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5307
5218
|
).toBe(true);
|
|
5308
5219
|
|
|
5309
5220
|
(method.postProgressMessage as jest.Mock).mockClear();
|
|
5310
|
-
expect(
|
|
5221
|
+
expect(
|
|
5311
5222
|
(method as any).assertProtocolV2TargetStatus(
|
|
5312
5223
|
[
|
|
5313
5224
|
{ target_id: 4, status: 'FW_MGMT_UPDATER_TASK_STATUS_FINISHED' },
|
|
@@ -5315,8 +5226,8 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5315
5226
|
],
|
|
5316
5227
|
new Set([4, 10])
|
|
5317
5228
|
)
|
|
5318
|
-
).
|
|
5319
|
-
expect(method.postProgressMessage).
|
|
5229
|
+
).toBe(false);
|
|
5230
|
+
expect(method.postProgressMessage).toHaveBeenCalledWith(50, 'installingFirmware');
|
|
5320
5231
|
expect(method.postProgressMessage).not.toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5321
5232
|
|
|
5322
5233
|
expect(
|
|
@@ -5420,14 +5331,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5420
5331
|
const writtenPaths: string[] = [];
|
|
5421
5332
|
method.postTipMessage = jest.fn();
|
|
5422
5333
|
method.postProgressMessage = jest.fn();
|
|
5423
|
-
(method as any).
|
|
5334
|
+
(method as any).protocolV2CommonUpdateProcess = jest.fn().mockImplementation(params => {
|
|
5424
5335
|
writtenPaths.push(params.filePath);
|
|
5425
|
-
return Number(params.processedSize ?? 0) + Number(params.
|
|
5336
|
+
return Number(params.processedSize ?? 0) + Number(params.payload.byteLength);
|
|
5426
5337
|
});
|
|
5427
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
5428
|
-
(method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
|
|
5429
|
-
(method as any).waitForProtocolV2FinalFeatures = jest.fn().mockResolvedValue({});
|
|
5430
|
-
(method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
|
|
5431
5338
|
(method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
|
|
5432
5339
|
(method as any).protocolV2StartFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
|
|
5433
5340
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest
|
|
@@ -5467,12 +5374,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5467
5374
|
'vol0:/coprocessor.bin',
|
|
5468
5375
|
1
|
|
5469
5376
|
);
|
|
5470
|
-
expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledTimes(
|
|
5471
|
-
expect((method as any).protocolV2StartFirmwareUpdate).
|
|
5472
|
-
targets: [{ target_id: 3, path: 'vol0:/bootloader.bin' }],
|
|
5473
|
-
});
|
|
5474
|
-
expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenNthCalledWith(2, {
|
|
5377
|
+
expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledTimes(1);
|
|
5378
|
+
expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledWith({
|
|
5475
5379
|
targets: [
|
|
5380
|
+
{ target_id: 3, path: 'vol0:/bootloader.bin' },
|
|
5476
5381
|
{ target_id: 6, path: 'vol0:/coprocessor.bin' },
|
|
5477
5382
|
{ target_id: 7, path: 'vol0:/se01.bin' },
|
|
5478
5383
|
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
@@ -5482,7 +5387,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5482
5387
|
expect((method as any).waitForProtocolV2FirmwareUpdateComplete).toHaveBeenCalled();
|
|
5483
5388
|
});
|
|
5484
5389
|
|
|
5485
|
-
test('announces
|
|
5390
|
+
test('announces one transfer when syncing resource bundles and staging firmware', async () => {
|
|
5486
5391
|
const method = new FirmwareUpdateV4({
|
|
5487
5392
|
id: 1,
|
|
5488
5393
|
payload: {
|
|
@@ -5492,14 +5397,11 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5492
5397
|
|
|
5493
5398
|
method.postTipMessage = jest.fn();
|
|
5494
5399
|
method.postProgressMessage = jest.fn();
|
|
5495
|
-
(method as any).
|
|
5400
|
+
(method as any).protocolV2CommonUpdateProcess = jest
|
|
5496
5401
|
.fn()
|
|
5497
5402
|
.mockImplementation(params =>
|
|
5498
|
-
Promise.resolve(Number(params.processedSize ?? 0) + Number(params.
|
|
5403
|
+
Promise.resolve(Number(params.processedSize ?? 0) + Number(params.payload.byteLength))
|
|
5499
5404
|
);
|
|
5500
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
5501
|
-
(method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
|
|
5502
|
-
(method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
|
|
5503
5405
|
(method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
|
|
5504
5406
|
(method as any).protocolV2StartFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
|
|
5505
5407
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest
|
|
@@ -5519,22 +5421,21 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5519
5421
|
{
|
|
5520
5422
|
fileName: 'application_p1.bin',
|
|
5521
5423
|
binary: new Uint8Array([3]).buffer,
|
|
5522
|
-
targetId:
|
|
5424
|
+
targetId: 3,
|
|
5523
5425
|
},
|
|
5524
5426
|
],
|
|
5525
5427
|
});
|
|
5526
5428
|
|
|
5527
|
-
expect(method.postTipMessage).toHaveBeenCalledTimes(
|
|
5429
|
+
expect(method.postTipMessage).toHaveBeenCalledTimes(2);
|
|
5528
5430
|
expect(method.postTipMessage).toHaveBeenNthCalledWith(1, 'StartTransferData');
|
|
5529
|
-
expect(method.postTipMessage).toHaveBeenNthCalledWith(2, '
|
|
5530
|
-
expect(method.
|
|
5531
|
-
expect((method as any).protocolV2SourceUpdateProcess).toHaveBeenNthCalledWith(
|
|
5431
|
+
expect(method.postTipMessage).toHaveBeenNthCalledWith(2, 'ConfirmOnDevice');
|
|
5432
|
+
expect((method as any).protocolV2CommonUpdateProcess).toHaveBeenNthCalledWith(
|
|
5532
5433
|
1,
|
|
5533
|
-
expect.objectContaining({ processedSize: 0, totalSize:
|
|
5434
|
+
expect.objectContaining({ processedSize: 0, totalSize: 3 })
|
|
5534
5435
|
);
|
|
5535
|
-
expect((method as any).
|
|
5436
|
+
expect((method as any).protocolV2CommonUpdateProcess).toHaveBeenNthCalledWith(
|
|
5536
5437
|
2,
|
|
5537
|
-
expect.objectContaining({ processedSize:
|
|
5438
|
+
expect.objectContaining({ processedSize: 2, totalSize: 3 })
|
|
5538
5439
|
);
|
|
5539
5440
|
});
|
|
5540
5441
|
|
|
@@ -5548,8 +5449,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5548
5449
|
|
|
5549
5450
|
method.postTipMessage = jest.fn();
|
|
5550
5451
|
method.postProgressMessage = jest.fn();
|
|
5551
|
-
(method as any).
|
|
5552
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
5452
|
+
(method as any).protocolV2CommonUpdateProcess = jest.fn().mockResolvedValue(3);
|
|
5553
5453
|
(method as any).device = stubDevice({
|
|
5554
5454
|
getCommands: () => ({
|
|
5555
5455
|
typedCall: jest.fn().mockResolvedValue({
|
|
@@ -5595,14 +5495,11 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5595
5495
|
|
|
5596
5496
|
method.postTipMessage = jest.fn();
|
|
5597
5497
|
method.postProgressMessage = jest.fn();
|
|
5598
|
-
(method as any).
|
|
5498
|
+
(method as any).protocolV2CommonUpdateProcess = jest
|
|
5599
5499
|
.fn()
|
|
5600
5500
|
.mockImplementation(params =>
|
|
5601
|
-
Promise.resolve(Number(params.processedSize ?? 0) + Number(params.
|
|
5501
|
+
Promise.resolve(Number(params.processedSize ?? 0) + Number(params.payload.byteLength))
|
|
5602
5502
|
);
|
|
5603
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
5604
|
-
(method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
|
|
5605
|
-
(method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
|
|
5606
5503
|
(method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
|
|
5607
5504
|
(method as any).protocolV2StartFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
|
|
5608
5505
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest
|
|
@@ -5925,58 +5822,6 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5925
5822
|
});
|
|
5926
5823
|
});
|
|
5927
5824
|
|
|
5928
|
-
test('rejects prepared RESC bundle paths before opening an artifact source', async () => {
|
|
5929
|
-
const method = new FirmwareUpdateV4({
|
|
5930
|
-
id: 1,
|
|
5931
|
-
payload: {
|
|
5932
|
-
method: 'firmwareUpdateV4',
|
|
5933
|
-
},
|
|
5934
|
-
});
|
|
5935
|
-
const openPreparedSource = jest.fn();
|
|
5936
|
-
(method as any).params = {
|
|
5937
|
-
targetsToUpdate: ['resource'],
|
|
5938
|
-
resourceBundleArtifacts: [
|
|
5939
|
-
{
|
|
5940
|
-
name: 'images',
|
|
5941
|
-
artifact: {
|
|
5942
|
-
artifactRef: `fw:${'a'.repeat(64)}`,
|
|
5943
|
-
size: 1,
|
|
5944
|
-
sha256: 'a'.repeat(64),
|
|
5945
|
-
},
|
|
5946
|
-
},
|
|
5947
|
-
],
|
|
5948
|
-
};
|
|
5949
|
-
(method as any).openProtocolV2PreparedSource = openPreparedSource;
|
|
5950
|
-
const getFirmwareLatestReleaseSpy = jest
|
|
5951
|
-
.spyOn(DataManager, 'getFirmwareLatestRelease')
|
|
5952
|
-
.mockReturnValue({
|
|
5953
|
-
required: false,
|
|
5954
|
-
version: [1, 0, 0],
|
|
5955
|
-
url: '',
|
|
5956
|
-
resourceBundles: [
|
|
5957
|
-
{
|
|
5958
|
-
name: 'images',
|
|
5959
|
-
url: 'https://example.com/images.okpkg',
|
|
5960
|
-
devicePath: 'vol0:/resource/../images.okpkg',
|
|
5961
|
-
},
|
|
5962
|
-
],
|
|
5963
|
-
fingerprint: '',
|
|
5964
|
-
changelog: {
|
|
5965
|
-
'zh-CN': '',
|
|
5966
|
-
'en-US': '',
|
|
5967
|
-
},
|
|
5968
|
-
});
|
|
5969
|
-
|
|
5970
|
-
await expect(
|
|
5971
|
-
(method as any).prepareProtocolV2ResourceSources('universal', {
|
|
5972
|
-
deviceType: 'pro2',
|
|
5973
|
-
})
|
|
5974
|
-
).rejects.toThrow('resourceBundles[].devicePath');
|
|
5975
|
-
expect(openPreparedSource).not.toHaveBeenCalled();
|
|
5976
|
-
|
|
5977
|
-
getFirmwareLatestReleaseSpy.mockRestore();
|
|
5978
|
-
});
|
|
5979
|
-
|
|
5980
5825
|
test('stops a remote update before reboot when the latest config cannot be refreshed', async () => {
|
|
5981
5826
|
const method = new FirmwareUpdateV4({
|
|
5982
5827
|
id: 1,
|
|
@@ -6132,10 +5977,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6132
5977
|
|
|
6133
5978
|
method.postTipMessage = jest.fn();
|
|
6134
5979
|
method.postProgressMessage = jest.fn();
|
|
6135
|
-
(method as any).
|
|
6136
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
6137
|
-
(method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
|
|
6138
|
-
(method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
|
|
5980
|
+
(method as any).protocolV2CommonUpdateProcess = jest.fn().mockResolvedValue(3);
|
|
6139
5981
|
(method as any).protocolV2StartFirmwareUpdate = jest.fn();
|
|
6140
5982
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest.fn();
|
|
6141
5983
|
|
|
@@ -6151,7 +5993,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6151
5993
|
fwBinaryMap: [],
|
|
6152
5994
|
});
|
|
6153
5995
|
|
|
6154
|
-
expect((method as any).
|
|
5996
|
+
expect((method as any).protocolV2CommonUpdateProcess).toHaveBeenCalledTimes(1);
|
|
6155
5997
|
expect((method as any).protocolV2StartFirmwareUpdate).not.toHaveBeenCalled();
|
|
6156
5998
|
expect((method as any).waitForProtocolV2FirmwareUpdateComplete).not.toHaveBeenCalled();
|
|
6157
5999
|
});
|
|
@@ -6184,19 +6026,12 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6184
6026
|
});
|
|
6185
6027
|
method.postMessage = jest.fn();
|
|
6186
6028
|
|
|
6187
|
-
|
|
6188
|
-
|
|
6029
|
+
await (method as any).protocolV2CommonUpdateProcess({
|
|
6030
|
+
payload: new Uint8Array(4097).buffer,
|
|
6031
|
+
filePath: 'vol1:firmware.bin',
|
|
6032
|
+
processedSize: 0,
|
|
6033
|
+
totalSize: 4097,
|
|
6189
6034
|
});
|
|
6190
|
-
try {
|
|
6191
|
-
await (method as any).protocolV2SourceUpdateProcess({
|
|
6192
|
-
source,
|
|
6193
|
-
filePath: 'vol1:firmware.bin',
|
|
6194
|
-
processedSize: 0,
|
|
6195
|
-
totalSize: 4097,
|
|
6196
|
-
});
|
|
6197
|
-
} finally {
|
|
6198
|
-
await source?.close();
|
|
6199
|
-
}
|
|
6200
6035
|
|
|
6201
6036
|
const writePayloads = typedCall.mock.calls.map(call => call[2]);
|
|
6202
6037
|
expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 4000]);
|
|
@@ -6264,16 +6099,12 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6264
6099
|
method.postProgressMessage = jest.fn();
|
|
6265
6100
|
|
|
6266
6101
|
try {
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
});
|
|
6270
|
-
await (method as any).protocolV2SourceUpdateProcess({
|
|
6271
|
-
source,
|
|
6102
|
+
await (method as any).protocolV2CommonUpdateProcess({
|
|
6103
|
+
payload: new Uint8Array(8001).buffer,
|
|
6272
6104
|
filePath: 'vol0:/firmware.bin',
|
|
6273
6105
|
processedSize: 0,
|
|
6274
6106
|
totalSize: 8001,
|
|
6275
6107
|
});
|
|
6276
|
-
await source?.close();
|
|
6277
6108
|
} finally {
|
|
6278
6109
|
setTimeoutSpy.mockRestore();
|
|
6279
6110
|
}
|
|
@@ -6308,21 +6139,16 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6308
6139
|
});
|
|
6309
6140
|
method.postProgressMessage = jest.fn();
|
|
6310
6141
|
method.postTipMessage = jest.fn();
|
|
6311
|
-
(method as any).recoverProtocolV2FileTransfer = jest.fn().mockResolvedValue(undefined);
|
|
6312
6142
|
|
|
6313
|
-
const source = await openFirmwareByteSource({
|
|
6314
|
-
binary: new Uint8Array(4097).buffer,
|
|
6315
|
-
});
|
|
6316
6143
|
await expect(
|
|
6317
|
-
(method as any).
|
|
6318
|
-
|
|
6144
|
+
(method as any).protocolV2WriteWholeFile({
|
|
6145
|
+
payload: new Uint8Array(4097).buffer,
|
|
6319
6146
|
filePath: 'vol0:/firmware.bin',
|
|
6320
6147
|
processedSize: 0,
|
|
6321
6148
|
totalSize: 4097,
|
|
6322
6149
|
})
|
|
6323
6150
|
).rejects.toMatchObject({ errorCode: HardwareErrorCode.EmmcFileWriteFirmwareError });
|
|
6324
|
-
|
|
6325
|
-
expect(typedCall).toHaveBeenCalledTimes(6);
|
|
6151
|
+
expect(typedCall).toHaveBeenCalledTimes(2);
|
|
6326
6152
|
});
|
|
6327
6153
|
|
|
6328
6154
|
test('caps native BLE firmware upload chunks below the WebUSB limit', async () => {
|
|
@@ -6355,27 +6181,26 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6355
6181
|
});
|
|
6356
6182
|
method.postProgressMessage = jest.fn();
|
|
6357
6183
|
|
|
6358
|
-
|
|
6359
|
-
|
|
6184
|
+
await (method as any).protocolV2CommonUpdateProcess({
|
|
6185
|
+
payload: new Uint8Array(1801).buffer,
|
|
6186
|
+
filePath: 'vol1:ble-firmware.bin',
|
|
6187
|
+
processedSize: 0,
|
|
6188
|
+
totalSize: 1801,
|
|
6360
6189
|
});
|
|
6361
|
-
try {
|
|
6362
|
-
await (method as any).protocolV2SourceUpdateProcess({
|
|
6363
|
-
source,
|
|
6364
|
-
filePath: 'vol1:ble-firmware.bin',
|
|
6365
|
-
processedSize: 0,
|
|
6366
|
-
totalSize: 1801,
|
|
6367
|
-
});
|
|
6368
|
-
} finally {
|
|
6369
|
-
await source?.close();
|
|
6370
|
-
}
|
|
6371
6190
|
|
|
6372
6191
|
const writePayloads = typedCall.mock.calls.map(call => call[2]);
|
|
6373
6192
|
expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 1800]);
|
|
6374
6193
|
expect(writePayloads.map(payload => payload.file.data.byteLength)).toEqual([1800, 1]);
|
|
6375
6194
|
expect(writePayloads.map(payload => payload.ui_percentage)).toEqual([0, 100]);
|
|
6376
6195
|
expect(typedCall.mock.calls.map(call => call[3])).toEqual([
|
|
6377
|
-
{
|
|
6378
|
-
|
|
6196
|
+
expect.objectContaining({
|
|
6197
|
+
writeWithResponse: false,
|
|
6198
|
+
onWriteCompleted: expect.any(Function),
|
|
6199
|
+
}),
|
|
6200
|
+
expect.objectContaining({
|
|
6201
|
+
writeWithResponse: false,
|
|
6202
|
+
onWriteCompleted: expect.any(Function),
|
|
6203
|
+
}),
|
|
6379
6204
|
]);
|
|
6380
6205
|
});
|
|
6381
6206
|
|
|
@@ -6488,9 +6313,9 @@ describe('Protocol V2 firmware update method', () => {
|
|
|
6488
6313
|
const typedCall = jest
|
|
6489
6314
|
.fn()
|
|
6490
6315
|
.mockRejectedValue(
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6316
|
+
new DOMException(
|
|
6317
|
+
"Failed to execute 'open' on 'USBDevice': The device was disconnected",
|
|
6318
|
+
'NotFoundError'
|
|
6494
6319
|
)
|
|
6495
6320
|
);
|
|
6496
6321
|
|
|
@@ -6713,21 +6538,6 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6713
6538
|
});
|
|
6714
6539
|
};
|
|
6715
6540
|
|
|
6716
|
-
test('keeps the host plan identity as the V4 reconnect anchor', () => {
|
|
6717
|
-
const method = new FirmwareUpdateV4({
|
|
6718
|
-
id: 1,
|
|
6719
|
-
payload: {
|
|
6720
|
-
method: 'firmwareUpdateV4',
|
|
6721
|
-
platform: 'native',
|
|
6722
|
-
expectedDeviceId: 'persisted-device-id',
|
|
6723
|
-
},
|
|
6724
|
-
});
|
|
6725
|
-
|
|
6726
|
-
method.init();
|
|
6727
|
-
|
|
6728
|
-
expect((method as any).params.expectedDeviceId).toBe('persisted-device-id');
|
|
6729
|
-
});
|
|
6730
|
-
|
|
6731
6541
|
test('rejects a different physical serial before firmware transfer resumes', () => {
|
|
6732
6542
|
expect(() => assertProtocolV2ReconnectIdentity('expected-serial', 'other-serial')).toThrow(
|
|
6733
6543
|
'identity mismatch'
|
|
@@ -6737,15 +6547,15 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6737
6547
|
).not.toThrow();
|
|
6738
6548
|
});
|
|
6739
6549
|
|
|
6740
|
-
test('
|
|
6741
|
-
expect(() =>
|
|
6742
|
-
|
|
6743
|
-
);
|
|
6744
|
-
expect(() =>
|
|
6745
|
-
|
|
6746
|
-
);
|
|
6550
|
+
test('requires the same descriptor path when either physical serial is unavailable', () => {
|
|
6551
|
+
expect(() =>
|
|
6552
|
+
assertProtocolV2ReconnectIdentity('expected-serial', undefined, 'usb-path', 'usb-path')
|
|
6553
|
+
).not.toThrow();
|
|
6554
|
+
expect(() =>
|
|
6555
|
+
assertProtocolV2ReconnectIdentity(undefined, 'actual-serial', 'usb-path', 'other-path')
|
|
6556
|
+
).toThrow('identity unavailable');
|
|
6747
6557
|
expect(() => assertProtocolV2ReconnectIdentity(undefined, undefined)).toThrow(
|
|
6748
|
-
|
|
6558
|
+
'identity unavailable'
|
|
6749
6559
|
);
|
|
6750
6560
|
});
|
|
6751
6561
|
|
|
@@ -6764,6 +6574,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6764
6574
|
},
|
|
6765
6575
|
});
|
|
6766
6576
|
(method as any).device = stubDevice({
|
|
6577
|
+
originalDescriptor: { id: 'usb-id', path: 'usb-path', protocolType: 'V2' },
|
|
6767
6578
|
features: { deviceId: 'wallet-derived-id' },
|
|
6768
6579
|
getCommands: () => ({ typedCall }),
|
|
6769
6580
|
});
|
|
@@ -6779,7 +6590,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6779
6590
|
);
|
|
6780
6591
|
});
|
|
6781
6592
|
|
|
6782
|
-
test('
|
|
6593
|
+
test('allows firmware update startup when DeviceInfo has no physical serial', async () => {
|
|
6783
6594
|
const method = new FirmwareUpdateV4({
|
|
6784
6595
|
id: 1,
|
|
6785
6596
|
payload: { method: 'firmwareUpdateV4' },
|
|
@@ -6789,42 +6600,13 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6789
6600
|
message: { protocol_version: 1, hw: {} },
|
|
6790
6601
|
});
|
|
6791
6602
|
(method as any).device = stubDevice({
|
|
6603
|
+
originalDescriptor: { id: 'usb-id', path: 'usb-path', protocolType: 'V2' },
|
|
6792
6604
|
getCommands: () => ({ typedCall }),
|
|
6793
6605
|
});
|
|
6794
6606
|
|
|
6795
|
-
await expect((method as any).captureProtocolV2PhysicalIdentity()).
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
});
|
|
6799
|
-
|
|
6800
|
-
test('uses the BLE read limit when reading an existing firmware bundle header', async () => {
|
|
6801
|
-
const method = new FirmwareUpdateV4({
|
|
6802
|
-
id: 1,
|
|
6803
|
-
payload: {
|
|
6804
|
-
method: 'firmwareUpdateV4',
|
|
6805
|
-
platform: 'native',
|
|
6806
|
-
chunkSize: 1800,
|
|
6807
|
-
},
|
|
6808
|
-
});
|
|
6809
|
-
method.init();
|
|
6810
|
-
const readChunkLengths: number[] = [];
|
|
6811
|
-
const typedCall = jest.fn((requestType: string, _responseType: string, request: any) => {
|
|
6812
|
-
if (requestType === 'FilesystemPathInfoQuery') {
|
|
6813
|
-
return Promise.resolve({ message: { exist: true, directory: false, size: 0x52a0 } });
|
|
6814
|
-
}
|
|
6815
|
-
if (requestType === 'FilesystemFileRead') {
|
|
6816
|
-
readChunkLengths.push(request.chunk_len);
|
|
6817
|
-
return Promise.resolve({ message: { data: new Uint8Array(request.chunk_len) } });
|
|
6818
|
-
}
|
|
6819
|
-
throw new Error(`Unexpected request: ${requestType}`);
|
|
6820
|
-
});
|
|
6821
|
-
(method as any).device = stubDevice({
|
|
6822
|
-
getCommands: () => ({ typedCall }),
|
|
6823
|
-
});
|
|
6824
|
-
|
|
6825
|
-
await expect((method as any).readProtocolV2DeviceFileHeader('bundle.okpp')).resolves.toBeNull();
|
|
6826
|
-
expect(readChunkLengths.length).toBeGreaterThan(1);
|
|
6827
|
-
expect(Math.max(...readChunkLengths)).toBe(900);
|
|
6607
|
+
await expect((method as any).captureProtocolV2PhysicalIdentity()).resolves.toBeUndefined();
|
|
6608
|
+
expect((method as any).protocolV2ExpectedSerialNumber).toBeUndefined();
|
|
6609
|
+
expect((method as any).protocolV2ExpectedPath).toBeDefined();
|
|
6828
6610
|
});
|
|
6829
6611
|
|
|
6830
6612
|
test('uses filesystem reads instead of ResourceInventoryGet for resource comparison', async () => {
|
|
@@ -6941,7 +6723,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6941
6723
|
resourcesSpy.mockRestore();
|
|
6942
6724
|
});
|
|
6943
6725
|
|
|
6944
|
-
test('does not resolve boot resources
|
|
6726
|
+
test('does not resolve boot resources when no resource target is selected', async () => {
|
|
6945
6727
|
const method = new FirmwareUpdateV4({
|
|
6946
6728
|
id: 1,
|
|
6947
6729
|
payload: { method: 'firmwareUpdateV4', platform: 'web' },
|
|
@@ -6956,7 +6738,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6956
6738
|
expect(downloadSpy).not.toHaveBeenCalled();
|
|
6957
6739
|
});
|
|
6958
6740
|
|
|
6959
|
-
test('
|
|
6741
|
+
test('includes startup resources in the complete resource target', async () => {
|
|
6960
6742
|
const bytes = new Uint8Array([1, 2, 3, 4]);
|
|
6961
6743
|
const binary = bytes.buffer as ArrayBuffer;
|
|
6962
6744
|
const fileHash = Array.from(sha256(bytes), byte => byte.toString(16).padStart(2, '0')).join('');
|
|
@@ -6978,7 +6760,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6978
6760
|
payload: {
|
|
6979
6761
|
method: 'firmwareUpdateV4',
|
|
6980
6762
|
platform: 'web',
|
|
6981
|
-
targetsToUpdate: ['
|
|
6763
|
+
targetsToUpdate: ['resource'],
|
|
6982
6764
|
},
|
|
6983
6765
|
});
|
|
6984
6766
|
method.init();
|
|
@@ -7921,7 +7703,10 @@ describe('Protocol V2 file write method', () => {
|
|
|
7921
7703
|
append: false,
|
|
7922
7704
|
ui_percentage: 100,
|
|
7923
7705
|
},
|
|
7924
|
-
{
|
|
7706
|
+
expect.objectContaining({
|
|
7707
|
+
timeoutMs: undefined,
|
|
7708
|
+
onWriteCompleted: expect.any(Function),
|
|
7709
|
+
})
|
|
7925
7710
|
);
|
|
7926
7711
|
expect(method.postMessage).toHaveBeenCalledWith({
|
|
7927
7712
|
event: 'UI_EVENT',
|
|
@@ -7970,7 +7755,10 @@ describe('Protocol V2 file write method', () => {
|
|
|
7970
7755
|
append: false,
|
|
7971
7756
|
ui_percentage: 0,
|
|
7972
7757
|
},
|
|
7973
|
-
{
|
|
7758
|
+
expect.objectContaining({
|
|
7759
|
+
timeoutMs: undefined,
|
|
7760
|
+
onWriteCompleted: expect.any(Function),
|
|
7761
|
+
})
|
|
7974
7762
|
);
|
|
7975
7763
|
expect(typedCall).toHaveBeenNthCalledWith(
|
|
7976
7764
|
2,
|
|
@@ -7987,7 +7775,10 @@ describe('Protocol V2 file write method', () => {
|
|
|
7987
7775
|
append: false,
|
|
7988
7776
|
ui_percentage: 100,
|
|
7989
7777
|
},
|
|
7990
|
-
{
|
|
7778
|
+
expect.objectContaining({
|
|
7779
|
+
timeoutMs: undefined,
|
|
7780
|
+
onWriteCompleted: expect.any(Function),
|
|
7781
|
+
})
|
|
7991
7782
|
);
|
|
7992
7783
|
expect(result).toMatchObject({
|
|
7993
7784
|
path: 'vol1:test.bin',
|