@onekeyfe/hd-core 1.2.0-alpha.73 → 1.2.0-alpha.75
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__/connectSettings.test.ts +5 -45
- package/__tests__/devicePoolBootloaderPath.test.ts +64 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
- package/__tests__/protocol-v2.test.ts +100 -405
- 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 +5 -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/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/core/index.d.ts.map +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/device/DeviceConnector.d.ts +1 -1
- package/dist/device/DeviceConnector.d.ts.map +1 -1
- package/dist/device/DevicePool.d.ts +1 -0
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/index.d.ts +2 -180
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1076 -3080
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.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 +0 -13
- 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 +6 -57
- 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 +347 -875
- 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/core/index.ts +16 -0
- package/src/data-manager/DataManager.ts +54 -62
- package/src/data-manager/connectSettings.ts +0 -11
- package/src/device/Device.ts +3 -7
- package/src/device/DeviceConnector.ts +2 -2
- package/src/device/DevicePool.ts +15 -1
- package/src/index.ts +0 -5
- package/src/inject.ts +2 -22
- package/src/lowLevelInject.ts +1 -5
- 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 +0 -13
- 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
|
@@ -101,7 +101,6 @@ import {
|
|
|
101
101
|
getMethodVersionRange,
|
|
102
102
|
} from '../src/utils';
|
|
103
103
|
import { getDeviceFirmwareVersion } from '../src/utils/deviceVersionUtils';
|
|
104
|
-
import { openFirmwareByteSource } from '../src/api/firmware/FirmwareArtifactSource';
|
|
105
104
|
import {
|
|
106
105
|
getPassphraseState,
|
|
107
106
|
getPassphraseStateWithRefreshDeviceInfo,
|
|
@@ -3802,6 +3801,7 @@ describe('API compatibility handling', () => {
|
|
|
3802
3801
|
});
|
|
3803
3802
|
|
|
3804
3803
|
describe('Protocol V2 firmware update targets', () => {
|
|
3804
|
+
const OKPP_HEADER_SIZE = 0x52a0;
|
|
3805
3805
|
let forceReloadDataSpy: jest.SpyInstance;
|
|
3806
3806
|
|
|
3807
3807
|
beforeEach(() => {
|
|
@@ -3812,6 +3812,38 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3812
3812
|
jest.restoreAllMocks();
|
|
3813
3813
|
});
|
|
3814
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
|
+
|
|
3815
3847
|
test('keeps Protocol V2 firmware updates off the firmwareUpdateV3 path', () => {
|
|
3816
3848
|
const method = new FirmwareUpdateV3({
|
|
3817
3849
|
id: 1,
|
|
@@ -3919,7 +3951,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3919
3951
|
});
|
|
3920
3952
|
});
|
|
3921
3953
|
|
|
3922
|
-
test('
|
|
3954
|
+
test('enters Protocol V2 bootloader before upload', async () => {
|
|
3923
3955
|
const method = new FirmwareUpdateV4({
|
|
3924
3956
|
id: 1,
|
|
3925
3957
|
payload: {
|
|
@@ -3954,7 +3986,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3954
3986
|
|
|
3955
3987
|
await method.run();
|
|
3956
3988
|
|
|
3957
|
-
expect((method as any).enterProtocolV2BootloaderMode).
|
|
3989
|
+
expect((method as any).enterProtocolV2BootloaderMode).toHaveBeenCalledTimes(1);
|
|
3958
3990
|
expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith({
|
|
3959
3991
|
fwBinaryMap: [
|
|
3960
3992
|
{
|
|
@@ -3965,6 +3997,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3965
3997
|
],
|
|
3966
3998
|
bootloaderBinary: null,
|
|
3967
3999
|
});
|
|
4000
|
+
expect(method.postTipMessage).toHaveBeenCalledWith('SwitchFirmwareReconnectDevice');
|
|
3968
4001
|
});
|
|
3969
4002
|
|
|
3970
4003
|
test('enters Protocol V2 bootloader before reading and downloading remote resources', async () => {
|
|
@@ -4741,9 +4774,9 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4741
4774
|
const typedCall = jest
|
|
4742
4775
|
.fn()
|
|
4743
4776
|
.mockRejectedValue(
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4777
|
+
new DOMException(
|
|
4778
|
+
"Failed to execute 'open' on 'USBDevice': The device was disconnected",
|
|
4779
|
+
'NotFoundError'
|
|
4747
4780
|
)
|
|
4748
4781
|
);
|
|
4749
4782
|
|
|
@@ -4964,181 +4997,6 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4964
4997
|
expect((method as any).probeProtocolV2NormalMode).toHaveBeenCalledWith(deviceInfo);
|
|
4965
4998
|
});
|
|
4966
4999
|
|
|
4967
|
-
test('rejects a finished target whose payload version conflicts with the plan', () => {
|
|
4968
|
-
const method = new FirmwareUpdateV4({
|
|
4969
|
-
id: 1,
|
|
4970
|
-
payload: {
|
|
4971
|
-
method: 'firmwareUpdateV4',
|
|
4972
|
-
platform: 'desktop',
|
|
4973
|
-
expectedTargetVersions: {
|
|
4974
|
-
app_v1: '2.0.0',
|
|
4975
|
-
},
|
|
4976
|
-
},
|
|
4977
|
-
});
|
|
4978
|
-
method.init();
|
|
4979
|
-
method.postProgressMessage = jest.fn();
|
|
4980
|
-
|
|
4981
|
-
expect(() =>
|
|
4982
|
-
(method as any).assertProtocolV2TargetStatus(
|
|
4983
|
-
[{ target_id: 4, status: 2, payload_version: 0x010000 }],
|
|
4984
|
-
new Set([4])
|
|
4985
|
-
)
|
|
4986
|
-
).toThrow('expected 131072');
|
|
4987
|
-
});
|
|
4988
|
-
|
|
4989
|
-
test('fails install polling immediately with the original firmware verification error', async () => {
|
|
4990
|
-
const method = new FirmwareUpdateV4({
|
|
4991
|
-
id: 1,
|
|
4992
|
-
payload: {
|
|
4993
|
-
method: 'firmwareUpdateV4',
|
|
4994
|
-
platform: 'desktop',
|
|
4995
|
-
expectedTargetVersions: {
|
|
4996
|
-
app_v1: '2.0.0',
|
|
4997
|
-
},
|
|
4998
|
-
},
|
|
4999
|
-
});
|
|
5000
|
-
method.init();
|
|
5001
|
-
const typedCall = jest.fn().mockResolvedValue({
|
|
5002
|
-
type: 'DeviceFirmwareUpdateStatus',
|
|
5003
|
-
message: {
|
|
5004
|
-
records: [{ target_id: 4, status: 2, payload_version: 0x010000 }],
|
|
5005
|
-
},
|
|
5006
|
-
});
|
|
5007
|
-
const dateNowSpy = jest
|
|
5008
|
-
.spyOn(Date, 'now')
|
|
5009
|
-
.mockReturnValueOnce(0)
|
|
5010
|
-
.mockReturnValueOnce(0)
|
|
5011
|
-
.mockReturnValue(300_001);
|
|
5012
|
-
const setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(((
|
|
5013
|
-
callback: () => void
|
|
5014
|
-
) => {
|
|
5015
|
-
callback();
|
|
5016
|
-
return 0 as any;
|
|
5017
|
-
}) as typeof setTimeout);
|
|
5018
|
-
|
|
5019
|
-
(method as any).device = stubDevice({
|
|
5020
|
-
getCommands: () => ({ typedCall }),
|
|
5021
|
-
});
|
|
5022
|
-
(method as any).reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
5023
|
-
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(undefined);
|
|
5024
|
-
|
|
5025
|
-
try {
|
|
5026
|
-
await expect(
|
|
5027
|
-
(method as any).waitForProtocolV2FirmwareUpdateComplete([
|
|
5028
|
-
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
5029
|
-
])
|
|
5030
|
-
).rejects.toMatchObject({
|
|
5031
|
-
errorCode: HardwareErrorCode.FirmwareVerificationFailed,
|
|
5032
|
-
message: expect.stringContaining('reached payload version 65536, expected 131072'),
|
|
5033
|
-
});
|
|
5034
|
-
} finally {
|
|
5035
|
-
dateNowSpy.mockRestore();
|
|
5036
|
-
setTimeoutSpy.mockRestore();
|
|
5037
|
-
}
|
|
5038
|
-
|
|
5039
|
-
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
5040
|
-
});
|
|
5041
|
-
|
|
5042
|
-
test('fails install polling immediately with the original status conflict error', async () => {
|
|
5043
|
-
const method = new FirmwareUpdateV4({
|
|
5044
|
-
id: 1,
|
|
5045
|
-
payload: {
|
|
5046
|
-
method: 'firmwareUpdateV4',
|
|
5047
|
-
},
|
|
5048
|
-
});
|
|
5049
|
-
const typedCall = jest.fn().mockResolvedValue({
|
|
5050
|
-
type: 'DeviceFirmwareUpdateStatus',
|
|
5051
|
-
message: {
|
|
5052
|
-
records: [{ target_id: 4, status: 2, path: 'vol0:/unexpected.bin' }],
|
|
5053
|
-
},
|
|
5054
|
-
});
|
|
5055
|
-
const dateNowSpy = jest
|
|
5056
|
-
.spyOn(Date, 'now')
|
|
5057
|
-
.mockReturnValueOnce(0)
|
|
5058
|
-
.mockReturnValueOnce(0)
|
|
5059
|
-
.mockReturnValue(300_001);
|
|
5060
|
-
const setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(((
|
|
5061
|
-
callback: () => void
|
|
5062
|
-
) => {
|
|
5063
|
-
callback();
|
|
5064
|
-
return 0 as any;
|
|
5065
|
-
}) as typeof setTimeout);
|
|
5066
|
-
|
|
5067
|
-
(method as any).device = stubDevice({
|
|
5068
|
-
getCommands: () => ({ typedCall }),
|
|
5069
|
-
});
|
|
5070
|
-
(method as any).reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
5071
|
-
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(undefined);
|
|
5072
|
-
|
|
5073
|
-
try {
|
|
5074
|
-
await expect(
|
|
5075
|
-
(method as any).waitForProtocolV2FirmwareUpdateComplete([
|
|
5076
|
-
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
5077
|
-
])
|
|
5078
|
-
).rejects.toMatchObject({
|
|
5079
|
-
errorCode: HardwareErrorCode.RuntimeError,
|
|
5080
|
-
message: 'Protocol V2 install status conflicts with target 4',
|
|
5081
|
-
params: {
|
|
5082
|
-
firmwareUpdateCode: 'FirmwareInstallStatusConflict',
|
|
5083
|
-
},
|
|
5084
|
-
});
|
|
5085
|
-
} finally {
|
|
5086
|
-
dateNowSpy.mockRestore();
|
|
5087
|
-
setTimeoutSpy.mockRestore();
|
|
5088
|
-
}
|
|
5089
|
-
|
|
5090
|
-
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
5091
|
-
});
|
|
5092
|
-
|
|
5093
|
-
test('does not fail a completed multi-app install when final app versions are unobservable', () => {
|
|
5094
|
-
const method = new FirmwareUpdateV4({
|
|
5095
|
-
id: 1,
|
|
5096
|
-
payload: {
|
|
5097
|
-
method: 'firmwareUpdateV4',
|
|
5098
|
-
platform: 'desktop',
|
|
5099
|
-
targetsToUpdate: ['app_v1', 'app_v2'],
|
|
5100
|
-
expectedTargetVersions: {
|
|
5101
|
-
app_v1: '1.0.0',
|
|
5102
|
-
app_v2: '2.0.0',
|
|
5103
|
-
},
|
|
5104
|
-
},
|
|
5105
|
-
});
|
|
5106
|
-
method.init();
|
|
5107
|
-
(method as any).protocolV2LatestFinalFeatures = {
|
|
5108
|
-
major_version: 3,
|
|
5109
|
-
minor_version: 0,
|
|
5110
|
-
patch_version: 0,
|
|
5111
|
-
};
|
|
5112
|
-
(method as any).protocolV2FinalStatusVerified = true;
|
|
5113
|
-
|
|
5114
|
-
expect(() => (method as any).assertExpectedProtocolV2Versions()).not.toThrow();
|
|
5115
|
-
});
|
|
5116
|
-
|
|
5117
|
-
test('rejects unobservable final versions after the status endpoint fallback', () => {
|
|
5118
|
-
const method = new FirmwareUpdateV4({
|
|
5119
|
-
id: 1,
|
|
5120
|
-
payload: {
|
|
5121
|
-
method: 'firmwareUpdateV4',
|
|
5122
|
-
platform: 'desktop',
|
|
5123
|
-
targetsToUpdate: ['app_v1', 'app_v2'],
|
|
5124
|
-
expectedTargetVersions: {
|
|
5125
|
-
app_v1: '1.0.0',
|
|
5126
|
-
app_v2: '2.0.0',
|
|
5127
|
-
},
|
|
5128
|
-
},
|
|
5129
|
-
});
|
|
5130
|
-
method.init();
|
|
5131
|
-
(method as any).protocolV2LatestFinalFeatures = {
|
|
5132
|
-
major_version: 3,
|
|
5133
|
-
minor_version: 0,
|
|
5134
|
-
patch_version: 0,
|
|
5135
|
-
};
|
|
5136
|
-
|
|
5137
|
-
expect(() => (method as any).assertExpectedProtocolV2Versions()).toThrow(
|
|
5138
|
-
'has no observable final version after status fallback'
|
|
5139
|
-
);
|
|
5140
|
-
});
|
|
5141
|
-
|
|
5142
5000
|
test('polls target status after update ACK and finishes when all targets complete', async () => {
|
|
5143
5001
|
const method = new FirmwareUpdateV4({
|
|
5144
5002
|
id: 1,
|
|
@@ -5360,7 +5218,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5360
5218
|
).toBe(true);
|
|
5361
5219
|
|
|
5362
5220
|
(method.postProgressMessage as jest.Mock).mockClear();
|
|
5363
|
-
expect(
|
|
5221
|
+
expect(
|
|
5364
5222
|
(method as any).assertProtocolV2TargetStatus(
|
|
5365
5223
|
[
|
|
5366
5224
|
{ target_id: 4, status: 'FW_MGMT_UPDATER_TASK_STATUS_FINISHED' },
|
|
@@ -5368,8 +5226,8 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5368
5226
|
],
|
|
5369
5227
|
new Set([4, 10])
|
|
5370
5228
|
)
|
|
5371
|
-
).
|
|
5372
|
-
expect(method.postProgressMessage).
|
|
5229
|
+
).toBe(false);
|
|
5230
|
+
expect(method.postProgressMessage).toHaveBeenCalledWith(50, 'installingFirmware');
|
|
5373
5231
|
expect(method.postProgressMessage).not.toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5374
5232
|
|
|
5375
5233
|
expect(
|
|
@@ -5473,14 +5331,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5473
5331
|
const writtenPaths: string[] = [];
|
|
5474
5332
|
method.postTipMessage = jest.fn();
|
|
5475
5333
|
method.postProgressMessage = jest.fn();
|
|
5476
|
-
(method as any).
|
|
5334
|
+
(method as any).protocolV2CommonUpdateProcess = jest.fn().mockImplementation(params => {
|
|
5477
5335
|
writtenPaths.push(params.filePath);
|
|
5478
|
-
return Number(params.processedSize ?? 0) + Number(params.
|
|
5336
|
+
return Number(params.processedSize ?? 0) + Number(params.payload.byteLength);
|
|
5479
5337
|
});
|
|
5480
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
5481
|
-
(method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
|
|
5482
|
-
(method as any).waitForProtocolV2FinalFeatures = jest.fn().mockResolvedValue({});
|
|
5483
|
-
(method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
|
|
5484
5338
|
(method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
|
|
5485
5339
|
(method as any).protocolV2StartFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
|
|
5486
5340
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest
|
|
@@ -5520,12 +5374,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5520
5374
|
'vol0:/coprocessor.bin',
|
|
5521
5375
|
1
|
|
5522
5376
|
);
|
|
5523
|
-
expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledTimes(
|
|
5524
|
-
expect((method as any).protocolV2StartFirmwareUpdate).
|
|
5525
|
-
targets: [{ target_id: 3, path: 'vol0:/bootloader.bin' }],
|
|
5526
|
-
});
|
|
5527
|
-
expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenNthCalledWith(2, {
|
|
5377
|
+
expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledTimes(1);
|
|
5378
|
+
expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledWith({
|
|
5528
5379
|
targets: [
|
|
5380
|
+
{ target_id: 3, path: 'vol0:/bootloader.bin' },
|
|
5529
5381
|
{ target_id: 6, path: 'vol0:/coprocessor.bin' },
|
|
5530
5382
|
{ target_id: 7, path: 'vol0:/se01.bin' },
|
|
5531
5383
|
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
@@ -5535,7 +5387,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5535
5387
|
expect((method as any).waitForProtocolV2FirmwareUpdateComplete).toHaveBeenCalled();
|
|
5536
5388
|
});
|
|
5537
5389
|
|
|
5538
|
-
test('announces
|
|
5390
|
+
test('announces one transfer when syncing resource bundles and staging firmware', async () => {
|
|
5539
5391
|
const method = new FirmwareUpdateV4({
|
|
5540
5392
|
id: 1,
|
|
5541
5393
|
payload: {
|
|
@@ -5545,14 +5397,11 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5545
5397
|
|
|
5546
5398
|
method.postTipMessage = jest.fn();
|
|
5547
5399
|
method.postProgressMessage = jest.fn();
|
|
5548
|
-
(method as any).
|
|
5400
|
+
(method as any).protocolV2CommonUpdateProcess = jest
|
|
5549
5401
|
.fn()
|
|
5550
5402
|
.mockImplementation(params =>
|
|
5551
|
-
Promise.resolve(Number(params.processedSize ?? 0) + Number(params.
|
|
5403
|
+
Promise.resolve(Number(params.processedSize ?? 0) + Number(params.payload.byteLength))
|
|
5552
5404
|
);
|
|
5553
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
5554
|
-
(method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
|
|
5555
|
-
(method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
|
|
5556
5405
|
(method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
|
|
5557
5406
|
(method as any).protocolV2StartFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
|
|
5558
5407
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest
|
|
@@ -5572,22 +5421,21 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5572
5421
|
{
|
|
5573
5422
|
fileName: 'application_p1.bin',
|
|
5574
5423
|
binary: new Uint8Array([3]).buffer,
|
|
5575
|
-
targetId:
|
|
5424
|
+
targetId: 3,
|
|
5576
5425
|
},
|
|
5577
5426
|
],
|
|
5578
5427
|
});
|
|
5579
5428
|
|
|
5580
|
-
expect(method.postTipMessage).toHaveBeenCalledTimes(
|
|
5429
|
+
expect(method.postTipMessage).toHaveBeenCalledTimes(2);
|
|
5581
5430
|
expect(method.postTipMessage).toHaveBeenNthCalledWith(1, 'StartTransferData');
|
|
5582
|
-
expect(method.postTipMessage).toHaveBeenNthCalledWith(2, '
|
|
5583
|
-
expect(method.
|
|
5584
|
-
expect((method as any).protocolV2SourceUpdateProcess).toHaveBeenNthCalledWith(
|
|
5431
|
+
expect(method.postTipMessage).toHaveBeenNthCalledWith(2, 'ConfirmOnDevice');
|
|
5432
|
+
expect((method as any).protocolV2CommonUpdateProcess).toHaveBeenNthCalledWith(
|
|
5585
5433
|
1,
|
|
5586
|
-
expect.objectContaining({ processedSize: 0, totalSize:
|
|
5434
|
+
expect.objectContaining({ processedSize: 0, totalSize: 3 })
|
|
5587
5435
|
);
|
|
5588
|
-
expect((method as any).
|
|
5436
|
+
expect((method as any).protocolV2CommonUpdateProcess).toHaveBeenNthCalledWith(
|
|
5589
5437
|
2,
|
|
5590
|
-
expect.objectContaining({ processedSize:
|
|
5438
|
+
expect.objectContaining({ processedSize: 2, totalSize: 3 })
|
|
5591
5439
|
);
|
|
5592
5440
|
});
|
|
5593
5441
|
|
|
@@ -5601,8 +5449,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5601
5449
|
|
|
5602
5450
|
method.postTipMessage = jest.fn();
|
|
5603
5451
|
method.postProgressMessage = jest.fn();
|
|
5604
|
-
(method as any).
|
|
5605
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
5452
|
+
(method as any).protocolV2CommonUpdateProcess = jest.fn().mockResolvedValue(3);
|
|
5606
5453
|
(method as any).device = stubDevice({
|
|
5607
5454
|
getCommands: () => ({
|
|
5608
5455
|
typedCall: jest.fn().mockResolvedValue({
|
|
@@ -5648,14 +5495,11 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5648
5495
|
|
|
5649
5496
|
method.postTipMessage = jest.fn();
|
|
5650
5497
|
method.postProgressMessage = jest.fn();
|
|
5651
|
-
(method as any).
|
|
5498
|
+
(method as any).protocolV2CommonUpdateProcess = jest
|
|
5652
5499
|
.fn()
|
|
5653
5500
|
.mockImplementation(params =>
|
|
5654
|
-
Promise.resolve(Number(params.processedSize ?? 0) + Number(params.
|
|
5501
|
+
Promise.resolve(Number(params.processedSize ?? 0) + Number(params.payload.byteLength))
|
|
5655
5502
|
);
|
|
5656
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
5657
|
-
(method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
|
|
5658
|
-
(method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
|
|
5659
5503
|
(method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
|
|
5660
5504
|
(method as any).protocolV2StartFirmwareUpdate = jest.fn().mockResolvedValue(undefined);
|
|
5661
5505
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest
|
|
@@ -5978,58 +5822,6 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5978
5822
|
});
|
|
5979
5823
|
});
|
|
5980
5824
|
|
|
5981
|
-
test('rejects prepared RESC bundle paths before opening an artifact source', async () => {
|
|
5982
|
-
const method = new FirmwareUpdateV4({
|
|
5983
|
-
id: 1,
|
|
5984
|
-
payload: {
|
|
5985
|
-
method: 'firmwareUpdateV4',
|
|
5986
|
-
},
|
|
5987
|
-
});
|
|
5988
|
-
const openPreparedSource = jest.fn();
|
|
5989
|
-
(method as any).params = {
|
|
5990
|
-
targetsToUpdate: ['resource'],
|
|
5991
|
-
resourceBundleArtifacts: [
|
|
5992
|
-
{
|
|
5993
|
-
name: 'images',
|
|
5994
|
-
artifact: {
|
|
5995
|
-
artifactRef: `fw:${'a'.repeat(64)}`,
|
|
5996
|
-
size: 1,
|
|
5997
|
-
sha256: 'a'.repeat(64),
|
|
5998
|
-
},
|
|
5999
|
-
},
|
|
6000
|
-
],
|
|
6001
|
-
};
|
|
6002
|
-
(method as any).openProtocolV2PreparedSource = openPreparedSource;
|
|
6003
|
-
const getFirmwareLatestReleaseSpy = jest
|
|
6004
|
-
.spyOn(DataManager, 'getFirmwareLatestRelease')
|
|
6005
|
-
.mockReturnValue({
|
|
6006
|
-
required: false,
|
|
6007
|
-
version: [1, 0, 0],
|
|
6008
|
-
url: '',
|
|
6009
|
-
resourceBundles: [
|
|
6010
|
-
{
|
|
6011
|
-
name: 'images',
|
|
6012
|
-
url: 'https://example.com/images.okpkg',
|
|
6013
|
-
devicePath: 'vol0:/resource/../images.okpkg',
|
|
6014
|
-
},
|
|
6015
|
-
],
|
|
6016
|
-
fingerprint: '',
|
|
6017
|
-
changelog: {
|
|
6018
|
-
'zh-CN': '',
|
|
6019
|
-
'en-US': '',
|
|
6020
|
-
},
|
|
6021
|
-
});
|
|
6022
|
-
|
|
6023
|
-
await expect(
|
|
6024
|
-
(method as any).prepareProtocolV2ResourceSources('universal', {
|
|
6025
|
-
deviceType: 'pro2',
|
|
6026
|
-
})
|
|
6027
|
-
).rejects.toThrow('resourceBundles[].devicePath');
|
|
6028
|
-
expect(openPreparedSource).not.toHaveBeenCalled();
|
|
6029
|
-
|
|
6030
|
-
getFirmwareLatestReleaseSpy.mockRestore();
|
|
6031
|
-
});
|
|
6032
|
-
|
|
6033
5825
|
test('stops a remote update before reboot when the latest config cannot be refreshed', async () => {
|
|
6034
5826
|
const method = new FirmwareUpdateV4({
|
|
6035
5827
|
id: 1,
|
|
@@ -6192,10 +5984,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6192
5984
|
|
|
6193
5985
|
method.postTipMessage = jest.fn();
|
|
6194
5986
|
method.postProgressMessage = jest.fn();
|
|
6195
|
-
(method as any).
|
|
6196
|
-
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockResolvedValue(undefined);
|
|
6197
|
-
(method as any).completeProtocolV2FinalVerification = jest.fn().mockResolvedValue({});
|
|
6198
|
-
(method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
|
|
5987
|
+
(method as any).protocolV2CommonUpdateProcess = jest.fn().mockResolvedValue(3);
|
|
6199
5988
|
(method as any).protocolV2StartFirmwareUpdate = jest.fn();
|
|
6200
5989
|
(method as any).waitForProtocolV2FirmwareUpdateComplete = jest.fn();
|
|
6201
5990
|
|
|
@@ -6211,7 +6000,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6211
6000
|
fwBinaryMap: [],
|
|
6212
6001
|
});
|
|
6213
6002
|
|
|
6214
|
-
expect((method as any).
|
|
6003
|
+
expect((method as any).protocolV2CommonUpdateProcess).toHaveBeenCalledTimes(1);
|
|
6215
6004
|
expect((method as any).protocolV2StartFirmwareUpdate).not.toHaveBeenCalled();
|
|
6216
6005
|
expect((method as any).waitForProtocolV2FirmwareUpdateComplete).not.toHaveBeenCalled();
|
|
6217
6006
|
});
|
|
@@ -6244,19 +6033,12 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6244
6033
|
});
|
|
6245
6034
|
method.postMessage = jest.fn();
|
|
6246
6035
|
|
|
6247
|
-
|
|
6248
|
-
|
|
6036
|
+
await (method as any).protocolV2CommonUpdateProcess({
|
|
6037
|
+
payload: new Uint8Array(4097).buffer,
|
|
6038
|
+
filePath: 'vol1:firmware.bin',
|
|
6039
|
+
processedSize: 0,
|
|
6040
|
+
totalSize: 4097,
|
|
6249
6041
|
});
|
|
6250
|
-
try {
|
|
6251
|
-
await (method as any).protocolV2SourceUpdateProcess({
|
|
6252
|
-
source,
|
|
6253
|
-
filePath: 'vol1:firmware.bin',
|
|
6254
|
-
processedSize: 0,
|
|
6255
|
-
totalSize: 4097,
|
|
6256
|
-
});
|
|
6257
|
-
} finally {
|
|
6258
|
-
await source?.close();
|
|
6259
|
-
}
|
|
6260
6042
|
|
|
6261
6043
|
const writePayloads = typedCall.mock.calls.map(call => call[2]);
|
|
6262
6044
|
expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 4000]);
|
|
@@ -6277,13 +6059,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6277
6059
|
});
|
|
6278
6060
|
});
|
|
6279
6061
|
|
|
6280
|
-
|
|
6281
|
-
// writeProtocolV2File path. PR #850 replaced that path with FirmwareByteSource
|
|
6282
|
-
// streaming (protocolV2SourceUpdateProcess), which restarts a failed transfer from
|
|
6283
|
-
// offset 0 and retries the whole file instead of a single chunk. Re-enable after the
|
|
6284
|
-
// resume/per-chunk-retry behavior is re-implemented on writeFirmwareByteSource, which
|
|
6285
|
-
// needs a start-offset parameter in FirmwareArtifactSource.ts.
|
|
6286
|
-
test.skip('resumes from the last confirmed offset after an ambiguous chunk write failure', async () => {
|
|
6062
|
+
test('resumes from the last confirmed offset after an ambiguous chunk write failure', async () => {
|
|
6287
6063
|
const method = new FirmwareUpdateV4({
|
|
6288
6064
|
id: 1,
|
|
6289
6065
|
payload: {
|
|
@@ -6341,16 +6117,12 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6341
6117
|
method.postProgressMessage = jest.fn();
|
|
6342
6118
|
|
|
6343
6119
|
try {
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
});
|
|
6347
|
-
await (method as any).protocolV2SourceUpdateProcess({
|
|
6348
|
-
source,
|
|
6120
|
+
await (method as any).protocolV2CommonUpdateProcess({
|
|
6121
|
+
payload: new Uint8Array(8001).buffer,
|
|
6349
6122
|
filePath: 'vol0:/firmware.bin',
|
|
6350
6123
|
processedSize: 0,
|
|
6351
6124
|
totalSize: 8001,
|
|
6352
6125
|
});
|
|
6353
|
-
await source?.close();
|
|
6354
6126
|
} finally {
|
|
6355
6127
|
setTimeoutSpy.mockRestore();
|
|
6356
6128
|
}
|
|
@@ -6365,13 +6137,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6365
6137
|
expect(initialize).toHaveBeenCalledTimes(1);
|
|
6366
6138
|
});
|
|
6367
6139
|
|
|
6368
|
-
|
|
6369
|
-
// writeProtocolV2File path. PR #850 replaced that path with FirmwareByteSource
|
|
6370
|
-
// streaming (protocolV2SourceUpdateProcess), which restarts a failed transfer from
|
|
6371
|
-
// offset 0 and retries the whole file instead of a single chunk. Re-enable after the
|
|
6372
|
-
// resume/per-chunk-retry behavior is re-implemented on writeFirmwareByteSource, which
|
|
6373
|
-
// needs a start-offset parameter in FirmwareArtifactSource.ts.
|
|
6374
|
-
test.skip('restarts from offset zero when remote staging is behind the confirmed offset', async () => {
|
|
6140
|
+
test('restarts from offset zero when remote staging is behind the confirmed offset', async () => {
|
|
6375
6141
|
const method = new FirmwareUpdateV4({
|
|
6376
6142
|
id: 1,
|
|
6377
6143
|
payload: { method: 'firmwareUpdateV4' },
|
|
@@ -6415,13 +6181,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6415
6181
|
expect((method as any).recoverProtocolV2FileTransfer).toHaveBeenCalledTimes(1);
|
|
6416
6182
|
});
|
|
6417
6183
|
|
|
6418
|
-
|
|
6419
|
-
// writeProtocolV2File path. PR #850 replaced that path with FirmwareByteSource
|
|
6420
|
-
// streaming (protocolV2SourceUpdateProcess), which restarts a failed transfer from
|
|
6421
|
-
// offset 0 and retries the whole file instead of a single chunk. Re-enable after the
|
|
6422
|
-
// resume/per-chunk-retry behavior is re-implemented on writeFirmwareByteSource, which
|
|
6423
|
-
// needs a start-offset parameter in FirmwareArtifactSource.ts.
|
|
6424
|
-
test.skip('retries an idempotent firmware chunk before restarting the whole file', async () => {
|
|
6184
|
+
test('retries an idempotent firmware chunk before restarting the whole file', async () => {
|
|
6425
6185
|
const method = new FirmwareUpdateV4({
|
|
6426
6186
|
id: 1,
|
|
6427
6187
|
payload: { method: 'firmwareUpdateV4' },
|
|
@@ -6478,30 +6238,19 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6478
6238
|
});
|
|
6479
6239
|
method.postProgressMessage = jest.fn();
|
|
6480
6240
|
method.postTipMessage = jest.fn();
|
|
6481
|
-
(method as any).recoverProtocolV2FileTransfer = jest.fn().mockResolvedValue(undefined);
|
|
6482
6241
|
|
|
6483
|
-
const source = await openFirmwareByteSource({
|
|
6484
|
-
binary: new Uint8Array(4097).buffer,
|
|
6485
|
-
});
|
|
6486
6242
|
await expect(
|
|
6487
|
-
(method as any).
|
|
6488
|
-
|
|
6243
|
+
(method as any).protocolV2WriteWholeFile({
|
|
6244
|
+
payload: new Uint8Array(4097).buffer,
|
|
6489
6245
|
filePath: 'vol0:/firmware.bin',
|
|
6490
6246
|
processedSize: 0,
|
|
6491
6247
|
totalSize: 4097,
|
|
6492
6248
|
})
|
|
6493
6249
|
).rejects.toMatchObject({ errorCode: HardwareErrorCode.EmmcFileWriteFirmwareError });
|
|
6494
|
-
|
|
6495
|
-
expect(typedCall).toHaveBeenCalledTimes(6);
|
|
6250
|
+
expect(typedCall).toHaveBeenCalledTimes(2);
|
|
6496
6251
|
});
|
|
6497
6252
|
|
|
6498
|
-
|
|
6499
|
-
// writeProtocolV2File path. PR #850 replaced that path with FirmwareByteSource
|
|
6500
|
-
// streaming (protocolV2SourceUpdateProcess), which restarts a failed transfer from
|
|
6501
|
-
// offset 0 and retries the whole file instead of a single chunk. Re-enable after the
|
|
6502
|
-
// resume/per-chunk-retry behavior is re-implemented on writeFirmwareByteSource, which
|
|
6503
|
-
// needs a start-offset parameter in FirmwareArtifactSource.ts.
|
|
6504
|
-
test.skip('coalesces public progress events without dropping confirmed-byte callbacks', async () => {
|
|
6253
|
+
test('coalesces public progress events without dropping confirmed-byte callbacks', async () => {
|
|
6505
6254
|
const method = new FirmwareUpdateV4({
|
|
6506
6255
|
id: 1,
|
|
6507
6256
|
payload: { method: 'firmwareUpdateV4' },
|
|
@@ -6567,19 +6316,12 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6567
6316
|
});
|
|
6568
6317
|
method.postProgressMessage = jest.fn();
|
|
6569
6318
|
|
|
6570
|
-
|
|
6571
|
-
|
|
6319
|
+
await (method as any).protocolV2CommonUpdateProcess({
|
|
6320
|
+
payload: new Uint8Array(1801).buffer,
|
|
6321
|
+
filePath: 'vol1:ble-firmware.bin',
|
|
6322
|
+
processedSize: 0,
|
|
6323
|
+
totalSize: 1801,
|
|
6572
6324
|
});
|
|
6573
|
-
try {
|
|
6574
|
-
await (method as any).protocolV2SourceUpdateProcess({
|
|
6575
|
-
source,
|
|
6576
|
-
filePath: 'vol1:ble-firmware.bin',
|
|
6577
|
-
processedSize: 0,
|
|
6578
|
-
totalSize: 1801,
|
|
6579
|
-
});
|
|
6580
|
-
} finally {
|
|
6581
|
-
await source?.close();
|
|
6582
|
-
}
|
|
6583
6325
|
|
|
6584
6326
|
const writePayloads = typedCall.mock.calls.map(call => call[2]);
|
|
6585
6327
|
expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 1800]);
|
|
@@ -6627,16 +6369,12 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6627
6369
|
});
|
|
6628
6370
|
method.postProgressMessage = jest.fn();
|
|
6629
6371
|
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
});
|
|
6633
|
-
await (method as any).protocolV2SourceUpdateProcess({
|
|
6634
|
-
source,
|
|
6372
|
+
await (method as any).protocolV2CommonUpdateProcess({
|
|
6373
|
+
payload: new Uint8Array(1961).buffer,
|
|
6635
6374
|
filePath: 'vol0:/application_p1.bin',
|
|
6636
6375
|
processedSize: 0,
|
|
6637
6376
|
totalSize: 1961,
|
|
6638
6377
|
});
|
|
6639
|
-
await source?.close();
|
|
6640
6378
|
|
|
6641
6379
|
const writePayloads = typedCall.mock.calls.map(call => call[2]);
|
|
6642
6380
|
expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 1960]);
|
|
@@ -6752,9 +6490,9 @@ describe('Protocol V2 firmware update method', () => {
|
|
|
6752
6490
|
const typedCall = jest
|
|
6753
6491
|
.fn()
|
|
6754
6492
|
.mockRejectedValue(
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6493
|
+
new DOMException(
|
|
6494
|
+
"Failed to execute 'open' on 'USBDevice': The device was disconnected",
|
|
6495
|
+
'NotFoundError'
|
|
6758
6496
|
)
|
|
6759
6497
|
);
|
|
6760
6498
|
|
|
@@ -6977,21 +6715,6 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6977
6715
|
});
|
|
6978
6716
|
};
|
|
6979
6717
|
|
|
6980
|
-
test('keeps the host plan identity as the V4 reconnect anchor', () => {
|
|
6981
|
-
const method = new FirmwareUpdateV4({
|
|
6982
|
-
id: 1,
|
|
6983
|
-
payload: {
|
|
6984
|
-
method: 'firmwareUpdateV4',
|
|
6985
|
-
platform: 'native',
|
|
6986
|
-
expectedDeviceId: 'persisted-device-id',
|
|
6987
|
-
},
|
|
6988
|
-
});
|
|
6989
|
-
|
|
6990
|
-
method.init();
|
|
6991
|
-
|
|
6992
|
-
expect((method as any).params.expectedDeviceId).toBe('persisted-device-id');
|
|
6993
|
-
});
|
|
6994
|
-
|
|
6995
6718
|
test('rejects a different physical serial before firmware transfer resumes', () => {
|
|
6996
6719
|
expect(() => assertProtocolV2ReconnectIdentity('expected-serial', 'other-serial')).toThrow(
|
|
6997
6720
|
'identity mismatch'
|
|
@@ -7001,15 +6724,15 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
7001
6724
|
).not.toThrow();
|
|
7002
6725
|
});
|
|
7003
6726
|
|
|
7004
|
-
test('
|
|
7005
|
-
expect(() =>
|
|
7006
|
-
|
|
7007
|
-
);
|
|
7008
|
-
expect(() =>
|
|
7009
|
-
|
|
7010
|
-
);
|
|
6727
|
+
test('requires the same descriptor path when either physical serial is unavailable', () => {
|
|
6728
|
+
expect(() =>
|
|
6729
|
+
assertProtocolV2ReconnectIdentity('expected-serial', undefined, 'usb-path', 'usb-path')
|
|
6730
|
+
).not.toThrow();
|
|
6731
|
+
expect(() =>
|
|
6732
|
+
assertProtocolV2ReconnectIdentity(undefined, 'actual-serial', 'usb-path', 'other-path')
|
|
6733
|
+
).toThrow('identity unavailable');
|
|
7011
6734
|
expect(() => assertProtocolV2ReconnectIdentity(undefined, undefined)).toThrow(
|
|
7012
|
-
|
|
6735
|
+
'identity unavailable'
|
|
7013
6736
|
);
|
|
7014
6737
|
});
|
|
7015
6738
|
|
|
@@ -7028,6 +6751,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
7028
6751
|
},
|
|
7029
6752
|
});
|
|
7030
6753
|
(method as any).device = stubDevice({
|
|
6754
|
+
originalDescriptor: { id: 'usb-id', path: 'usb-path', protocolType: 'V2' },
|
|
7031
6755
|
features: { deviceId: 'wallet-derived-id' },
|
|
7032
6756
|
getCommands: () => ({ typedCall }),
|
|
7033
6757
|
});
|
|
@@ -7043,7 +6767,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
7043
6767
|
);
|
|
7044
6768
|
});
|
|
7045
6769
|
|
|
7046
|
-
test('
|
|
6770
|
+
test('allows firmware update startup when DeviceInfo has no physical serial', async () => {
|
|
7047
6771
|
const method = new FirmwareUpdateV4({
|
|
7048
6772
|
id: 1,
|
|
7049
6773
|
payload: { method: 'firmwareUpdateV4' },
|
|
@@ -7053,42 +6777,13 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
7053
6777
|
message: { protocol_version: 1, hw: {} },
|
|
7054
6778
|
});
|
|
7055
6779
|
(method as any).device = stubDevice({
|
|
6780
|
+
originalDescriptor: { id: 'usb-id', path: 'usb-path', protocolType: 'V2' },
|
|
7056
6781
|
getCommands: () => ({ typedCall }),
|
|
7057
6782
|
});
|
|
7058
6783
|
|
|
7059
|
-
await expect((method as any).captureProtocolV2PhysicalIdentity()).
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
});
|
|
7063
|
-
|
|
7064
|
-
test('uses the BLE read limit when reading an existing firmware bundle header', async () => {
|
|
7065
|
-
const method = new FirmwareUpdateV4({
|
|
7066
|
-
id: 1,
|
|
7067
|
-
payload: {
|
|
7068
|
-
method: 'firmwareUpdateV4',
|
|
7069
|
-
platform: 'native',
|
|
7070
|
-
chunkSize: 1800,
|
|
7071
|
-
},
|
|
7072
|
-
});
|
|
7073
|
-
method.init();
|
|
7074
|
-
const readChunkLengths: number[] = [];
|
|
7075
|
-
const typedCall = jest.fn((requestType: string, _responseType: string, request: any) => {
|
|
7076
|
-
if (requestType === 'FilesystemPathInfoQuery') {
|
|
7077
|
-
return Promise.resolve({ message: { exist: true, directory: false, size: 0x52a0 } });
|
|
7078
|
-
}
|
|
7079
|
-
if (requestType === 'FilesystemFileRead') {
|
|
7080
|
-
readChunkLengths.push(request.chunk_len);
|
|
7081
|
-
return Promise.resolve({ message: { data: new Uint8Array(request.chunk_len) } });
|
|
7082
|
-
}
|
|
7083
|
-
throw new Error(`Unexpected request: ${requestType}`);
|
|
7084
|
-
});
|
|
7085
|
-
(method as any).device = stubDevice({
|
|
7086
|
-
getCommands: () => ({ typedCall }),
|
|
7087
|
-
});
|
|
7088
|
-
|
|
7089
|
-
await expect((method as any).readProtocolV2DeviceFileHeader('bundle.okpp')).resolves.toBeNull();
|
|
7090
|
-
expect(readChunkLengths.length).toBeGreaterThan(1);
|
|
7091
|
-
expect(Math.max(...readChunkLengths)).toBe(900);
|
|
6784
|
+
await expect((method as any).captureProtocolV2PhysicalIdentity()).resolves.toBeUndefined();
|
|
6785
|
+
expect((method as any).protocolV2ExpectedSerialNumber).toBeUndefined();
|
|
6786
|
+
expect((method as any).protocolV2ExpectedPath).toBeDefined();
|
|
7092
6787
|
});
|
|
7093
6788
|
|
|
7094
6789
|
test('uses filesystem reads instead of ResourceInventoryGet for resource comparison', async () => {
|