@onekeyfe/hd-core 1.2.0-alpha.111 → 1.2.0-alpha.112
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__/DeviceCommands.test.ts +2 -2
- package/__tests__/device-lifecycle-events.test.ts +1 -1
- package/__tests__/device-state-mapper.test.ts +4 -4
- package/__tests__/device-utils.test.ts +1 -1
- package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +36 -89
- package/__tests__/get-device-state.test.ts +8 -8
- package/__tests__/protocol-v2-resources.test.ts +20 -0
- package/__tests__/protocol-v2.test.ts +219 -240
- package/dist/api/FirmwareUpdateV4.d.ts +0 -3
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts +1 -1
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
- package/dist/index.d.ts +5 -20
- package/dist/index.js +133 -214
- package/dist/protocols/protocol-v2/features.d.ts +4 -4
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -1
- package/dist/types/settings.d.ts +4 -19
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +85 -178
- package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +1 -1
- package/src/api/protocol-v2/DeviceInfoGet.ts +3 -3
- package/src/data/messages/messages-protocol-v2.json +31 -14
- package/src/device/DeviceStateMapper.ts +15 -15
- package/src/deviceProfile/buildDeviceFeatures.ts +3 -3
- package/src/protocols/protocol-v2/features.ts +6 -6
- package/src/protocols/protocol-v2/resources.ts +10 -49
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +1 -0
- package/src/types/settings.ts +4 -19
|
@@ -613,7 +613,7 @@ const protocolV2BootloaderDeviceInfo: ProtocolV2DeviceInfo = {
|
|
|
613
613
|
hw: {
|
|
614
614
|
serial_no: 'PR9999999999',
|
|
615
615
|
},
|
|
616
|
-
|
|
616
|
+
main_mcu: {
|
|
617
617
|
bootloader: {
|
|
618
618
|
version: '0.0.1',
|
|
619
619
|
},
|
|
@@ -677,7 +677,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
677
677
|
const deviceInfo: ProtocolV2DeviceInfo = {
|
|
678
678
|
protocol_version: 1,
|
|
679
679
|
hw: { serial_no: 'P2-STATIC' },
|
|
680
|
-
|
|
680
|
+
main_mcu: { application: { version: '1.0.0' } },
|
|
681
681
|
coprocessor: { bt_adv_name: 'Pro2 STATIC' },
|
|
682
682
|
};
|
|
683
683
|
const deviceStatus: DeviceStatus = {
|
|
@@ -751,7 +751,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
751
751
|
Device_type: DeviceType.PRO2,
|
|
752
752
|
serial_no: 'PR2SERIAL',
|
|
753
753
|
},
|
|
754
|
-
|
|
754
|
+
main_mcu: {
|
|
755
755
|
romloader: {
|
|
756
756
|
version: '0.1.0',
|
|
757
757
|
build_id: 'rom-build',
|
|
@@ -841,7 +841,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
841
841
|
hw: {
|
|
842
842
|
serial_no: 'PR2BOOT',
|
|
843
843
|
},
|
|
844
|
-
|
|
844
|
+
main_mcu: {
|
|
845
845
|
bootloader: {
|
|
846
846
|
version: '0.2.0',
|
|
847
847
|
},
|
|
@@ -863,7 +863,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
863
863
|
const features = normalizeProtocolV2Features(descriptor as any, {
|
|
864
864
|
protocol_version: 1,
|
|
865
865
|
hw: { serial_no: 'PR2NORMAL' },
|
|
866
|
-
|
|
866
|
+
main_mcu: { bootloader: { version: '0.2.0' } },
|
|
867
867
|
});
|
|
868
868
|
|
|
869
869
|
expect(features.mode).toBe('normal');
|
|
@@ -876,7 +876,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
876
876
|
hw: {
|
|
877
877
|
serial_no: 'PR2ROM',
|
|
878
878
|
},
|
|
879
|
-
|
|
879
|
+
main_mcu: {
|
|
880
880
|
romloader: {
|
|
881
881
|
version: '1.0.0',
|
|
882
882
|
},
|
|
@@ -917,17 +917,17 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
917
917
|
|
|
918
918
|
expect(
|
|
919
919
|
getProtocolV2RuntimeMode(legacyProtocolInfo, {
|
|
920
|
-
|
|
920
|
+
main_mcu: { bootloader: { version: '0.2.0' } },
|
|
921
921
|
})
|
|
922
922
|
).toBe('bootloader');
|
|
923
923
|
expect(
|
|
924
924
|
getProtocolV2RuntimeMode(legacyProtocolInfo, {
|
|
925
|
-
|
|
925
|
+
main_mcu: { romloader: { version: '1.0.0' } },
|
|
926
926
|
})
|
|
927
927
|
).toBe('romloader');
|
|
928
928
|
expect(
|
|
929
929
|
getProtocolV2RuntimeMode(legacyProtocolInfo, {
|
|
930
|
-
|
|
930
|
+
main_mcu: {
|
|
931
931
|
application: { version: '1.2.3' },
|
|
932
932
|
bootloader: { version: '0.2.0' },
|
|
933
933
|
},
|
|
@@ -1998,7 +1998,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
1998
1998
|
{ ...descriptor, protocolType: 'V2' } as any,
|
|
1999
1999
|
{
|
|
2000
2000
|
protocol_version: 2,
|
|
2001
|
-
|
|
2001
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
2002
2002
|
se1: { application: { version: '4.5.6' } },
|
|
2003
2003
|
status: { unlocked: false, passphrase_enabled: false },
|
|
2004
2004
|
}
|
|
@@ -2035,7 +2035,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
2035
2035
|
deviceInfo: {
|
|
2036
2036
|
protocol_version: 1,
|
|
2037
2037
|
hw: { serial_no: 'PR9999999999' },
|
|
2038
|
-
|
|
2038
|
+
main_mcu: { application: { version: '1.0.0' } },
|
|
2039
2039
|
},
|
|
2040
2040
|
deviceStatus: {
|
|
2041
2041
|
device_id: 'firmware-reconnect-id',
|
|
@@ -2400,7 +2400,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
2400
2400
|
(device as any).features = {
|
|
2401
2401
|
...normalizeProtocolV2Features({ ...descriptor, protocolType: 'V2' } as any, {
|
|
2402
2402
|
hw: { serial_no: 'PR2SERIAL' },
|
|
2403
|
-
|
|
2403
|
+
main_mcu: { application: { version: '4.15.0' } },
|
|
2404
2404
|
status: { passphrase_enabled: true },
|
|
2405
2405
|
}),
|
|
2406
2406
|
unlocked: true,
|
|
@@ -2825,7 +2825,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
2825
2825
|
type: 'DeviceInfo',
|
|
2826
2826
|
message: {
|
|
2827
2827
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
2828
|
-
|
|
2828
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
2829
2829
|
},
|
|
2830
2830
|
}),
|
|
2831
2831
|
};
|
|
@@ -2846,7 +2846,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
2846
2846
|
{
|
|
2847
2847
|
targets: {
|
|
2848
2848
|
hw: true,
|
|
2849
|
-
|
|
2849
|
+
main_mcu: true,
|
|
2850
2850
|
coprocessor: true,
|
|
2851
2851
|
},
|
|
2852
2852
|
types: {
|
|
@@ -2955,7 +2955,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
2955
2955
|
const device = stubDevice({
|
|
2956
2956
|
originalDescriptor: { protocolType: 'V2' },
|
|
2957
2957
|
features: normalizeProtocolV2Features({ ...descriptor, protocolType: 'V2' } as any, {
|
|
2958
|
-
|
|
2958
|
+
main_mcu: {
|
|
2959
2959
|
application: {
|
|
2960
2960
|
version: '4.14.0',
|
|
2961
2961
|
},
|
|
@@ -3009,7 +3009,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3009
3009
|
type: 'DeviceInfo',
|
|
3010
3010
|
message: {
|
|
3011
3011
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3012
|
-
|
|
3012
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3013
3013
|
},
|
|
3014
3014
|
})
|
|
3015
3015
|
.mockResolvedValueOnce({
|
|
@@ -3044,7 +3044,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3044
3044
|
{
|
|
3045
3045
|
targets: {
|
|
3046
3046
|
hw: true,
|
|
3047
|
-
|
|
3047
|
+
main_mcu: true,
|
|
3048
3048
|
coprocessor: true,
|
|
3049
3049
|
},
|
|
3050
3050
|
types: {
|
|
@@ -3073,7 +3073,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3073
3073
|
type: 'DeviceInfo',
|
|
3074
3074
|
message: {
|
|
3075
3075
|
hw: { serial_no: 'PR2SERIAL' },
|
|
3076
|
-
|
|
3076
|
+
main_mcu: { bootloader: { version: '0.2.0' } },
|
|
3077
3077
|
se1: {},
|
|
3078
3078
|
},
|
|
3079
3079
|
})
|
|
@@ -3123,7 +3123,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3123
3123
|
|
|
3124
3124
|
await device.probeProtocolV2RuntimeState({
|
|
3125
3125
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3126
|
-
|
|
3126
|
+
main_mcu: { romloader: { version: '1.0.0' } },
|
|
3127
3127
|
});
|
|
3128
3128
|
|
|
3129
3129
|
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
@@ -3151,7 +3151,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3151
3151
|
await expect(
|
|
3152
3152
|
device.probeProtocolV2RuntimeState({
|
|
3153
3153
|
hw: { Device_type: DeviceType.PRO, serial_no: 'PRO-SERIAL' },
|
|
3154
|
-
|
|
3154
|
+
main_mcu: { romloader: { version: '1.0.0' } },
|
|
3155
3155
|
})
|
|
3156
3156
|
).rejects.toMatchObject({ errorCode: HardwareErrorCode.DeviceInitializeFailed });
|
|
3157
3157
|
|
|
@@ -3176,7 +3176,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3176
3176
|
|
|
3177
3177
|
await device.probeProtocolV2RuntimeState({
|
|
3178
3178
|
hw: { serial_no: 'PR2SERIAL' },
|
|
3179
|
-
|
|
3179
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3180
3180
|
});
|
|
3181
3181
|
|
|
3182
3182
|
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
@@ -3208,7 +3208,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3208
3208
|
|
|
3209
3209
|
await device.probeProtocolV2RuntimeState({
|
|
3210
3210
|
hw: { serial_no: 'PR2SERIAL' },
|
|
3211
|
-
|
|
3211
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3212
3212
|
});
|
|
3213
3213
|
|
|
3214
3214
|
expect(typedCall).toHaveBeenCalledTimes(2);
|
|
@@ -3236,7 +3236,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3236
3236
|
|
|
3237
3237
|
await device.probeProtocolV2RuntimeState({
|
|
3238
3238
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3239
|
-
|
|
3239
|
+
main_mcu: { bootloader: { version: '0.2.0' } },
|
|
3240
3240
|
});
|
|
3241
3241
|
|
|
3242
3242
|
expect(device.features).toMatchObject({
|
|
@@ -3265,7 +3265,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3265
3265
|
await expect(
|
|
3266
3266
|
device.probeProtocolV2RuntimeState({
|
|
3267
3267
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3268
|
-
|
|
3268
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3269
3269
|
})
|
|
3270
3270
|
).rejects.toBe(linkError);
|
|
3271
3271
|
|
|
@@ -3290,7 +3290,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3290
3290
|
await expect(
|
|
3291
3291
|
device.probeProtocolV2RuntimeState({
|
|
3292
3292
|
hw: { serial_no: 'PR2SERIAL' },
|
|
3293
|
-
|
|
3293
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3294
3294
|
})
|
|
3295
3295
|
).rejects.toMatchObject({ errorCode: HardwareErrorCode.DeviceInitializeFailed });
|
|
3296
3296
|
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
@@ -3307,7 +3307,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3307
3307
|
type: 'DeviceInfo',
|
|
3308
3308
|
message: {
|
|
3309
3309
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3310
|
-
|
|
3310
|
+
main_mcu: { bootloader: { version: '0.2.0' } },
|
|
3311
3311
|
},
|
|
3312
3312
|
})
|
|
3313
3313
|
.mockResolvedValueOnce({
|
|
@@ -3357,7 +3357,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3357
3357
|
await device.probeProtocolV2RuntimeState(
|
|
3358
3358
|
{
|
|
3359
3359
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3360
|
-
|
|
3360
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3361
3361
|
},
|
|
3362
3362
|
5000
|
|
3363
3363
|
);
|
|
@@ -3402,7 +3402,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3402
3402
|
|
|
3403
3403
|
await device.probeProtocolV2RuntimeState({
|
|
3404
3404
|
hw: { Device_type: DeviceType.NEO, serial_no: 'NEOSERIAL' },
|
|
3405
|
-
|
|
3405
|
+
main_mcu: { bootloader: { version: '0.2.0' } },
|
|
3406
3406
|
});
|
|
3407
3407
|
|
|
3408
3408
|
expect(typedCall).toHaveBeenNthCalledWith(1, 'ProtocolInfoRequest', 'ProtocolInfo', {
|
|
@@ -3436,7 +3436,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3436
3436
|
|
|
3437
3437
|
await device.probeProtocolV2RuntimeState({
|
|
3438
3438
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3439
|
-
|
|
3439
|
+
main_mcu: { romloader: { version: '1.0.0' } },
|
|
3440
3440
|
});
|
|
3441
3441
|
|
|
3442
3442
|
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
@@ -3474,7 +3474,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3474
3474
|
await expect(
|
|
3475
3475
|
device.probeProtocolV2RuntimeState({
|
|
3476
3476
|
hw: { serial_no: 'PR2SERIAL' },
|
|
3477
|
-
|
|
3477
|
+
main_mcu: { application: { version: '1.0.0' } },
|
|
3478
3478
|
})
|
|
3479
3479
|
).rejects.toThrow('state update failed');
|
|
3480
3480
|
|
|
@@ -3499,7 +3499,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3499
3499
|
type: 'DeviceInfo',
|
|
3500
3500
|
message: {
|
|
3501
3501
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3502
|
-
|
|
3502
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3503
3503
|
},
|
|
3504
3504
|
})
|
|
3505
3505
|
.mockResolvedValueOnce({
|
|
@@ -3514,7 +3514,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3514
3514
|
type: 'DeviceInfo',
|
|
3515
3515
|
message: {
|
|
3516
3516
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3517
|
-
|
|
3517
|
+
main_mcu: { application: { version: '1.2.4' } },
|
|
3518
3518
|
},
|
|
3519
3519
|
})
|
|
3520
3520
|
.mockResolvedValueOnce({
|
|
@@ -3546,7 +3546,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3546
3546
|
{
|
|
3547
3547
|
targets: {
|
|
3548
3548
|
hw: true,
|
|
3549
|
-
|
|
3549
|
+
main_mcu: true,
|
|
3550
3550
|
coprocessor: true,
|
|
3551
3551
|
},
|
|
3552
3552
|
types: {
|
|
@@ -3567,7 +3567,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3567
3567
|
type: 'DeviceInfo',
|
|
3568
3568
|
message: {
|
|
3569
3569
|
hw: { serial_no: 'PR2SERIAL' },
|
|
3570
|
-
|
|
3570
|
+
main_mcu: { application: { version: '1.2.4' } },
|
|
3571
3571
|
},
|
|
3572
3572
|
})
|
|
3573
3573
|
.mockResolvedValueOnce({
|
|
@@ -3644,7 +3644,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3644
3644
|
{ ...descriptor, protocolType: 'V2' } as any,
|
|
3645
3645
|
{
|
|
3646
3646
|
hw: { Device_type: DeviceType.PRO2, serial_no: 'PR2SERIAL' },
|
|
3647
|
-
|
|
3647
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3648
3648
|
status: { init_states: true },
|
|
3649
3649
|
}
|
|
3650
3650
|
);
|
|
@@ -3684,7 +3684,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3684
3684
|
{ ...descriptor, protocolType: 'V2' } as any,
|
|
3685
3685
|
{
|
|
3686
3686
|
hw: { serial_no: 'PR2SERIAL' },
|
|
3687
|
-
|
|
3687
|
+
main_mcu: { application: { version: '4.15.0' } },
|
|
3688
3688
|
status: { passphrase_enabled: false },
|
|
3689
3689
|
}
|
|
3690
3690
|
);
|
|
@@ -3731,7 +3731,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
3731
3731
|
(device as any).features = normalizeProtocolV2Features(
|
|
3732
3732
|
{ ...descriptor, protocolType: 'V2' } as any,
|
|
3733
3733
|
{
|
|
3734
|
-
|
|
3734
|
+
main_mcu: { application: { version: '1.2.3' } },
|
|
3735
3735
|
status: { unlocked: false },
|
|
3736
3736
|
}
|
|
3737
3737
|
);
|
|
@@ -4160,7 +4160,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4160
4160
|
type: 'DeviceInfo',
|
|
4161
4161
|
message: {
|
|
4162
4162
|
hw: { serial_no: 'BLE-PRO2-SERIAL' },
|
|
4163
|
-
|
|
4163
|
+
main_mcu: {
|
|
4164
4164
|
bootloader: { version: '0.0.0' },
|
|
4165
4165
|
application: { version: '0.0.0' },
|
|
4166
4166
|
},
|
|
@@ -4212,7 +4212,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4212
4212
|
{
|
|
4213
4213
|
targets: {
|
|
4214
4214
|
hw: true,
|
|
4215
|
-
|
|
4215
|
+
main_mcu: true,
|
|
4216
4216
|
coprocessor: true,
|
|
4217
4217
|
se1: true,
|
|
4218
4218
|
se2: true,
|
|
@@ -4631,43 +4631,6 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4631
4631
|
expect(method.postTipMessage).toHaveBeenCalledWith('GoToBootloaderSuccess');
|
|
4632
4632
|
});
|
|
4633
4633
|
|
|
4634
|
-
test('keeps an ambiguous legacy runtime on the direct loader update path', async () => {
|
|
4635
|
-
const method = new FirmwareUpdateV4({
|
|
4636
|
-
id: 1,
|
|
4637
|
-
payload: {
|
|
4638
|
-
method: 'firmwareUpdateV4',
|
|
4639
|
-
},
|
|
4640
|
-
});
|
|
4641
|
-
(method as any).device = stubDevice({
|
|
4642
|
-
originalDescriptor: { id: 'usb-id', path: 'legacy-path', protocolType: 'V2' },
|
|
4643
|
-
state: {
|
|
4644
|
-
raw: {
|
|
4645
|
-
protocolV2ProtocolInfo: {
|
|
4646
|
-
version: 1,
|
|
4647
|
-
build_fingerprint: '',
|
|
4648
|
-
supported_messages: [],
|
|
4649
|
-
protobuf_definition: null,
|
|
4650
|
-
},
|
|
4651
|
-
},
|
|
4652
|
-
},
|
|
4653
|
-
features: {
|
|
4654
|
-
deviceType: 'pro2',
|
|
4655
|
-
mode: 'bootloader',
|
|
4656
|
-
bootloaderMode: true,
|
|
4657
|
-
capabilities: [],
|
|
4658
|
-
},
|
|
4659
|
-
isBootloader: () => true,
|
|
4660
|
-
isRomloader: () => false,
|
|
4661
|
-
});
|
|
4662
|
-
(method as any).protocolV2Reboot = jest.fn();
|
|
4663
|
-
method.postTipMessage = jest.fn();
|
|
4664
|
-
|
|
4665
|
-
await expect((method as any).enterProtocolV2BootloaderMode()).resolves.toBe(false);
|
|
4666
|
-
|
|
4667
|
-
expect((method as any).protocolV2LegacyDirectUpdate).toBe(true);
|
|
4668
|
-
expect((method as any).protocolV2Reboot).not.toHaveBeenCalled();
|
|
4669
|
-
});
|
|
4670
|
-
|
|
4671
4634
|
test('keeps Protocol V2 romloader active before firmware transfer', async () => {
|
|
4672
4635
|
const method = new FirmwareUpdateV4({
|
|
4673
4636
|
id: 1,
|
|
@@ -5116,7 +5079,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5116
5079
|
type: 'DeviceInfo',
|
|
5117
5080
|
message: {
|
|
5118
5081
|
hw: { serial_no: 'PR2SERIAL' },
|
|
5119
|
-
|
|
5082
|
+
main_mcu: { application: { version: '1.0.0' } },
|
|
5120
5083
|
},
|
|
5121
5084
|
});
|
|
5122
5085
|
(method as any).protocolV2ExpectedSerialNumber = 'expected-serial';
|
|
@@ -5243,49 +5206,50 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5243
5206
|
);
|
|
5244
5207
|
});
|
|
5245
5208
|
|
|
5246
|
-
test('
|
|
5209
|
+
test('stages targets before sending the empty Protocol V2 install request', async () => {
|
|
5247
5210
|
const method = new FirmwareUpdateV4({
|
|
5248
5211
|
id: 1,
|
|
5249
5212
|
payload: {
|
|
5250
5213
|
method: 'firmwareUpdateV4',
|
|
5251
5214
|
},
|
|
5252
5215
|
});
|
|
5253
|
-
const
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
Object.assign(
|
|
5257
|
-
new Error("Failed to execute 'open' on 'USBDevice': The device was disconnected"),
|
|
5258
|
-
{ name: 'NotFoundError' }
|
|
5259
|
-
)
|
|
5260
|
-
);
|
|
5216
|
+
const targets = [{ target_id: 4, path: 'vol1:firmware.bin' }];
|
|
5217
|
+
const typedCall = jest.fn().mockResolvedValue({ type: 'Success', message: {} });
|
|
5218
|
+
const call = jest.fn().mockResolvedValue({ type: 'WriteCompleted', message: {} });
|
|
5261
5219
|
|
|
5262
5220
|
(method as any).device = stubDevice({
|
|
5263
|
-
getCommands: () => ({ typedCall }),
|
|
5221
|
+
getCommands: () => ({ typedCall, call }),
|
|
5264
5222
|
});
|
|
5265
5223
|
method.postTipMessage = jest.fn();
|
|
5266
5224
|
method.postProgressMessage = jest.fn();
|
|
5267
5225
|
|
|
5268
5226
|
await expect(
|
|
5269
|
-
(method as any).protocolV2StartFirmwareUpdate({
|
|
5270
|
-
|
|
5271
|
-
})
|
|
5272
|
-
).rejects.toThrow();
|
|
5227
|
+
(method as any).protocolV2StartFirmwareUpdate({ targets })
|
|
5228
|
+
).resolves.toBeUndefined();
|
|
5273
5229
|
|
|
5274
|
-
expect(
|
|
5275
|
-
expect(
|
|
5230
|
+
expect(typedCall).toHaveBeenCalledWith('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
5231
|
+
expect(call).toHaveBeenCalledWith(
|
|
5232
|
+
'DeviceFirmwareUpdateRequest',
|
|
5233
|
+
{},
|
|
5234
|
+
{ returnAfterWrite: true }
|
|
5235
|
+
);
|
|
5236
|
+
expect(typedCall.mock.invocationCallOrder[0]).toBeLessThan(call.mock.invocationCallOrder[0]);
|
|
5237
|
+
expect(method.postTipMessage).toHaveBeenCalledWith('FirmwareUpdating');
|
|
5238
|
+
expect(method.postProgressMessage).toHaveBeenCalledWith(0, 'installingFirmware');
|
|
5276
5239
|
});
|
|
5277
5240
|
|
|
5278
|
-
test('does not
|
|
5241
|
+
test('does not send the install request when Protocol V2 staging fails', async () => {
|
|
5279
5242
|
const method = new FirmwareUpdateV4({
|
|
5280
5243
|
id: 1,
|
|
5281
5244
|
payload: {
|
|
5282
5245
|
method: 'firmwareUpdateV4',
|
|
5283
5246
|
},
|
|
5284
5247
|
});
|
|
5285
|
-
const typedCall = jest.fn().mockRejectedValue(new Error('
|
|
5248
|
+
const typedCall = jest.fn().mockRejectedValue(new Error('stage failed'));
|
|
5249
|
+
const call = jest.fn();
|
|
5286
5250
|
|
|
5287
5251
|
(method as any).device = stubDevice({
|
|
5288
|
-
getCommands: () => ({ typedCall }),
|
|
5252
|
+
getCommands: () => ({ typedCall, call }),
|
|
5289
5253
|
});
|
|
5290
5254
|
method.postTipMessage = jest.fn();
|
|
5291
5255
|
method.postProgressMessage = jest.fn();
|
|
@@ -5294,78 +5258,26 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5294
5258
|
(method as any).protocolV2StartFirmwareUpdate({
|
|
5295
5259
|
targets: [{ target_id: 4, path: 'vol1:application_p1.bin' }],
|
|
5296
5260
|
})
|
|
5297
|
-
).rejects.toThrow('
|
|
5261
|
+
).rejects.toThrow('stage failed');
|
|
5298
5262
|
|
|
5263
|
+
expect(call).not.toHaveBeenCalled();
|
|
5299
5264
|
expect(method.postTipMessage).not.toHaveBeenCalled();
|
|
5300
5265
|
expect(method.postProgressMessage).not.toHaveBeenCalled();
|
|
5301
5266
|
});
|
|
5302
5267
|
|
|
5303
|
-
test
|
|
5304
|
-
'Failure_InvalidMessage,Handler not registered',
|
|
5305
|
-
'Failure_InvalidMessage,Unsupported message',
|
|
5306
|
-
])('reboots a legacy App when the direct update endpoint is unavailable: %s', async message => {
|
|
5307
|
-
const method = new FirmwareUpdateV4({
|
|
5308
|
-
id: 1,
|
|
5309
|
-
payload: {
|
|
5310
|
-
method: 'firmwareUpdateV4',
|
|
5311
|
-
},
|
|
5312
|
-
});
|
|
5313
|
-
const targets = [{ target_id: 4, path: 'vol0:/application_p1.bin' }];
|
|
5314
|
-
const appTypedCall = jest.fn().mockRejectedValueOnce(new Error(message));
|
|
5315
|
-
const bootloaderTypedCall = jest
|
|
5316
|
-
.fn()
|
|
5317
|
-
.mockResolvedValueOnce({ type: 'Success', message: { message: '' } });
|
|
5318
|
-
let activeCommands = { typedCall: appTypedCall };
|
|
5319
|
-
|
|
5320
|
-
(method as any).device = stubDevice({
|
|
5321
|
-
getCommands: () => activeCommands,
|
|
5322
|
-
});
|
|
5323
|
-
(method as any).protocolV2LegacyDirectUpdate = true;
|
|
5324
|
-
(method as any).rebootProtocolV2ToBootloader = jest.fn().mockImplementation(() => {
|
|
5325
|
-
activeCommands = { typedCall: bootloaderTypedCall };
|
|
5326
|
-
return Promise.resolve(true);
|
|
5327
|
-
});
|
|
5328
|
-
method.postTipMessage = jest.fn();
|
|
5329
|
-
method.postProgressMessage = jest.fn();
|
|
5330
|
-
|
|
5331
|
-
await expect((method as any).protocolV2StartFirmwareUpdate({ targets })).resolves.toEqual({
|
|
5332
|
-
type: 'Success',
|
|
5333
|
-
message: { message: '' },
|
|
5334
|
-
});
|
|
5335
|
-
|
|
5336
|
-
expect(appTypedCall).toHaveBeenCalledTimes(1);
|
|
5337
|
-
expect(appTypedCall).toHaveBeenCalledWith(
|
|
5338
|
-
'DeviceFirmwareUpdateRequest',
|
|
5339
|
-
'Success',
|
|
5340
|
-
{ targets },
|
|
5341
|
-
{ timeoutMs: 180000 }
|
|
5342
|
-
);
|
|
5343
|
-
expect(bootloaderTypedCall).toHaveBeenCalledTimes(1);
|
|
5344
|
-
expect(bootloaderTypedCall).toHaveBeenCalledWith(
|
|
5345
|
-
'DeviceFirmwareUpdateRequest',
|
|
5346
|
-
'Success',
|
|
5347
|
-
{ targets },
|
|
5348
|
-
{ timeoutMs: 180000 }
|
|
5349
|
-
);
|
|
5350
|
-
expect((method as any).rebootProtocolV2ToBootloader).toHaveBeenCalledTimes(1);
|
|
5351
|
-
expect(method.postTipMessage).toHaveBeenCalledWith('FirmwareUpdating');
|
|
5352
|
-
expect(method.postProgressMessage).toHaveBeenCalledWith(0, 'installingFirmware');
|
|
5353
|
-
});
|
|
5354
|
-
|
|
5355
|
-
test('does not replay a legacy direct update after a link failure', async () => {
|
|
5268
|
+
test('does not enter install state when writing the empty request fails', async () => {
|
|
5356
5269
|
const method = new FirmwareUpdateV4({
|
|
5357
5270
|
id: 1,
|
|
5358
5271
|
payload: {
|
|
5359
5272
|
method: 'firmwareUpdateV4',
|
|
5360
5273
|
},
|
|
5361
5274
|
});
|
|
5362
|
-
const typedCall = jest.fn().
|
|
5275
|
+
const typedCall = jest.fn().mockResolvedValue({ type: 'Success', message: {} });
|
|
5276
|
+
const call = jest.fn().mockRejectedValue(new Error('write failed'));
|
|
5363
5277
|
|
|
5364
5278
|
(method as any).device = stubDevice({
|
|
5365
|
-
getCommands: () => ({ typedCall }),
|
|
5279
|
+
getCommands: () => ({ typedCall, call }),
|
|
5366
5280
|
});
|
|
5367
|
-
(method as any).protocolV2LegacyDirectUpdate = true;
|
|
5368
|
-
(method as any).rebootProtocolV2ToBootloader = jest.fn();
|
|
5369
5281
|
method.postTipMessage = jest.fn();
|
|
5370
5282
|
method.postProgressMessage = jest.fn();
|
|
5371
5283
|
|
|
@@ -5373,10 +5285,9 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5373
5285
|
(method as any).protocolV2StartFirmwareUpdate({
|
|
5374
5286
|
targets: [{ target_id: 4, path: 'vol0:/application_p1.bin' }],
|
|
5375
5287
|
})
|
|
5376
|
-
).rejects.toThrow('
|
|
5288
|
+
).rejects.toThrow('write failed');
|
|
5377
5289
|
|
|
5378
|
-
expect(
|
|
5379
|
-
expect((method as any).rebootProtocolV2ToBootloader).not.toHaveBeenCalled();
|
|
5290
|
+
expect(call).toHaveBeenCalledTimes(1);
|
|
5380
5291
|
expect(method.postTipMessage).not.toHaveBeenCalled();
|
|
5381
5292
|
expect(method.postProgressMessage).not.toHaveBeenCalled();
|
|
5382
5293
|
});
|
|
@@ -5424,26 +5335,21 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5424
5335
|
expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5425
5336
|
});
|
|
5426
5337
|
|
|
5427
|
-
test('accepts
|
|
5338
|
+
test('accepts the terminal Success returned by the install request', async () => {
|
|
5428
5339
|
const method = new FirmwareUpdateV4({
|
|
5429
5340
|
id: 1,
|
|
5430
5341
|
payload: {
|
|
5431
5342
|
method: 'firmwareUpdateV4',
|
|
5432
5343
|
},
|
|
5433
5344
|
});
|
|
5434
|
-
const typedCall = jest
|
|
5435
|
-
.fn()
|
|
5436
|
-
.mockRejectedValue(new Error('Failure: Handler not registered for this message'));
|
|
5345
|
+
const typedCall = jest.fn().mockResolvedValue({ type: 'Success', message: {} });
|
|
5437
5346
|
const reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
5438
5347
|
|
|
5439
5348
|
(method as any).device = stubDevice({
|
|
5440
5349
|
getCommands: () => ({ typedCall }),
|
|
5441
5350
|
});
|
|
5442
5351
|
(method as any).reconnectProtocolV2Device = reconnectProtocolV2Device;
|
|
5443
|
-
|
|
5444
|
-
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(deviceInfo);
|
|
5445
|
-
(method as any).probeProtocolV2NormalMode = jest.fn().mockResolvedValue(true);
|
|
5446
|
-
(method as any).protocolV2InstallAckReceived = true;
|
|
5352
|
+
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(undefined);
|
|
5447
5353
|
method.postProgressMessage = jest.fn();
|
|
5448
5354
|
|
|
5449
5355
|
await (method as any).waitForProtocolV2FirmwareUpdateComplete([
|
|
@@ -5452,47 +5358,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5452
5358
|
|
|
5453
5359
|
expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(1);
|
|
5454
5360
|
expect(typedCall.mock.calls.map(call => call[0])).toEqual(['DeviceFirmwareUpdateStatusGet']);
|
|
5455
|
-
expect((method as any).
|
|
5456
|
-
expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5457
|
-
});
|
|
5458
|
-
|
|
5459
|
-
test('accepts an empty firmware status dump only after confirming normal mode', async () => {
|
|
5460
|
-
const method = new FirmwareUpdateV4({
|
|
5461
|
-
id: 1,
|
|
5462
|
-
payload: {
|
|
5463
|
-
method: 'firmwareUpdateV4',
|
|
5464
|
-
},
|
|
5465
|
-
});
|
|
5466
|
-
const typedCall = jest.fn().mockResolvedValue({
|
|
5467
|
-
type: 'DeviceFirmwareUpdateStatus',
|
|
5468
|
-
message: { records: [] },
|
|
5469
|
-
});
|
|
5470
|
-
const deviceInfo = { hw: { serial_no: 'PRO2-PHYSICAL-1' } };
|
|
5471
|
-
let now = 0;
|
|
5472
|
-
jest.spyOn(Date, 'now').mockImplementation(() => now);
|
|
5473
|
-
jest.spyOn(global, 'setTimeout').mockImplementation(((callback: () => void) => {
|
|
5474
|
-
now += 31 * 1000;
|
|
5475
|
-
callback();
|
|
5476
|
-
return 0 as any;
|
|
5477
|
-
}) as typeof setTimeout);
|
|
5478
|
-
|
|
5479
|
-
(method as any).device = stubDevice({
|
|
5480
|
-
getCommands: () => ({ typedCall }),
|
|
5481
|
-
});
|
|
5482
|
-
(method as any).reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
|
|
5483
|
-
(method as any).verifyProtocolV2ReconnectIdentity = jest.fn().mockResolvedValue(deviceInfo);
|
|
5484
|
-
(method as any).probeProtocolV2NormalMode = jest.fn().mockResolvedValue(true);
|
|
5485
|
-
(method as any).protocolV2InstallAckReceived = true;
|
|
5486
|
-
method.postProgressMessage = jest.fn();
|
|
5487
|
-
|
|
5488
|
-
await expect(
|
|
5489
|
-
(method as any).waitForProtocolV2FirmwareUpdateComplete([
|
|
5490
|
-
{ target_id: 4, path: 'vol0:/application_p1.bin' },
|
|
5491
|
-
])
|
|
5492
|
-
).resolves.toBeUndefined();
|
|
5493
|
-
|
|
5494
|
-
expect(typedCall).toHaveBeenCalledTimes(1);
|
|
5495
|
-
expect((method as any).probeProtocolV2NormalMode).toHaveBeenCalledWith(deviceInfo);
|
|
5361
|
+
expect((method as any).protocolV2FinalStatusVerified).toBe(true);
|
|
5496
5362
|
expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'installingFirmware');
|
|
5497
5363
|
});
|
|
5498
5364
|
|
|
@@ -5806,7 +5672,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5806
5672
|
);
|
|
5807
5673
|
});
|
|
5808
5674
|
|
|
5809
|
-
test('polls target status after
|
|
5675
|
+
test('polls target status after the install request and finishes when all targets complete', async () => {
|
|
5810
5676
|
const method = new FirmwareUpdateV4({
|
|
5811
5677
|
id: 1,
|
|
5812
5678
|
payload: {
|
|
@@ -5841,7 +5707,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
5841
5707
|
expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(1);
|
|
5842
5708
|
expect(typedCall).toHaveBeenCalledWith(
|
|
5843
5709
|
'DeviceFirmwareUpdateStatusGet',
|
|
5844
|
-
'DeviceFirmwareUpdateStatus',
|
|
5710
|
+
['DeviceFirmwareUpdateStatus', 'Success'],
|
|
5845
5711
|
expect.anything(),
|
|
5846
5712
|
expect.anything()
|
|
5847
5713
|
);
|
|
@@ -6117,7 +5983,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6117
5983
|
});
|
|
6118
5984
|
expect(typedCall).toHaveBeenCalledWith(
|
|
6119
5985
|
'DeviceFirmwareUpdateStatusGet',
|
|
6120
|
-
'DeviceFirmwareUpdateStatus',
|
|
5986
|
+
['DeviceFirmwareUpdateStatus', 'Success'],
|
|
6121
5987
|
{
|
|
6122
5988
|
fields: {
|
|
6123
5989
|
status: true,
|
|
@@ -7317,9 +7183,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
7317
7183
|
],
|
|
7318
7184
|
};
|
|
7319
7185
|
const zip = new JSZip();
|
|
7320
|
-
zip.file('manifest.json', JSON.stringify(manifest));
|
|
7321
|
-
zip.file('bundles/images/images.okpkg', imagesBinary);
|
|
7322
|
-
zip.file('loaders/bootloader/boot_resource.okpkg', bootResourceBinary);
|
|
7186
|
+
zip.file('pro2-resource/manifest.json', JSON.stringify(manifest));
|
|
7187
|
+
zip.file('pro2-resource/bundles/images/images.okpkg', imagesBinary);
|
|
7188
|
+
zip.file('pro2-resource/loaders/bootloader/boot_resource.okpkg', bootResourceBinary);
|
|
7189
|
+
zip.file('pro2-resource/build-info.txt', 'ignored');
|
|
7323
7190
|
const resourceArchiveBinary = await zip.generateAsync({ type: 'arraybuffer' });
|
|
7324
7191
|
const applicationP1Binary = new Uint8Array([7, 8, 9]).buffer;
|
|
7325
7192
|
const bootloaderBinary = new Uint8Array([10, 11, 12]).buffer;
|
|
@@ -7395,6 +7262,39 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
7395
7262
|
}
|
|
7396
7263
|
});
|
|
7397
7264
|
|
|
7265
|
+
test('accepts a local resource ZIP without manifest.json', async () => {
|
|
7266
|
+
const imagesBinary = new Uint8Array([1, 2, 3]).buffer;
|
|
7267
|
+
const bootResourceBinary = new Uint8Array([4, 5, 6]).buffer;
|
|
7268
|
+
const zip = new JSZip();
|
|
7269
|
+
zip.file('pro2-resource/bundles/images/images.okpkg', imagesBinary);
|
|
7270
|
+
zip.file('pro2-resource/loaders/bootloader/boot_resource.okpkg', bootResourceBinary);
|
|
7271
|
+
zip.file('pro2-resource/build-info.txt', 'ignored');
|
|
7272
|
+
const method = new FirmwareUpdateV4({
|
|
7273
|
+
id: 1,
|
|
7274
|
+
payload: {
|
|
7275
|
+
method: 'firmwareUpdateV4',
|
|
7276
|
+
platform: 'web',
|
|
7277
|
+
targetsToUpdate: ['resource'],
|
|
7278
|
+
},
|
|
7279
|
+
});
|
|
7280
|
+
method.init();
|
|
7281
|
+
|
|
7282
|
+
await expect(
|
|
7283
|
+
(method as any).prepareProtocolV2LocalResourceArchive(
|
|
7284
|
+
await zip.generateAsync({ type: 'arraybuffer' })
|
|
7285
|
+
)
|
|
7286
|
+
).resolves.toMatchObject({
|
|
7287
|
+
materializedEntries: [
|
|
7288
|
+
{ entryName: 'manifest.json' },
|
|
7289
|
+
{ entryName: 'bundles/images/images.okpkg', binary: imagesBinary },
|
|
7290
|
+
{
|
|
7291
|
+
entryName: 'loaders/bootloader/boot_resource.okpkg',
|
|
7292
|
+
binary: bootResourceBinary,
|
|
7293
|
+
},
|
|
7294
|
+
],
|
|
7295
|
+
});
|
|
7296
|
+
});
|
|
7297
|
+
|
|
7398
7298
|
test('rejects a local resource ZIP whose file hash does not match its manifest', async () => {
|
|
7399
7299
|
const resourceBinary = new Uint8Array([1, 2, 3]).buffer;
|
|
7400
7300
|
const bootResourceBinary = new Uint8Array([4, 5, 6]).buffer;
|
|
@@ -7485,18 +7385,57 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
7485
7385
|
|
|
7486
7386
|
test('rejects an oversized ZIP entry before allocating its decompressed bytes', async () => {
|
|
7487
7387
|
const extractEntry = jest.fn();
|
|
7488
|
-
const
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7388
|
+
const oversizedFileSize = 257 * 1024 * 1024;
|
|
7389
|
+
const manifestBinary = new TextEncoder().encode(
|
|
7390
|
+
JSON.stringify({
|
|
7391
|
+
files: [
|
|
7392
|
+
{
|
|
7393
|
+
archive_path: 'loaders/bootloader/boot_resource.okpkg',
|
|
7394
|
+
original_name: 'boot_resource.okpkg',
|
|
7395
|
+
device_path: 'vol0:/loaders/bootloader/boot_resource.okpkg',
|
|
7396
|
+
size: oversizedFileSize,
|
|
7397
|
+
sha256: '0'.repeat(64),
|
|
7398
|
+
signed: true,
|
|
7399
|
+
sig_algo: 'ed25519',
|
|
7496
7400
|
},
|
|
7497
|
-
|
|
7401
|
+
{
|
|
7402
|
+
archive_path: 'bundles/images/images.okpkg',
|
|
7403
|
+
original_name: 'images.okpkg',
|
|
7404
|
+
device_path: 'vol0:/bundles/images/images.okpkg',
|
|
7405
|
+
size: oversizedFileSize,
|
|
7406
|
+
sha256: '0'.repeat(64),
|
|
7407
|
+
signed: true,
|
|
7408
|
+
sig_algo: 'ed25519',
|
|
7409
|
+
},
|
|
7410
|
+
],
|
|
7411
|
+
})
|
|
7412
|
+
);
|
|
7413
|
+
const zipFiles = {
|
|
7414
|
+
'manifest.json': {
|
|
7415
|
+
name: 'manifest.json',
|
|
7416
|
+
dir: false,
|
|
7417
|
+
_data: {
|
|
7418
|
+
compressedSize: manifestBinary.byteLength,
|
|
7419
|
+
uncompressedSize: manifestBinary.byteLength,
|
|
7498
7420
|
},
|
|
7421
|
+
async: jest.fn().mockResolvedValue(manifestBinary.buffer),
|
|
7422
|
+
},
|
|
7423
|
+
'loaders/bootloader/boot_resource.okpkg': {
|
|
7424
|
+
name: 'loaders/bootloader/boot_resource.okpkg',
|
|
7425
|
+
dir: false,
|
|
7426
|
+
_data: { compressedSize: 1, uncompressedSize: oversizedFileSize },
|
|
7427
|
+
async: extractEntry,
|
|
7499
7428
|
},
|
|
7429
|
+
'bundles/images/images.okpkg': {
|
|
7430
|
+
name: 'bundles/images/images.okpkg',
|
|
7431
|
+
dir: false,
|
|
7432
|
+
_data: { compressedSize: 1, uncompressedSize: oversizedFileSize },
|
|
7433
|
+
async: extractEntry,
|
|
7434
|
+
},
|
|
7435
|
+
};
|
|
7436
|
+
const loadSpy = jest.spyOn(JSZip, 'loadAsync').mockResolvedValue({
|
|
7437
|
+
files: zipFiles,
|
|
7438
|
+
file: (name: string) => zipFiles[name as keyof typeof zipFiles] ?? null,
|
|
7500
7439
|
} as unknown as JSZip);
|
|
7501
7440
|
const method = new FirmwareUpdateV4({
|
|
7502
7441
|
id: 1,
|
|
@@ -7511,7 +7450,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
7511
7450
|
try {
|
|
7512
7451
|
await expect(
|
|
7513
7452
|
(method as any).prepareProtocolV2LocalResourceArchive(new Uint8Array([1]).buffer)
|
|
7514
|
-
).rejects.toThrow('declared size
|
|
7453
|
+
).rejects.toThrow('declared size is invalid');
|
|
7515
7454
|
expect(extractEntry).not.toHaveBeenCalled();
|
|
7516
7455
|
} finally {
|
|
7517
7456
|
loadSpy.mockRestore();
|
|
@@ -7807,7 +7746,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
7807
7746
|
expect(writePayloads.map(payload => payload.file.data.byteLength)).toEqual([4000, 97]);
|
|
7808
7747
|
expect(writePayloads.map(payload => payload.overwrite)).toEqual([true, false]);
|
|
7809
7748
|
expect(writePayloads.every(payload => payload.append === false)).toBe(true);
|
|
7810
|
-
expect(writePayloads.map(payload => payload.ui_percentage)).toEqual([0,
|
|
7749
|
+
expect(writePayloads.map(payload => payload.ui_percentage)).toEqual([0, 99]);
|
|
7811
7750
|
expect(method.postMessage).toHaveBeenLastCalledWith({
|
|
7812
7751
|
event: 'UI_EVENT',
|
|
7813
7752
|
type: UI_REQUEST.FIRMWARE_PROGRESS,
|
|
@@ -7888,9 +7827,9 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
7888
7827
|
|
|
7889
7828
|
const writePayloads = typedCall.mock.calls.map(call => call[2]);
|
|
7890
7829
|
const deviceProgress = writePayloads.map(payload => payload.ui_percentage);
|
|
7891
|
-
expect(deviceProgress).toEqual([0, 50, 99,
|
|
7830
|
+
expect(deviceProgress).toEqual([0, 50, 99, 99]);
|
|
7892
7831
|
expect(deviceProgress.filter(progress => progress === 0)).toHaveLength(1);
|
|
7893
|
-
expect(deviceProgress.filter(progress => progress === 100)).toHaveLength(
|
|
7832
|
+
expect(deviceProgress.filter(progress => progress === 100)).toHaveLength(0);
|
|
7894
7833
|
expect(method.postTipMessage).toHaveBeenCalledTimes(2);
|
|
7895
7834
|
expect(method.postTipMessage).toHaveBeenNthCalledWith(1, 'StartTransferData');
|
|
7896
7835
|
expect(method.postTipMessage).toHaveBeenNthCalledWith(2, 'ConfirmOnDevice');
|
|
@@ -8208,7 +8147,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8208
8147
|
const writePayloads = typedCall.mock.calls.map(call => call[2]);
|
|
8209
8148
|
expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 1800]);
|
|
8210
8149
|
expect(writePayloads.map(payload => payload.file.data.byteLength)).toEqual([1800, 1]);
|
|
8211
|
-
expect(writePayloads.map(payload => payload.ui_percentage)).toEqual([0,
|
|
8150
|
+
expect(writePayloads.map(payload => payload.ui_percentage)).toEqual([0, 99]);
|
|
8212
8151
|
expect(typedCall.mock.calls.map(call => call[3])).toEqual([
|
|
8213
8152
|
expect.objectContaining({
|
|
8214
8153
|
writeWithResponse: false,
|
|
@@ -8267,23 +8206,24 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8267
8206
|
expect(writePayloads.map(payload => payload.file.data.byteLength)).toEqual([1960, 1]);
|
|
8268
8207
|
});
|
|
8269
8208
|
|
|
8270
|
-
test('
|
|
8209
|
+
test('starts install progress only after Stage and the empty Request are written', async () => {
|
|
8271
8210
|
const method = new FirmwareUpdateV4({
|
|
8272
8211
|
id: 1,
|
|
8273
8212
|
payload: {
|
|
8274
8213
|
method: 'firmwareUpdateV4',
|
|
8275
8214
|
},
|
|
8276
8215
|
});
|
|
8277
|
-
let
|
|
8278
|
-
const typedCall = jest.fn().
|
|
8216
|
+
let resolveWrite: ((value: unknown) => void) | undefined;
|
|
8217
|
+
const typedCall = jest.fn().mockResolvedValue({ type: 'Success', message: {} });
|
|
8218
|
+
const call = jest.fn().mockImplementation(
|
|
8279
8219
|
() =>
|
|
8280
8220
|
new Promise(resolve => {
|
|
8281
|
-
|
|
8221
|
+
resolveWrite = resolve;
|
|
8282
8222
|
})
|
|
8283
8223
|
);
|
|
8284
8224
|
|
|
8285
8225
|
(method as any).device = stubDevice({
|
|
8286
|
-
getCommands: () => ({ typedCall }),
|
|
8226
|
+
getCommands: () => ({ typedCall, call }),
|
|
8287
8227
|
});
|
|
8288
8228
|
method.postProgressMessage = jest.fn();
|
|
8289
8229
|
method.postTipMessage = jest.fn();
|
|
@@ -8291,21 +8231,31 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8291
8231
|
const startPromise = (method as any).protocolV2StartFirmwareUpdate({
|
|
8292
8232
|
targets: [{ target_id: 4, path: 'vol1:firmware.bin' }],
|
|
8293
8233
|
});
|
|
8294
|
-
await Promise
|
|
8234
|
+
await new Promise<void>(resolve => {
|
|
8235
|
+
setImmediate(resolve);
|
|
8236
|
+
});
|
|
8295
8237
|
|
|
8296
|
-
expect(typedCall.mock.calls[0]
|
|
8297
|
-
|
|
8238
|
+
expect(typedCall.mock.calls[0]).toEqual([
|
|
8239
|
+
'DeviceFirmwareUpdateStage',
|
|
8240
|
+
'Success',
|
|
8241
|
+
{ targets: [{ target_id: 4, path: 'vol1:firmware.bin' }] },
|
|
8242
|
+
]);
|
|
8243
|
+
expect(call).toHaveBeenCalledWith(
|
|
8244
|
+
'DeviceFirmwareUpdateRequest',
|
|
8245
|
+
{},
|
|
8246
|
+
{ returnAfterWrite: true }
|
|
8247
|
+
);
|
|
8298
8248
|
expect(method.postTipMessage).not.toHaveBeenCalled();
|
|
8299
8249
|
expect(method.postProgressMessage).not.toHaveBeenCalled();
|
|
8300
8250
|
|
|
8301
|
-
|
|
8251
|
+
resolveWrite?.({ type: 'WriteCompleted', message: {} });
|
|
8302
8252
|
await startPromise;
|
|
8303
8253
|
expect(method.postTipMessage).toHaveBeenCalledWith('FirmwareUpdating');
|
|
8304
8254
|
expect(method.postProgressMessage).toHaveBeenCalledWith(0, 'installingFirmware');
|
|
8305
8255
|
expect(method.postTipMessage).toHaveBeenCalledTimes(1);
|
|
8306
8256
|
});
|
|
8307
8257
|
|
|
8308
|
-
test('
|
|
8258
|
+
test('sends an empty Protocol V2 firmware install request without waiting for its response', async () => {
|
|
8309
8259
|
const method = new FirmwareUpdateV4({
|
|
8310
8260
|
id: 1,
|
|
8311
8261
|
payload: {
|
|
@@ -8316,9 +8266,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8316
8266
|
type: 'Success',
|
|
8317
8267
|
message: { message: 'accepted' },
|
|
8318
8268
|
});
|
|
8269
|
+
const call = jest.fn().mockResolvedValue({ type: 'WriteCompleted', message: {} });
|
|
8319
8270
|
|
|
8320
8271
|
(method as any).device = stubDevice({
|
|
8321
|
-
getCommands: () => ({ typedCall }),
|
|
8272
|
+
getCommands: () => ({ typedCall, call }),
|
|
8322
8273
|
});
|
|
8323
8274
|
method.postProgressMessage = jest.fn();
|
|
8324
8275
|
method.postTipMessage = jest.fn();
|
|
@@ -8327,7 +8278,12 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
8327
8278
|
targets: [{ target_id: 4, path: 'vol1:firmware.bin' }],
|
|
8328
8279
|
});
|
|
8329
8280
|
|
|
8330
|
-
expect(typedCall.mock.calls[0][
|
|
8281
|
+
expect(typedCall.mock.calls[0][0]).toBe('DeviceFirmwareUpdateStage');
|
|
8282
|
+
expect(call).toHaveBeenCalledWith(
|
|
8283
|
+
'DeviceFirmwareUpdateRequest',
|
|
8284
|
+
{},
|
|
8285
|
+
{ returnAfterWrite: true }
|
|
8286
|
+
);
|
|
8331
8287
|
expect(method.postTipMessage).toHaveBeenCalledWith('FirmwareUpdating');
|
|
8332
8288
|
});
|
|
8333
8289
|
});
|
|
@@ -9222,6 +9178,29 @@ describe('Protocol V2 protected method execution', () => {
|
|
|
9222
9178
|
}
|
|
9223
9179
|
);
|
|
9224
9180
|
|
|
9181
|
+
test('skips DeviceStatus and unlock when Protocol V2 is not initialized', async () => {
|
|
9182
|
+
const method = {
|
|
9183
|
+
name: 'firmwareUpdateV4',
|
|
9184
|
+
unlockPolicy: 'unlock-before-run',
|
|
9185
|
+
run: jest.fn().mockResolvedValue({ message: 'updating' }),
|
|
9186
|
+
};
|
|
9187
|
+
const device = {
|
|
9188
|
+
state: { status: { initialized: false } },
|
|
9189
|
+
commands: { typedCall: jest.fn() },
|
|
9190
|
+
isProtocolV2: () => true,
|
|
9191
|
+
isBootloader: () => false,
|
|
9192
|
+
isRomloader: () => false,
|
|
9193
|
+
unlockDevice: jest.fn(),
|
|
9194
|
+
};
|
|
9195
|
+
|
|
9196
|
+
await expect(runMethodWithUnlockPolicy(method as any, device as any)).resolves.toEqual({
|
|
9197
|
+
message: 'updating',
|
|
9198
|
+
});
|
|
9199
|
+
expect(device.commands.typedCall).not.toHaveBeenCalled();
|
|
9200
|
+
expect(device.unlockDevice).not.toHaveBeenCalled();
|
|
9201
|
+
expect(method.run).toHaveBeenCalledTimes(1);
|
|
9202
|
+
});
|
|
9203
|
+
|
|
9225
9204
|
test('keeps Protocol V1 and lock-free methods outside the preflight path', async () => {
|
|
9226
9205
|
for (const [isProtocolV2, unlockPolicy] of [
|
|
9227
9206
|
[false, 'unlock-before-run'],
|
|
@@ -9401,7 +9380,7 @@ describe('Protocol V2 current low-level methods', () => {
|
|
|
9401
9380
|
info: {
|
|
9402
9381
|
version: undefined,
|
|
9403
9382
|
serial_number: 'PR2SERIAL',
|
|
9404
|
-
|
|
9383
|
+
factory_burn_in_completed: true,
|
|
9405
9384
|
factory_test_completed: undefined,
|
|
9406
9385
|
manufacture_time: undefined,
|
|
9407
9386
|
},
|
|
@@ -9651,7 +9630,7 @@ describe('Protocol V2 raw device info method', () => {
|
|
|
9651
9630
|
'DeviceInfoGet',
|
|
9652
9631
|
'DeviceInfo',
|
|
9653
9632
|
{
|
|
9654
|
-
targets: { hw: true,
|
|
9633
|
+
targets: { hw: true, main_mcu: true, coprocessor: true },
|
|
9655
9634
|
types: { version: true, specific: true },
|
|
9656
9635
|
},
|
|
9657
9636
|
{ timeoutMs: PROTOCOL_V2_DEVICE_INFO_TIMEOUT_MS }
|