@onekeyfe/hd-core 1.2.0 → 1.2.1

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.
@@ -335,7 +335,97 @@ describe('FirmwareUpdateV4 install polling', () => {
335
335
  expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'installingFirmware');
336
336
  });
337
337
 
338
- test('accepts stable finished BLE status after an actual install disconnect hides in-progress', async () => {
338
+ test.each([
339
+ {
340
+ component: 'boot',
341
+ targets: [{ target_id: 3, path: 'vol0:/bootloader.bin' }],
342
+ },
343
+ {
344
+ component: 'P1',
345
+ targets: [{ target_id: 4, path: 'vol0:/application_p1.bin' }],
346
+ },
347
+ {
348
+ component: 'P2',
349
+ targets: [{ target_id: 5, path: 'vol0:/application_p2.bin' }],
350
+ },
351
+ {
352
+ component: 'coprocessor',
353
+ targets: [{ target_id: 6, path: 'vol0:/coprocessor.bin' }],
354
+ },
355
+ {
356
+ component: 'SE',
357
+ targets: [
358
+ { target_id: 7, path: 'vol0:/se01.bin' },
359
+ { target_id: 8, path: 'vol0:/se02.bin' },
360
+ { target_id: 9, path: 'vol0:/se03.bin' },
361
+ { target_id: 10, path: 'vol0:/se04.bin' },
362
+ ],
363
+ },
364
+ ])(
365
+ 'accepts stable finished BLE status for $component after an actual install disconnect hides in-progress',
366
+ async ({ targets }) => {
367
+ const method = new FirmwareUpdateV4({
368
+ id: 1,
369
+ payload: {
370
+ method: 'firmwareUpdateV4',
371
+ connectId: 'pro2-ble',
372
+ },
373
+ });
374
+ const finishedStatus = {
375
+ type: 'DeviceFirmwareUpdateStatus',
376
+ message: {
377
+ records: targets.map(target => ({
378
+ ...target,
379
+ status: 'FW_MGMT_UPDATER_TASK_STATUS_FINISHED',
380
+ })),
381
+ },
382
+ };
383
+ const typedCall = jest
384
+ .fn()
385
+ .mockResolvedValueOnce(finishedStatus)
386
+ .mockImplementationOnce(() => {
387
+ expect(method.postProgressMessage).not.toHaveBeenCalled();
388
+ throw new Error('device was disconnected');
389
+ })
390
+ .mockResolvedValueOnce(finishedStatus)
391
+ .mockImplementationOnce(() => {
392
+ expect(method.postProgressMessage).toHaveBeenCalledTimes(1);
393
+ expect(method.postProgressMessage).toHaveBeenCalledWith(1, 'installingFirmware');
394
+ return finishedStatus;
395
+ })
396
+ .mockResolvedValueOnce(finishedStatus)
397
+ .mockResolvedValueOnce(finishedStatus)
398
+ .mockRejectedValueOnce(ERRORS.TypedError(HardwareErrorCode.ActionCancelled));
399
+ const reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
400
+
401
+ method.device = {
402
+ getCommands: () => ({ typedCall }),
403
+ setCancelableAction: jest.fn(),
404
+ } as unknown as Device;
405
+ method.postProgressMessage = jest.fn();
406
+
407
+ const firmwareUpdate = method as unknown as {
408
+ waitForProtocolV2FirmwareUpdateComplete: (
409
+ value: typeof targets,
410
+ requireCurrentInstallStatus: boolean
411
+ ) => Promise<void>;
412
+ reconnectProtocolV2Device: (options: { skipProtocolProbe: boolean }) => Promise<void>;
413
+ };
414
+ firmwareUpdate.reconnectProtocolV2Device = reconnectProtocolV2Device;
415
+ (method as any).isBleReconnect = jest.fn(() => true);
416
+
417
+ await firmwareUpdate.waitForProtocolV2FirmwareUpdateComplete(targets, true);
418
+
419
+ expect(reconnectProtocolV2Device).toHaveBeenCalledWith({ skipProtocolProbe: true });
420
+ expect(typedCall).toHaveBeenCalledTimes(6);
421
+ expect(method.postProgressMessage).toHaveBeenNthCalledWith(1, 1, 'installingFirmware');
422
+ expect(method.postProgressMessage).toHaveBeenNthCalledWith(2, 100, 'installingFirmware');
423
+ expect(method.postProgressMessage).toHaveBeenCalledTimes(2);
424
+ },
425
+ 10_000
426
+ );
427
+
428
+ test('uses a real BLE disconnect while writing the Request as install evidence', async () => {
339
429
  const method = new FirmwareUpdateV4({
340
430
  id: 1,
341
431
  payload: {
@@ -343,49 +433,41 @@ describe('FirmwareUpdateV4 install polling', () => {
343
433
  connectId: 'pro2-ble',
344
434
  },
345
435
  });
346
- const targets = [{ target_id: 6, path: 'vol0:/coprocessor.bin' }];
436
+ const targets = [{ target_id: 3, path: 'vol0:/bootloader.bin' }];
347
437
  const finishedStatus = {
348
438
  type: 'DeviceFirmwareUpdateStatus',
349
439
  message: {
350
440
  records: [
351
441
  {
352
- target_id: 6,
442
+ ...targets[0],
353
443
  status: 'FW_MGMT_UPDATER_TASK_STATUS_FINISHED',
354
- payload_version: 65_556,
355
- path: 'vol0:/coprocessor.bin',
356
444
  },
357
445
  ],
358
446
  },
359
447
  };
360
448
  const typedCall = jest
361
449
  .fn()
450
+ .mockResolvedValueOnce({ type: 'Success', message: {} })
362
451
  .mockResolvedValueOnce(finishedStatus)
363
- .mockImplementationOnce(() => {
364
- expect(method.postProgressMessage).not.toHaveBeenCalled();
365
- throw new Error('device was disconnected');
366
- })
367
452
  .mockResolvedValueOnce(finishedStatus)
368
- .mockImplementationOnce(() => {
369
- expect(method.postProgressMessage).toHaveBeenCalledTimes(1);
370
- expect(method.postProgressMessage).toHaveBeenCalledWith(1, 'installingFirmware');
371
- return finishedStatus;
372
- })
373
453
  .mockResolvedValueOnce(finishedStatus)
374
454
  .mockResolvedValueOnce(finishedStatus)
375
455
  .mockRejectedValueOnce(ERRORS.TypedError(HardwareErrorCode.ActionCancelled));
456
+ const call = jest.fn().mockRejectedValue(ERRORS.TypedError(HardwareErrorCode.BleTimeoutError));
376
457
  const reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
377
458
 
378
- (method as any).params = {
379
- expectedTargetVersions: { coprocessor: '1.0.20' },
380
- };
381
-
382
459
  method.device = {
383
- getCommands: () => ({ typedCall }),
460
+ getCommands: () => ({ typedCall, call, cancelDevice: jest.fn() }),
461
+ createProtocolV2UiPhaseMetadata: jest.fn().mockReturnValue(undefined),
462
+ toMessageObject: jest.fn().mockReturnValue({ connectId: 'pro2-ble' }),
384
463
  setCancelableAction: jest.fn(),
464
+ clearCancelableAction: jest.fn(),
385
465
  } as unknown as Device;
466
+ method.postMessage = jest.fn();
386
467
  method.postProgressMessage = jest.fn();
387
468
 
388
469
  const firmwareUpdate = method as unknown as {
470
+ protocolV2StartFirmwareUpdate: (params: { targets: typeof targets }) => Promise<void>;
389
471
  waitForProtocolV2FirmwareUpdateComplete: (
390
472
  value: typeof targets,
391
473
  requireCurrentInstallStatus: boolean
@@ -395,15 +477,234 @@ describe('FirmwareUpdateV4 install polling', () => {
395
477
  firmwareUpdate.reconnectProtocolV2Device = reconnectProtocolV2Device;
396
478
  (method as any).isBleReconnect = jest.fn(() => true);
397
479
 
480
+ await firmwareUpdate.protocolV2StartFirmwareUpdate({ targets });
398
481
  await firmwareUpdate.waitForProtocolV2FirmwareUpdateComplete(targets, true);
399
482
 
400
483
  expect(reconnectProtocolV2Device).toHaveBeenCalledWith({ skipProtocolProbe: true });
401
- expect(typedCall).toHaveBeenCalledTimes(6);
402
484
  expect(method.postProgressMessage).toHaveBeenNthCalledWith(1, 1, 'installingFirmware');
403
485
  expect(method.postProgressMessage).toHaveBeenNthCalledWith(2, 100, 'installingFirmware');
404
- expect(method.postProgressMessage).toHaveBeenCalledTimes(2);
486
+ expect(typedCall).toHaveBeenCalledTimes(5);
487
+ }, 10_000);
488
+
489
+ test('does not use a Request response timeout as BLE install evidence', async () => {
490
+ const method = new FirmwareUpdateV4({
491
+ id: 1,
492
+ payload: {
493
+ method: 'firmwareUpdateV4',
494
+ connectId: 'pro2-ble',
495
+ },
496
+ });
497
+ const targets = [{ target_id: 3, path: 'vol0:/bootloader.bin' }];
498
+ const finishedStatus = {
499
+ type: 'DeviceFirmwareUpdateStatus',
500
+ message: {
501
+ records: [
502
+ {
503
+ ...targets[0],
504
+ status: 'FW_MGMT_UPDATER_TASK_STATUS_FINISHED',
505
+ },
506
+ ],
507
+ },
508
+ };
509
+ const typedCall = jest
510
+ .fn()
511
+ .mockResolvedValueOnce({ type: 'Success', message: {} })
512
+ .mockResolvedValueOnce(finishedStatus)
513
+ .mockResolvedValueOnce(finishedStatus)
514
+ .mockResolvedValueOnce(finishedStatus)
515
+ .mockResolvedValueOnce(finishedStatus)
516
+ .mockRejectedValueOnce(ERRORS.TypedError(HardwareErrorCode.ActionCancelled));
517
+ const call = jest
518
+ .fn()
519
+ .mockRejectedValue(
520
+ ERRORS.TypedError(
521
+ HardwareErrorCode.BleTimeoutError,
522
+ 'device was disconnected after Lowlevel response timeout'
523
+ )
524
+ );
525
+ const reconnectProtocolV2Device = jest.fn().mockResolvedValue(undefined);
526
+
527
+ method.device = {
528
+ getCommands: () => ({ typedCall, call, cancelDevice: jest.fn() }),
529
+ createProtocolV2UiPhaseMetadata: jest.fn().mockReturnValue(undefined),
530
+ toMessageObject: jest.fn().mockReturnValue({ connectId: 'pro2-ble' }),
531
+ setCancelableAction: jest.fn(),
532
+ clearCancelableAction: jest.fn(),
533
+ } as unknown as Device;
534
+ method.postMessage = jest.fn();
535
+ method.postProgressMessage = jest.fn();
536
+
537
+ const firmwareUpdate = method as unknown as {
538
+ protocolV2StartFirmwareUpdate: (params: { targets: typeof targets }) => Promise<void>;
539
+ waitForProtocolV2FirmwareUpdateComplete: (
540
+ value: typeof targets,
541
+ requireCurrentInstallStatus: boolean
542
+ ) => Promise<void>;
543
+ reconnectProtocolV2Device: (options: { skipProtocolProbe: boolean }) => Promise<void>;
544
+ };
545
+ firmwareUpdate.reconnectProtocolV2Device = reconnectProtocolV2Device;
546
+ (method as any).isBleReconnect = jest.fn(() => true);
547
+
548
+ await firmwareUpdate.protocolV2StartFirmwareUpdate({ targets });
549
+ await expect(
550
+ firmwareUpdate.waitForProtocolV2FirmwareUpdateComplete(targets, true)
551
+ ).rejects.toMatchObject({
552
+ errorCode: HardwareErrorCode.ActionCancelled,
553
+ });
554
+
555
+ expect(reconnectProtocolV2Device).toHaveBeenCalledWith({ skipProtocolProbe: true });
556
+ expect(method.postProgressMessage).not.toHaveBeenCalled();
405
557
  }, 10_000);
406
558
 
559
+ test('records a real BLE disconnect that occurs during install reconnect', async () => {
560
+ const method = new FirmwareUpdateV4({
561
+ id: 1,
562
+ payload: {
563
+ method: 'firmwareUpdateV4',
564
+ connectId: 'pro2-ble',
565
+ },
566
+ });
567
+ const targets = [{ target_id: 3, path: 'vol0:/bootloader.bin' }];
568
+ const finishedStatus = {
569
+ type: 'DeviceFirmwareUpdateStatus',
570
+ message: {
571
+ records: [
572
+ {
573
+ ...targets[0],
574
+ status: 'FW_MGMT_UPDATER_TASK_STATUS_FINISHED',
575
+ },
576
+ ],
577
+ },
578
+ };
579
+ const typedCall = jest
580
+ .fn()
581
+ .mockRejectedValueOnce(
582
+ ERRORS.TypedError(
583
+ HardwareErrorCode.BleTimeoutError,
584
+ 'Lowlevel response timeout after 15000ms for DeviceFirmwareUpdateStatusGet'
585
+ )
586
+ )
587
+ .mockResolvedValueOnce(finishedStatus)
588
+ .mockResolvedValueOnce(finishedStatus)
589
+ .mockResolvedValueOnce(finishedStatus)
590
+ .mockResolvedValueOnce(finishedStatus);
591
+ const reconnectProtocolV2Device = jest
592
+ .fn()
593
+ .mockRejectedValueOnce(ERRORS.TypedError(HardwareErrorCode.BleTimeoutError))
594
+ .mockResolvedValueOnce(undefined);
595
+ const setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(((
596
+ callback: () => void
597
+ ) => {
598
+ callback();
599
+ return 0 as any;
600
+ }) as typeof setTimeout);
601
+
602
+ method.device = {
603
+ getCommands: () => ({ typedCall, cancelDevice: jest.fn() }),
604
+ setCancelableAction: jest.fn(),
605
+ } as unknown as Device;
606
+ method.postProgressMessage = jest.fn();
607
+
608
+ const firmwareUpdate = method as unknown as {
609
+ waitForProtocolV2FirmwareUpdateComplete: (
610
+ value: typeof targets,
611
+ requireCurrentInstallStatus: boolean
612
+ ) => Promise<void>;
613
+ reconnectProtocolV2Device: (options: { skipProtocolProbe: boolean }) => Promise<void>;
614
+ };
615
+ firmwareUpdate.reconnectProtocolV2Device = reconnectProtocolV2Device;
616
+ (method as any).isBleReconnect = jest.fn(() => true);
617
+
618
+ try {
619
+ await firmwareUpdate.waitForProtocolV2FirmwareUpdateComplete(targets, true);
620
+ } finally {
621
+ setTimeoutSpy.mockRestore();
622
+ }
623
+
624
+ expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(2);
625
+ expect(method.postProgressMessage).toHaveBeenNthCalledWith(1, 1, 'installingFirmware');
626
+ expect(method.postProgressMessage).toHaveBeenNthCalledWith(2, 100, 'installingFirmware');
627
+ });
628
+
629
+ test('does not use a reconnect response timeout as BLE install evidence', async () => {
630
+ const method = new FirmwareUpdateV4({
631
+ id: 1,
632
+ payload: {
633
+ method: 'firmwareUpdateV4',
634
+ connectId: 'pro2-ble',
635
+ },
636
+ });
637
+ const targets = [{ target_id: 3, path: 'vol0:/bootloader.bin' }];
638
+ const finishedStatus = {
639
+ type: 'DeviceFirmwareUpdateStatus',
640
+ message: {
641
+ records: [
642
+ {
643
+ ...targets[0],
644
+ status: 'FW_MGMT_UPDATER_TASK_STATUS_FINISHED',
645
+ },
646
+ ],
647
+ },
648
+ };
649
+ const typedCall = jest
650
+ .fn()
651
+ .mockRejectedValueOnce(
652
+ ERRORS.TypedError(
653
+ HardwareErrorCode.BleTimeoutError,
654
+ 'Lowlevel response timeout after 15000ms for DeviceFirmwareUpdateStatusGet'
655
+ )
656
+ )
657
+ .mockResolvedValueOnce(finishedStatus)
658
+ .mockResolvedValueOnce(finishedStatus)
659
+ .mockResolvedValueOnce(finishedStatus)
660
+ .mockResolvedValueOnce(finishedStatus)
661
+ .mockRejectedValueOnce(ERRORS.TypedError(HardwareErrorCode.ActionCancelled));
662
+ const reconnectProtocolV2Device = jest
663
+ .fn()
664
+ .mockRejectedValueOnce(
665
+ ERRORS.TypedError(
666
+ HardwareErrorCode.BleTimeoutError,
667
+ 'device was disconnected after Lowlevel response timeout'
668
+ )
669
+ )
670
+ .mockResolvedValueOnce(undefined);
671
+ const setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(((
672
+ callback: () => void
673
+ ) => {
674
+ callback();
675
+ return 0 as any;
676
+ }) as typeof setTimeout);
677
+
678
+ method.device = {
679
+ getCommands: () => ({ typedCall, cancelDevice: jest.fn() }),
680
+ setCancelableAction: jest.fn(),
681
+ } as unknown as Device;
682
+ method.postProgressMessage = jest.fn();
683
+
684
+ const firmwareUpdate = method as unknown as {
685
+ waitForProtocolV2FirmwareUpdateComplete: (
686
+ value: typeof targets,
687
+ requireCurrentInstallStatus: boolean
688
+ ) => Promise<void>;
689
+ reconnectProtocolV2Device: (options: { skipProtocolProbe: boolean }) => Promise<void>;
690
+ };
691
+ firmwareUpdate.reconnectProtocolV2Device = reconnectProtocolV2Device;
692
+ (method as any).isBleReconnect = jest.fn(() => true);
693
+
694
+ try {
695
+ await expect(
696
+ firmwareUpdate.waitForProtocolV2FirmwareUpdateComplete(targets, true)
697
+ ).rejects.toMatchObject({
698
+ errorCode: HardwareErrorCode.ActionCancelled,
699
+ });
700
+ } finally {
701
+ setTimeoutSpy.mockRestore();
702
+ }
703
+
704
+ expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(2);
705
+ expect(method.postProgressMessage).not.toHaveBeenCalled();
706
+ });
707
+
407
708
  test('rejects stable stale finished BLE status after a status response timeout', async () => {
408
709
  const method = new FirmwareUpdateV4({
409
710
  id: 1,
@@ -5686,6 +5686,7 @@ describe('Protocol V2 firmware update targets', () => {
5686
5686
  );
5687
5687
  expect(typedCall).not.toHaveBeenCalledWith('DeviceFirmwareUpdateRequest', 'Success', {});
5688
5688
  expect((method as any).protocolV2InstallNeedsReconnect).toBe(true);
5689
+ expect((method as any).protocolV2InstallDisconnectObserved).toBe(true);
5689
5690
  });
5690
5691
 
5691
5692
  test.each([
@@ -18,6 +18,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
18
18
  private protocolV2LatestFinalDeviceInfo?;
19
19
  private protocolV2InstallBaselineVersions;
20
20
  private protocolV2InstallNeedsReconnect;
21
+ private protocolV2InstallDisconnectObserved;
21
22
  private protocolV2InstallTerminalSuccessObserved;
22
23
  private protocolV2LastRuntimeProbeFeatures?;
23
24
  private protocolV2LastTransferProgress?;
@@ -1 +1 @@
1
- {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -52302,6 +52302,13 @@ const isProtocolV2FirmwareStatusEndpointUnavailable = (error) => {
52302
52302
  message.includes('message handler not found') ||
52303
52303
  message.includes('unsupported message'));
52304
52304
  };
52305
+ const isProtocolV2InstallResponseTimeout = (error) => {
52306
+ if (!error || typeof error !== 'object')
52307
+ return false;
52308
+ const { code } = error;
52309
+ return (code === 'response-timeout' ||
52310
+ /\bresponse timeout\b/i.test(getProtocolV2UnknownErrorText(error)));
52311
+ };
52305
52312
  const isProtocolV2TerminalInstallStatusError = (error) => {
52306
52313
  var _a;
52307
52314
  return hdShared.isBleStaleBondHardwareError(error) ||
@@ -52429,6 +52436,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52429
52436
  this.protocolV2CompletedTargetIds = new Set();
52430
52437
  this.protocolV2InstallBaselineVersions = new Map();
52431
52438
  this.protocolV2InstallNeedsReconnect = false;
52439
+ this.protocolV2InstallDisconnectObserved = false;
52432
52440
  this.protocolV2InstallTerminalSuccessObserved = false;
52433
52441
  this.protocolV2LastTransferProgressAt = 0;
52434
52442
  }
@@ -53899,15 +53907,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53899
53907
  return __awaiter(this, void 0, void 0, function* () {
53900
53908
  const expectedTargetIds = new Set(targets.map(target => target.target_id));
53901
53909
  const expectedPaths = new Map(targets.map(target => [target.target_id, target.path]));
53902
- const isBleCoprocessorInstall = this.isBleReconnect() &&
53903
- expectedTargetIds.has(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR);
53910
+ const isBleInstall = this.isBleReconnect();
53904
53911
  const startTime = Date.now();
53905
53912
  let lastError;
53906
53913
  let shouldReconnect = this.protocolV2InstallNeedsReconnect;
53907
53914
  this.protocolV2InstallNeedsReconnect = false;
53908
53915
  let deviceInfo;
53909
53916
  let bleInstallLinkReady = false;
53910
- let installStatusDisconnectObserved = false;
53917
+ let installStatusDisconnectObserved = isBleInstall && this.protocolV2InstallDisconnectObserved;
53918
+ this.protocolV2InstallDisconnectObserved = false;
53911
53919
  let installReconnectObserved = false;
53912
53920
  let finishedStatusSnapshotKey;
53913
53921
  let finishedStatusSnapshotPolls = 0;
@@ -53915,6 +53923,17 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53915
53923
  let installEvidenceObserved = this.protocolV2InstallTerminalSuccessObserved;
53916
53924
  let currentInstallStatusObserved = false;
53917
53925
  const liveTargetIds = new Set();
53926
+ const recordBleInstallDisconnect = (error) => {
53927
+ if (!isBleInstall ||
53928
+ !isProtocolV2DeviceDisconnectedError(error) ||
53929
+ isProtocolV2InstallResponseTimeout(error)) {
53930
+ return;
53931
+ }
53932
+ installStatusDisconnectObserved = true;
53933
+ installReconnectObserved = false;
53934
+ finishedStatusSnapshotKey = undefined;
53935
+ finishedStatusSnapshotPolls = 0;
53936
+ };
53918
53937
  while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
53919
53938
  this.throwIfAborted();
53920
53939
  try {
@@ -54101,13 +54120,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54101
54120
  }
54102
54121
  }
54103
54122
  else {
54104
- if (isBleCoprocessorInstall &&
54105
- isProtocolV2DeviceDisconnectedError(error) &&
54106
- !isProtocolV2ResponseTimeout(error)) {
54107
- installStatusDisconnectObserved = true;
54108
- finishedStatusSnapshotKey = undefined;
54109
- finishedStatusSnapshotPolls = 0;
54110
- }
54123
+ recordBleInstallDisconnect(error);
54111
54124
  shouldReconnect = true;
54112
54125
  deviceInfo = undefined;
54113
54126
  bleInstallLinkReady = false;
@@ -54128,6 +54141,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54128
54141
  ((_b = error.params) === null || _b === void 0 ? void 0 : _b.firmwareUpdateCode) === 'FirmwareInstallStatusUnavailable') {
54129
54142
  throw error;
54130
54143
  }
54144
+ recordBleInstallDisconnect(error);
54131
54145
  shouldReconnect = true;
54132
54146
  deviceInfo = undefined;
54133
54147
  bleInstallLinkReady = false;
@@ -54377,6 +54391,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54377
54391
  return __awaiter(this, void 0, void 0, function* () {
54378
54392
  this.protocolV2LastRuntimeProbeFeatures = undefined;
54379
54393
  this.protocolV2InstallNeedsReconnect = false;
54394
+ this.protocolV2InstallDisconnectObserved = false;
54380
54395
  this.protocolV2InstallTerminalSuccessObserved = false;
54381
54396
  const commands = this.device.getCommands();
54382
54397
  yield commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
@@ -54404,6 +54419,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54404
54419
  }
54405
54420
  Log$6.log('[FirmwareUpdateV4] transport released while writing install request; continue status polling');
54406
54421
  this.protocolV2InstallNeedsReconnect = true;
54422
+ this.protocolV2InstallDisconnectObserved = !isProtocolV2InstallResponseTimeout(error);
54407
54423
  }
54408
54424
  });
54409
54425
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-core",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Core processes and APIs for communicating with OneKey hardware devices.",
5
5
  "author": "OneKey",
6
6
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
@@ -25,8 +25,8 @@
25
25
  "url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-shared": "1.2.0",
29
- "@onekeyfe/hd-transport": "1.2.0",
28
+ "@onekeyfe/hd-shared": "1.2.1",
29
+ "@onekeyfe/hd-transport": "1.2.1",
30
30
  "axios": "1.15.2",
31
31
  "bignumber.js": "^9.0.2",
32
32
  "buffer": "^6.0.3",
@@ -46,5 +46,5 @@
46
46
  "@types/w3c-web-usb": "^1.0.10",
47
47
  "@types/web-bluetooth": "^0.0.21"
48
48
  },
49
- "gitHead": "cc51df0a415bead21304ad1d8bc92b5312c91344"
49
+ "gitHead": "43d2856e593a93fbf056fdb334e0fe407a79cdc0"
50
50
  }
@@ -374,6 +374,15 @@ const isProtocolV2FirmwareStatusEndpointUnavailable = (error: unknown) => {
374
374
  );
375
375
  };
376
376
 
377
+ const isProtocolV2InstallResponseTimeout = (error: unknown) => {
378
+ if (!error || typeof error !== 'object') return false;
379
+ const { code } = error as { code?: number | string };
380
+ return (
381
+ code === 'response-timeout' ||
382
+ /\bresponse timeout\b/i.test(getProtocolV2UnknownErrorText(error))
383
+ );
384
+ };
385
+
377
386
  const isProtocolV2TerminalInstallStatusError = (error: unknown) =>
378
387
  isBleStaleBondHardwareError(error) ||
379
388
  (error instanceof HardwareError &&
@@ -565,6 +574,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
565
574
 
566
575
  private protocolV2InstallNeedsReconnect = false;
567
576
 
577
+ private protocolV2InstallDisconnectObserved = false;
578
+
568
579
  private protocolV2InstallTerminalSuccessObserved = false;
569
580
 
570
581
  private protocolV2LastRuntimeProbeFeatures?: Features;
@@ -2517,9 +2528,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2517
2528
  ) {
2518
2529
  const expectedTargetIds = new Set(targets.map(target => target.target_id));
2519
2530
  const expectedPaths = new Map(targets.map(target => [target.target_id, target.path]));
2520
- const isBleCoprocessorInstall =
2521
- this.isBleReconnect() &&
2522
- expectedTargetIds.has(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR);
2531
+ const isBleInstall = this.isBleReconnect();
2523
2532
  const startTime = Date.now();
2524
2533
  let lastError: unknown;
2525
2534
  // The loader may release either USB or BLE as installation starts. Recovery reconnects
@@ -2528,7 +2537,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2528
2537
  this.protocolV2InstallNeedsReconnect = false;
2529
2538
  let deviceInfo: ProtocolV2DeviceInfo | undefined;
2530
2539
  let bleInstallLinkReady = false;
2531
- let installStatusDisconnectObserved = false;
2540
+ let installStatusDisconnectObserved = isBleInstall && this.protocolV2InstallDisconnectObserved;
2541
+ this.protocolV2InstallDisconnectObserved = false;
2532
2542
  let installReconnectObserved = false;
2533
2543
  let finishedStatusSnapshotKey: string | undefined;
2534
2544
  let finishedStatusSnapshotPolls = 0;
@@ -2536,6 +2546,19 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2536
2546
  let installEvidenceObserved = this.protocolV2InstallTerminalSuccessObserved;
2537
2547
  let currentInstallStatusObserved = false;
2538
2548
  const liveTargetIds = new Set<number>();
2549
+ const recordBleInstallDisconnect = (error: unknown) => {
2550
+ if (
2551
+ !isBleInstall ||
2552
+ !isProtocolV2DeviceDisconnectedError(error) ||
2553
+ isProtocolV2InstallResponseTimeout(error)
2554
+ ) {
2555
+ return;
2556
+ }
2557
+ installStatusDisconnectObserved = true;
2558
+ installReconnectObserved = false;
2559
+ finishedStatusSnapshotKey = undefined;
2560
+ finishedStatusSnapshotPolls = 0;
2561
+ };
2539
2562
 
2540
2563
  while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
2541
2564
  // A transport release caused by an explicit workflow cancellation must not
@@ -2787,15 +2810,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2787
2810
  );
2788
2811
  }
2789
2812
  } else {
2790
- if (
2791
- isBleCoprocessorInstall &&
2792
- isProtocolV2DeviceDisconnectedError(error) &&
2793
- !isProtocolV2ResponseTimeout(error)
2794
- ) {
2795
- installStatusDisconnectObserved = true;
2796
- finishedStatusSnapshotKey = undefined;
2797
- finishedStatusSnapshotPolls = 0;
2798
- }
2813
+ recordBleInstallDisconnect(error);
2799
2814
  shouldReconnect = true;
2800
2815
  deviceInfo = undefined;
2801
2816
  bleInstallLinkReady = false;
@@ -2820,6 +2835,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2820
2835
  ) {
2821
2836
  throw error;
2822
2837
  }
2838
+ recordBleInstallDisconnect(error);
2823
2839
  shouldReconnect = true;
2824
2840
  deviceInfo = undefined;
2825
2841
  bleInstallLinkReady = false;
@@ -3154,6 +3170,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
3154
3170
  }) {
3155
3171
  this.protocolV2LastRuntimeProbeFeatures = undefined;
3156
3172
  this.protocolV2InstallNeedsReconnect = false;
3173
+ this.protocolV2InstallDisconnectObserved = false;
3157
3174
  this.protocolV2InstallTerminalSuccessObserved = false;
3158
3175
  const commands = this.device.getCommands();
3159
3176
  await commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
@@ -3196,6 +3213,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
3196
3213
  '[FirmwareUpdateV4] transport released while writing install request; continue status polling'
3197
3214
  );
3198
3215
  this.protocolV2InstallNeedsReconnect = true;
3216
+ this.protocolV2InstallDisconnectObserved = !isProtocolV2InstallResponseTimeout(error);
3199
3217
  }
3200
3218
  }
3201
3219