@onekeyfe/hd-core 1.2.0-alpha.140 → 1.2.0-alpha.142
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__/device-lifecycle-events.test.ts +5 -3
- package/__tests__/device-wallet-session-store.test.ts +147 -21
- package/__tests__/protocol-v2.test.ts +209 -13
- package/dist/api/FirmwareUpdateV4.d.ts +4 -1
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -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/index.d.ts +1 -1
- package/dist/index.js +75 -70
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +67 -58
- package/src/device/Device.ts +55 -9
- package/src/device/DeviceConnector.ts +4 -1
|
@@ -105,6 +105,7 @@ const PROTOCOL_V2_CONNECT_POLL_INTERVAL = 500;
|
|
|
105
105
|
const PROTOCOL_V2_CONNECT_SINGLE_TIMEOUT = 75 * 1000;
|
|
106
106
|
const PROTOCOL_V2_DEVICE_INFO_READY_TIMEOUT = 30 * 1000;
|
|
107
107
|
const PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT = 3;
|
|
108
|
+
const PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS = 1000;
|
|
108
109
|
const PROTOCOL_V2_INSTALL_STATUS_CONFLICT_CODE = 'FirmwareInstallStatusConflict';
|
|
109
110
|
const PROTOCOL_V2_INSTALL_FAILED_CODE = 'FirmwareInstallFailed';
|
|
110
111
|
const PROTOCOL_V2_INSTALL_TIMEOUT_CODE = 'FirmwareInstallTimeout';
|
|
@@ -594,10 +595,16 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
594
595
|
|
|
595
596
|
private protocolV2LatestFinalFeatures?: Features;
|
|
596
597
|
|
|
598
|
+
private protocolV2LatestFinalDeviceInfo?: ProtocolV2DeviceInfo;
|
|
599
|
+
|
|
597
600
|
private protocolV2InstallBaselineVersions = new Map<number, string>();
|
|
598
601
|
|
|
599
602
|
private protocolV2LastRuntimeProbeFeatures?: Features;
|
|
600
603
|
|
|
604
|
+
private protocolV2LastTransferProgress?: number;
|
|
605
|
+
|
|
606
|
+
private protocolV2LastTransferProgressAt = 0;
|
|
607
|
+
|
|
601
608
|
init() {
|
|
602
609
|
this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
|
|
603
610
|
this.requireDeviceMode = [];
|
|
@@ -1598,21 +1605,20 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1598
1605
|
const expected = this.params?.expectedTargetVersions;
|
|
1599
1606
|
if (!expected) return;
|
|
1600
1607
|
const features = this.protocolV2LatestFinalFeatures;
|
|
1601
|
-
const
|
|
1602
|
-
const applicationTargets = requestedTargets.filter(
|
|
1603
|
-
target => target === 'app_v1' || target === 'app_v2'
|
|
1604
|
-
);
|
|
1608
|
+
const deviceInfo = this.protocolV2LatestFinalDeviceInfo;
|
|
1605
1609
|
const visibleVersions: Partial<Record<FirmwareUpdateV4Target, string>> = {
|
|
1606
1610
|
boot: features ? getDeviceBootloaderVersion(features).join('.') : undefined,
|
|
1611
|
+
// Protocol V2 firmware exposes P1 as the device firmware version after reboot.
|
|
1612
|
+
app_v1: features
|
|
1613
|
+
? getDeviceFirmwareVersion(features).join('.')
|
|
1614
|
+
: deviceInfo?.main_mcu?.application?.version,
|
|
1615
|
+
app_v2: deviceInfo?.main_mcu?.application_data?.version,
|
|
1607
1616
|
coprocessor: features ? getDeviceBLEFirmwareVersion(features).join('.') : undefined,
|
|
1608
1617
|
se01: features?.se01Version ?? undefined,
|
|
1609
1618
|
se02: features?.se02Version ?? undefined,
|
|
1610
1619
|
se03: features?.se03Version ?? undefined,
|
|
1611
1620
|
se04: features?.se04Version ?? undefined,
|
|
1612
1621
|
};
|
|
1613
|
-
if (features && applicationTargets.length === 1) {
|
|
1614
|
-
visibleVersions[applicationTargets[0]] = getDeviceFirmwareVersion(features).join('.');
|
|
1615
|
-
}
|
|
1616
1622
|
const expectedEntries = (
|
|
1617
1623
|
Object.entries(expected) as Array<[FirmwareUpdateV4Target, string]>
|
|
1618
1624
|
).filter(([target]) => !targets || targets.includes(target));
|
|
@@ -1629,14 +1635,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1629
1635
|
Math.floor(statusVersion / 0x100) % 0x100
|
|
1630
1636
|
}.${statusVersion % 0x100}`;
|
|
1631
1637
|
if (!observedVersion) {
|
|
1632
|
-
const requestedTargetIds = requestedTargets.flatMap(requestedTarget => {
|
|
1633
|
-
if (requestedTarget === 'resource' || requestedTarget === 'boot_resources') return [];
|
|
1634
|
-
const installTarget = PROTOCOL_V2_INSTALL_TARGET_BY_UPDATE_TARGET.get(requestedTarget);
|
|
1635
|
-
return installTarget ? [installTarget.targetId] : [];
|
|
1636
|
-
});
|
|
1637
1638
|
const hasCompleteTargetEvidence =
|
|
1638
|
-
|
|
1639
|
-
requestedTargetIds.every(targetId => this.protocolV2CompletedTargetIds.has(targetId));
|
|
1639
|
+
targetId !== undefined && this.protocolV2CompletedTargetIds.has(targetId);
|
|
1640
1640
|
if (hasCompleteTargetEvidence) {
|
|
1641
1641
|
Log.warn(
|
|
1642
1642
|
`Protocol V2 target ${target} has no observable final version; install completion is authoritative`
|
|
@@ -1656,28 +1656,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1656
1656
|
}
|
|
1657
1657
|
}
|
|
1658
1658
|
|
|
1659
|
-
private getProtocolV2RequestedTargets(): FirmwareUpdateV4Target[] {
|
|
1660
|
-
if (this.params.targetsToUpdate?.length) {
|
|
1661
|
-
return [...new Set(this.params.targetsToUpdate)];
|
|
1662
|
-
}
|
|
1663
|
-
if (this.params.preparedPlan?.targetsToUpdate.length) {
|
|
1664
|
-
return [...new Set(this.params.preparedPlan.targetsToUpdate)] as FirmwareUpdateV4Target[];
|
|
1665
|
-
}
|
|
1666
|
-
const targets = new Set<FirmwareUpdateV4Target>();
|
|
1667
|
-
Object.keys(this.params.componentArtifacts ?? {}).forEach(target =>
|
|
1668
|
-
targets.add(target as FirmwareUpdateV4Target)
|
|
1669
|
-
);
|
|
1670
|
-
if (this.params.bootloaderBinary) targets.add('boot');
|
|
1671
|
-
if (this.params.applicationP1Binary) targets.add('app_v1');
|
|
1672
|
-
if (this.params.applicationP2Binary) targets.add('app_v2');
|
|
1673
|
-
if (this.params.coprocessorBinary) targets.add('coprocessor');
|
|
1674
|
-
if (this.params.se01Binary) targets.add('se01');
|
|
1675
|
-
if (this.params.se02Binary) targets.add('se02');
|
|
1676
|
-
if (this.params.se03Binary) targets.add('se03');
|
|
1677
|
-
if (this.params.se04Binary) targets.add('se04');
|
|
1678
|
-
return Array.from(targets);
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
1659
|
private async getProtocolV2DeviceFeatures(): Promise<Features> {
|
|
1682
1660
|
let { features } = this.device;
|
|
1683
1661
|
if (typeof this.device.getFeatures === 'function') {
|
|
@@ -1987,13 +1965,15 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1987
1965
|
? PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId)
|
|
1988
1966
|
: undefined;
|
|
1989
1967
|
if (updateTarget && targetsToUpdate.has(updateTarget)) {
|
|
1990
|
-
if (component.version) {
|
|
1991
|
-
this.params.expectedTargetVersions ??= {};
|
|
1992
|
-
this.params.expectedTargetVersions[updateTarget] = component.version.join('.');
|
|
1993
|
-
}
|
|
1994
1968
|
const explicitInstallItem = explicitInstallItemByTargetId.get(target.targetId);
|
|
1995
|
-
|
|
1996
|
-
|
|
1969
|
+
let installItem = explicitInstallItem;
|
|
1970
|
+
if (!installItem) {
|
|
1971
|
+
installItem = await this.downloadRemoteProtocolV2Component(key, component);
|
|
1972
|
+
if (component.version) {
|
|
1973
|
+
this.params.expectedTargetVersions ??= {};
|
|
1974
|
+
this.params.expectedTargetVersions[updateTarget] = component.version.join('.');
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1997
1977
|
if (installItem.kind === 'bootloader') {
|
|
1998
1978
|
bootloaderBinary = installItem.binary;
|
|
1999
1979
|
} else {
|
|
@@ -2362,6 +2342,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2362
2342
|
}
|
|
2363
2343
|
|
|
2364
2344
|
this.postTipMessage(FirmwareUpdateTipMessage.StartTransferData);
|
|
2345
|
+
this.protocolV2LastTransferProgress = undefined;
|
|
2346
|
+
this.protocolV2LastTransferProgressAt = 0;
|
|
2365
2347
|
let processedSize = 0;
|
|
2366
2348
|
for (const resource of resourcesToSync) {
|
|
2367
2349
|
// The bootloader keeps its live resource package mounted. FatFs rejects
|
|
@@ -2458,18 +2440,25 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2458
2440
|
);
|
|
2459
2441
|
}
|
|
2460
2442
|
const transferredBytes = processedSize + chunkEnd;
|
|
2461
|
-
const
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2443
|
+
const now = Date.now();
|
|
2444
|
+
const elapsedMs = Math.max(now - transferStartedAt, 0);
|
|
2445
|
+
const progress = Math.min(Math.ceil((transferredBytes / totalSize) * 100), 99);
|
|
2446
|
+
const shouldPostProgress =
|
|
2447
|
+
progress !== this.protocolV2LastTransferProgress ||
|
|
2448
|
+
now - this.protocolV2LastTransferProgressAt >=
|
|
2449
|
+
PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS ||
|
|
2450
|
+
chunkEnd === source.size;
|
|
2451
|
+
if (shouldPostProgress) {
|
|
2452
|
+
this.protocolV2LastTransferProgress = progress;
|
|
2453
|
+
this.protocolV2LastTransferProgressAt = now;
|
|
2454
|
+
this.postProgressMessage(progress, 'transferData', {
|
|
2466
2455
|
transferredBytes,
|
|
2467
2456
|
totalBytes: totalSize,
|
|
2468
2457
|
rateBytesPerSecond:
|
|
2469
2458
|
elapsedMs > 0 ? Math.round((chunkEnd / elapsedMs) * 1000) : undefined,
|
|
2470
2459
|
elapsedMs,
|
|
2471
|
-
}
|
|
2472
|
-
|
|
2460
|
+
});
|
|
2461
|
+
}
|
|
2473
2462
|
return length;
|
|
2474
2463
|
},
|
|
2475
2464
|
});
|
|
@@ -2525,9 +2514,13 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2525
2514
|
path: failedTarget.path,
|
|
2526
2515
|
});
|
|
2527
2516
|
Log.error(`[FirmwareUpdateV4] firmware install failed target=${failedTargetDetails}`);
|
|
2528
|
-
throw ERRORS.TypedError(
|
|
2529
|
-
|
|
2530
|
-
|
|
2517
|
+
throw ERRORS.TypedError(
|
|
2518
|
+
HardwareErrorCode.FirmwareError,
|
|
2519
|
+
'Protocol V2 firmware install failed',
|
|
2520
|
+
{
|
|
2521
|
+
firmwareUpdateCode: PROTOCOL_V2_INSTALL_FAILED_CODE,
|
|
2522
|
+
}
|
|
2523
|
+
);
|
|
2531
2524
|
}
|
|
2532
2525
|
|
|
2533
2526
|
const matchingTargets = statusTargets.filter(target =>
|
|
@@ -2542,9 +2535,13 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2542
2535
|
(target.path && expectedPaths.get(targetId) && target.path !== expectedPaths.get(targetId))
|
|
2543
2536
|
) {
|
|
2544
2537
|
Log.error(`[FirmwareUpdateV4] install status conflicts with target=${target.target_id}`);
|
|
2545
|
-
throw ERRORS.TypedError(
|
|
2546
|
-
|
|
2547
|
-
|
|
2538
|
+
throw ERRORS.TypedError(
|
|
2539
|
+
HardwareErrorCode.FirmwareError,
|
|
2540
|
+
'Protocol V2 firmware install status conflict',
|
|
2541
|
+
{
|
|
2542
|
+
firmwareUpdateCode: PROTOCOL_V2_INSTALL_STATUS_CONFLICT_CODE,
|
|
2543
|
+
}
|
|
2544
|
+
);
|
|
2548
2545
|
}
|
|
2549
2546
|
seenTargetIds.add(targetId);
|
|
2550
2547
|
}
|
|
@@ -2657,6 +2654,10 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2657
2654
|
});
|
|
2658
2655
|
}
|
|
2659
2656
|
|
|
2657
|
+
private recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds: Set<number>) {
|
|
2658
|
+
expectedTargetIds.forEach(targetId => this.protocolV2CompletedTargetIds.add(targetId));
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2660
2661
|
private async waitForProtocolV2FirmwareUpdateComplete(
|
|
2661
2662
|
targets: Array<{ target_id: number; path: string }>,
|
|
2662
2663
|
requireCurrentInstallStatus = false
|
|
@@ -2760,6 +2761,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2760
2761
|
Log.log(
|
|
2761
2762
|
'[FirmwareUpdateV4] empty firmware status after confirmed App reboot; update complete'
|
|
2762
2763
|
);
|
|
2764
|
+
this.recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds);
|
|
2763
2765
|
this.postProgressMessage(100, 'installingFirmware');
|
|
2764
2766
|
return;
|
|
2765
2767
|
}
|
|
@@ -2807,6 +2809,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2807
2809
|
Log.log(
|
|
2808
2810
|
'[FirmwareUpdateV4] firmware status endpoint unavailable after confirmed App reboot'
|
|
2809
2811
|
);
|
|
2812
|
+
this.recordProtocolV2AuthoritativeInstallCompletion(expectedTargetIds);
|
|
2810
2813
|
this.postProgressMessage(100, 'installingFirmware');
|
|
2811
2814
|
return;
|
|
2812
2815
|
}
|
|
@@ -2855,9 +2858,13 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2855
2858
|
PROTOCOL_V2_INSTALL_TIMEOUT / 1000
|
|
2856
2859
|
}s: ${this.normalizeErrorMessage(lastError)}`
|
|
2857
2860
|
);
|
|
2858
|
-
throw ERRORS.TypedError(
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
+
throw ERRORS.TypedError(
|
|
2862
|
+
HardwareErrorCode.FirmwareError,
|
|
2863
|
+
'Protocol V2 firmware install timed out',
|
|
2864
|
+
{
|
|
2865
|
+
firmwareUpdateCode: PROTOCOL_V2_INSTALL_TIMEOUT_CODE,
|
|
2866
|
+
}
|
|
2867
|
+
);
|
|
2861
2868
|
}
|
|
2862
2869
|
|
|
2863
2870
|
private async exitProtocolV2BootloaderToNormal() {
|
|
@@ -2931,6 +2938,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2931
2938
|
const startTime = Date.now();
|
|
2932
2939
|
let lastError: unknown;
|
|
2933
2940
|
let shouldReconnect = true;
|
|
2941
|
+
this.protocolV2LatestFinalDeviceInfo = undefined;
|
|
2934
2942
|
|
|
2935
2943
|
while (Date.now() - startTime < timeout) {
|
|
2936
2944
|
try {
|
|
@@ -2951,6 +2959,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2951
2959
|
{ forceRuntimeContextRefresh: true }
|
|
2952
2960
|
);
|
|
2953
2961
|
if (this.isProtocolV2ApplicationMode(features)) {
|
|
2962
|
+
this.protocolV2LatestFinalDeviceInfo = deviceInfo;
|
|
2954
2963
|
return features;
|
|
2955
2964
|
}
|
|
2956
2965
|
lastError = ERRORS.TypedError(
|
package/src/device/Device.ts
CHANGED
|
@@ -449,7 +449,8 @@ export class Device extends EventEmitter {
|
|
|
449
449
|
undefined,
|
|
450
450
|
true,
|
|
451
451
|
strictProtocol,
|
|
452
|
-
undefined
|
|
452
|
+
undefined,
|
|
453
|
+
options?.forceProtocolDetection
|
|
453
454
|
);
|
|
454
455
|
this.mainId = (acquireResult as any)?.uuid ?? '';
|
|
455
456
|
Log.debug('Expected uuid:', this.mainId);
|
|
@@ -459,7 +460,8 @@ export class Device extends EventEmitter {
|
|
|
459
460
|
this.originalDescriptor.session,
|
|
460
461
|
undefined,
|
|
461
462
|
strictProtocol,
|
|
462
|
-
undefined
|
|
463
|
+
undefined,
|
|
464
|
+
options?.forceProtocolDetection
|
|
463
465
|
);
|
|
464
466
|
this.mainId = acquireResult as string | undefined;
|
|
465
467
|
Log.debug('Expected session id:', this.mainId);
|
|
@@ -930,13 +932,18 @@ export class Device extends EventEmitter {
|
|
|
930
932
|
};
|
|
931
933
|
|
|
932
934
|
const expectedDeviceId = options?.deviceId;
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
//
|
|
935
|
+
|
|
936
|
+
if (expectedDeviceId && !(this.features && this.checkDeviceId(expectedDeviceId))) {
|
|
937
|
+
// No locally-cached evidence that the device at this path is the
|
|
938
|
+
// expected one (first contact, or the cached features already disagree
|
|
939
|
+
// with the caller). Establish identity with a context-free Initialize
|
|
940
|
+
// BEFORE any wallet context (session_id / passphrase_state) goes on
|
|
941
|
+
// the wire. In normal flows features are always fresh — enumerate /
|
|
942
|
+
// getFeatures run first and every call response refreshes them — so
|
|
943
|
+
// this extra round trip is confined to the ambiguous cases where the
|
|
944
|
+
// disclosure risk actually lives.
|
|
936
945
|
this.passphraseState = undefined;
|
|
937
|
-
|
|
938
|
-
this._updateFeatures(message);
|
|
939
|
-
await TransportManager.reconfigure(this.features);
|
|
946
|
+
await callInitialize({ is_contains_attach: true });
|
|
940
947
|
if (!this.checkDeviceId(expectedDeviceId)) {
|
|
941
948
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
942
949
|
}
|
|
@@ -960,7 +967,46 @@ export class Device extends EventEmitter {
|
|
|
960
967
|
payload.derive_cardano = true;
|
|
961
968
|
}
|
|
962
969
|
|
|
963
|
-
|
|
970
|
+
if (this.features) {
|
|
971
|
+
// Re-sync the V1 message schema for THIS device before encoding
|
|
972
|
+
// Initialize: the process-global schema may still reflect another
|
|
973
|
+
// device (e.g. legacy-firmware Touch/Mini) on multi-device setups, and
|
|
974
|
+
// a stale legacy schema would silently strip passphrase_state /
|
|
975
|
+
// is_contains_attach from the wire message. Local operation, no wire
|
|
976
|
+
// I/O; a no-op when the schema is unchanged.
|
|
977
|
+
await TransportManager.reconfigure(this.features);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// Initialize's own Features response carries device_id, so the physical
|
|
981
|
+
// device identity is validated on the same round trip instead of via a
|
|
982
|
+
// separate read-only GetFeatures preflight (which doubled the wire cost
|
|
983
|
+
// of every deviceId-carrying call). The method fn has not run yet, so a
|
|
984
|
+
// mismatch still fails before any wallet data can be derived, with the
|
|
985
|
+
// same DeviceCheckDeviceIdError. Wallet-context selection is unchanged:
|
|
986
|
+
// it is decided by the Initialize payload above either way.
|
|
987
|
+
const assertExpectedDeviceIdentity = () => {
|
|
988
|
+
if (expectedDeviceId && !this.checkDeviceId(expectedDeviceId)) {
|
|
989
|
+
// The mismatched Initialize may have cached a session under the wrong
|
|
990
|
+
// device's identity; drop it so no wallet context survives from it.
|
|
991
|
+
// (This also evicts any session the wrong device legitimately cached
|
|
992
|
+
// under the same passphraseState — a deliberate conservative purge
|
|
993
|
+
// after a physical-swap event, consistent with
|
|
994
|
+
// reconcileDeviceIdentity purging the previous device's sessions.)
|
|
995
|
+
this.clearInternalState();
|
|
996
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
try {
|
|
1001
|
+
await callInitialize(payload, options?.initSession);
|
|
1002
|
+
} catch (error) {
|
|
1003
|
+
// callInitialize can fail AFTER the wire call cached the session (e.g.
|
|
1004
|
+
// TransportManager.reconfigure rejecting); the identity check must
|
|
1005
|
+
// still run so a wrong-device session never survives the error path.
|
|
1006
|
+
assertExpectedDeviceIdentity();
|
|
1007
|
+
throw error;
|
|
1008
|
+
}
|
|
1009
|
+
assertExpectedDeviceIdentity();
|
|
964
1010
|
} catch (error) {
|
|
965
1011
|
Log.error('Initialization failed:', error);
|
|
966
1012
|
throw error;
|
|
@@ -95,7 +95,8 @@ export default class DeviceConnector {
|
|
|
95
95
|
session?: string | null,
|
|
96
96
|
forceCleanRunPromise?: boolean,
|
|
97
97
|
expectedProtocol?: HardwareConnectProtocol,
|
|
98
|
-
protocolHint?: HardwareConnectProtocol
|
|
98
|
+
protocolHint?: HardwareConnectProtocol,
|
|
99
|
+
forceProtocolDetection?: boolean
|
|
99
100
|
) {
|
|
100
101
|
Log.debug('acquire', path, session, expectedProtocol, protocolHint);
|
|
101
102
|
const env = DataManager.getSettings('env');
|
|
@@ -108,6 +109,7 @@ export default class DeviceConnector {
|
|
|
108
109
|
forceCleanRunPromise,
|
|
109
110
|
expectedProtocol,
|
|
110
111
|
protocolHint,
|
|
112
|
+
forceProtocolDetection,
|
|
111
113
|
});
|
|
112
114
|
} else {
|
|
113
115
|
res = await transport.acquire({
|
|
@@ -115,6 +117,7 @@ export default class DeviceConnector {
|
|
|
115
117
|
previous: session ?? null,
|
|
116
118
|
expectedProtocol,
|
|
117
119
|
protocolHint,
|
|
120
|
+
forceProtocolDetection,
|
|
118
121
|
});
|
|
119
122
|
}
|
|
120
123
|
if (expectedProtocol) {
|