@onekeyfe/hd-core 1.2.2-alpha.0 → 1.2.2-alpha.100
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__/AllNetworkGetAddressBase.tracing.test.ts +4 -20
- package/__tests__/DeviceCommands.test.ts +0 -13
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +2 -0
- package/__tests__/check-firmware-release-protocol-v2.test.ts +2 -0
- package/__tests__/device-lifecycle-events.test.ts +0 -19
- package/__tests__/deviceUploadNft.test.ts +0 -41
- package/__tests__/evmSignTypedData.test.ts +0 -42
- package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +12 -524
- package/__tests__/open-wallet-session.test.ts +1 -127
- package/__tests__/protocol-v2-resources.test.ts +4 -7
- package/__tests__/protocol-v2-unlock-policy.test.ts +1 -35
- package/__tests__/protocol-v2.test.ts +27 -673
- package/dist/api/FirmwareUpdateV4.d.ts +0 -3
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +2 -2
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +2 -2
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/device/Device.d.ts +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/events/ui-request.d.ts +0 -3
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/index.d.ts +5 -10
- package/dist/index.js +398 -1116
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +0 -2
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/walletSession.d.ts +0 -3
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/types/settings.d.ts +2 -2
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +0 -3
- package/dist/utils/deviceFeaturesUtils.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 +75 -416
- package/src/api/OpenWalletSession.ts +9 -39
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +1 -2
- package/src/api/evm/EVMSignTypedData.ts +0 -1
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +3 -9
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +1 -7
- package/src/api/protocol-v2/DeviceUploadNft.ts +8 -28
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +8 -19
- package/src/api/protocol-v2/helpers.ts +0 -8
- package/src/core/index.ts +10 -121
- package/src/data/messages/messages-protocol-v2.json +1 -111
- package/src/device/Device.ts +1 -3
- package/src/device/DeviceConnector.ts +3 -7
- package/src/events/ui-request.ts +0 -3
- package/src/protocols/protocol-v2/resources.ts +1 -9
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +1 -8
- package/src/protocols/protocol-v2/walletSession.ts +22 -65
- package/src/types/settings.ts +2 -4
- package/src/utils/deviceFeaturesUtils.ts +0 -4
- package/__tests__/pro2HostAssetPackage.test.ts +0 -58
- package/dist/utils/pro2HostAssetPackage.d.ts +0 -8
- package/dist/utils/pro2HostAssetPackage.d.ts.map +0 -1
- package/src/utils/pro2HostAssetPackage.ts +0 -315
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EDeviceType,
|
|
3
|
-
ERRORS,
|
|
4
|
-
HardwareError,
|
|
5
|
-
HardwareErrorCode,
|
|
6
|
-
isBleStaleBondHardwareError,
|
|
7
|
-
wait,
|
|
8
|
-
} from '@onekeyfe/hd-shared';
|
|
1
|
+
import { EDeviceType, ERRORS, HardwareError, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
|
|
9
2
|
import JSZip from 'jszip';
|
|
10
3
|
import {
|
|
11
4
|
DeviceRebootType,
|
|
@@ -51,7 +44,6 @@ import {
|
|
|
51
44
|
getProtocolV2UnknownErrorText,
|
|
52
45
|
isProtocolV2DeviceDisconnectedError,
|
|
53
46
|
} from './protocol-v2/helpers';
|
|
54
|
-
import { isProtocolV2ResponseTimeout } from './helpers/protocolV2FileWrite';
|
|
55
47
|
import {
|
|
56
48
|
openFirmwareByteSource,
|
|
57
49
|
readFirmwareByteSourceFully,
|
|
@@ -63,7 +55,6 @@ import {
|
|
|
63
55
|
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
64
56
|
validateFirmwareUpdatePreparedPlan,
|
|
65
57
|
} from './firmware/FirmwareUpdatePreparedPlan';
|
|
66
|
-
|
|
67
58
|
import type {
|
|
68
59
|
FirmwareArtifactReference,
|
|
69
60
|
FirmwareUpdateV4Params,
|
|
@@ -93,7 +84,6 @@ const PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT = 5 * 1000;
|
|
|
93
84
|
const PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT = 15 * 1000;
|
|
94
85
|
const PROTOCOL_V2_INSTALL_TIMEOUT = 5 * 60 * 1000;
|
|
95
86
|
const PROTOCOL_V2_INSTALL_STATUS_INITIAL_DELAY = 1000;
|
|
96
|
-
const PROTOCOL_V2_INSTALL_FINISHED_AFTER_DISCONNECT_POLLS = 4;
|
|
97
87
|
const PROTOCOL_V2_TARGET_STATUS_PENDING = 0;
|
|
98
88
|
const PROTOCOL_V2_TARGET_STATUS_IN_PROGRESS = 1;
|
|
99
89
|
const PROTOCOL_V2_TARGET_STATUS_FINISHED = 2;
|
|
@@ -192,11 +182,6 @@ const getProtocolV2DeviceTransferProgress = (
|
|
|
192
182
|
type ProtocolV2FirmwareUpdateStatusTarget = {
|
|
193
183
|
target_id: number | string;
|
|
194
184
|
status?: number | string;
|
|
195
|
-
progress_percent?: number;
|
|
196
|
-
phase_info?: {
|
|
197
|
-
phase: number | string;
|
|
198
|
-
progress_percent: number;
|
|
199
|
-
};
|
|
200
185
|
payload_version?: number;
|
|
201
186
|
path?: string;
|
|
202
187
|
};
|
|
@@ -375,12 +360,11 @@ const isProtocolV2FirmwareStatusEndpointUnavailable = (error: unknown) => {
|
|
|
375
360
|
};
|
|
376
361
|
|
|
377
362
|
const isProtocolV2TerminalInstallStatusError = (error: unknown) =>
|
|
378
|
-
|
|
379
|
-
(error
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
error.params?.firmwareUpdateCode === PROTOCOL_V2_INSTALL_STATUS_CONFLICT_CODE));
|
|
363
|
+
error instanceof HardwareError &&
|
|
364
|
+
(error.errorCode === HardwareErrorCode.ActionCancelled ||
|
|
365
|
+
error.errorCode === HardwareErrorCode.FirmwareError ||
|
|
366
|
+
error.errorCode === HardwareErrorCode.FirmwareVerificationFailed ||
|
|
367
|
+
error.params?.firmwareUpdateCode === PROTOCOL_V2_INSTALL_STATUS_CONFLICT_CODE);
|
|
384
368
|
|
|
385
369
|
const isProtocolV2TargetStatusFinished = (status: ProtocolV2FirmwareUpdateStatusTarget['status']) =>
|
|
386
370
|
normalizeProtocolV2TargetStatus(status) === PROTOCOL_V2_TARGET_STATUS_FINISHED;
|
|
@@ -417,18 +401,6 @@ const normalizeProtocolV2TargetStatus = (
|
|
|
417
401
|
return undefined;
|
|
418
402
|
};
|
|
419
403
|
|
|
420
|
-
const PROTOCOL_V2_INSTALL_PHASE_BY_DECODED_VALUE = new Map<
|
|
421
|
-
number | string,
|
|
422
|
-
'prepare' | 'install' | 'verify'
|
|
423
|
-
>([
|
|
424
|
-
[0, 'prepare'],
|
|
425
|
-
[1, 'install'],
|
|
426
|
-
[2, 'verify'],
|
|
427
|
-
['FW_MGMT_UPDATER_PHASE_PREPARE', 'prepare'],
|
|
428
|
-
['FW_MGMT_UPDATER_PHASE_INSTALL', 'install'],
|
|
429
|
-
['FW_MGMT_UPDATER_PHASE_VERIFY', 'verify'],
|
|
430
|
-
]);
|
|
431
|
-
|
|
432
404
|
const normalizeProtocolV2Hex = (value?: string) => value?.replace(/^0x/i, '').toLowerCase();
|
|
433
405
|
|
|
434
406
|
const versionArrayToNumber = (version?: IVersionArray) => {
|
|
@@ -486,11 +458,6 @@ const toProtocolV2FiniteNumber = (value: unknown) => {
|
|
|
486
458
|
return undefined;
|
|
487
459
|
};
|
|
488
460
|
|
|
489
|
-
const normalizeProtocolV2ProgressPercent = (value: unknown) => {
|
|
490
|
-
const progress = toProtocolV2FiniteNumber(value);
|
|
491
|
-
return progress === undefined ? undefined : Math.min(100, Math.max(0, progress));
|
|
492
|
-
};
|
|
493
|
-
|
|
494
461
|
export const isProtocolV2FirmwareFingerprintValid = (
|
|
495
462
|
binary: ArrayBuffer | Uint8Array,
|
|
496
463
|
fingerprint: string | undefined
|
|
@@ -563,10 +530,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
563
530
|
|
|
564
531
|
private protocolV2InstallBaselineVersions = new Map<number, string>();
|
|
565
532
|
|
|
566
|
-
private protocolV2InstallNeedsReconnect = false;
|
|
567
|
-
|
|
568
|
-
private protocolV2InstallTerminalSuccessObserved = false;
|
|
569
|
-
|
|
570
533
|
private protocolV2LastRuntimeProbeFeatures?: Features;
|
|
571
534
|
|
|
572
535
|
private protocolV2LastTransferProgress?: number;
|
|
@@ -1845,9 +1808,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1845
1808
|
if (!expectedHeaderHash || header.headerHash !== expectedHeaderHash) return false;
|
|
1846
1809
|
return true;
|
|
1847
1810
|
} catch (error) {
|
|
1848
|
-
if (isBleStaleBondHardwareError(error)) {
|
|
1849
|
-
throw error;
|
|
1850
|
-
}
|
|
1851
1811
|
Log.log(`[FirmwareUpdateV4] RESC bundle ${bundle.name} header check failed: `, error);
|
|
1852
1812
|
return false;
|
|
1853
1813
|
}
|
|
@@ -1941,7 +1901,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1941
1901
|
}
|
|
1942
1902
|
lastError = new Error('Protocol V2 device is reachable but is not in bootloader mode');
|
|
1943
1903
|
} catch (error) {
|
|
1944
|
-
if (
|
|
1904
|
+
if (this.isProtocolV2ReconnectIdentityError(error)) {
|
|
1945
1905
|
throw error;
|
|
1946
1906
|
}
|
|
1947
1907
|
shouldReconnect = true;
|
|
@@ -2223,9 +2183,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2223
2183
|
});
|
|
2224
2184
|
return processedSize + source.size;
|
|
2225
2185
|
} catch (error) {
|
|
2226
|
-
if (isBleStaleBondHardwareError(error)) {
|
|
2227
|
-
throw error;
|
|
2228
|
-
}
|
|
2229
2186
|
lastError = error;
|
|
2230
2187
|
if (attempt < PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
|
|
2231
2188
|
await this.recoverProtocolV2FileTransfer();
|
|
@@ -2255,41 +2212,19 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2255
2212
|
}
|
|
2256
2213
|
}
|
|
2257
2214
|
|
|
2258
|
-
private collectProtocolV2LiveTargetIds(
|
|
2259
|
-
statusTargets: ProtocolV2FirmwareUpdateStatusTarget[],
|
|
2260
|
-
expectedTargetIds: Set<number>,
|
|
2261
|
-
liveTargetIds: Set<number>
|
|
2262
|
-
) {
|
|
2263
|
-
statusTargets.forEach(target => {
|
|
2264
|
-
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
2265
|
-
if (
|
|
2266
|
-
targetId !== undefined &&
|
|
2267
|
-
expectedTargetIds.has(targetId) &&
|
|
2268
|
-
isProtocolV2TargetStatusInProgress(target.status)
|
|
2269
|
-
) {
|
|
2270
|
-
liveTargetIds.add(targetId);
|
|
2271
|
-
}
|
|
2272
|
-
});
|
|
2273
|
-
}
|
|
2274
|
-
|
|
2275
2215
|
private assertProtocolV2TargetStatus(
|
|
2276
2216
|
statusTargets: ProtocolV2FirmwareUpdateStatusTarget[],
|
|
2277
2217
|
expectedTargetIds: Set<number>,
|
|
2278
|
-
expectedPaths
|
|
2279
|
-
liveTargetIds?: Set<number>
|
|
2218
|
+
expectedPaths = new Map<number, string>()
|
|
2280
2219
|
) {
|
|
2281
|
-
const resolvedExpectedPaths = expectedPaths ?? new Map<number, string>();
|
|
2282
2220
|
Log.log(
|
|
2283
2221
|
`[FirmwareUpdateV4] DeviceFirmwareUpdateStatus records=${JSON.stringify(statusTargets)}`
|
|
2284
2222
|
);
|
|
2285
|
-
const failedTarget = statusTargets.find(
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
(!liveTargetIds || liveTargetIds.has(targetId))
|
|
2291
|
-
);
|
|
2292
|
-
});
|
|
2223
|
+
const failedTarget = statusTargets.find(
|
|
2224
|
+
target =>
|
|
2225
|
+
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1) &&
|
|
2226
|
+
isProtocolV2TargetStatusFailed(target.status)
|
|
2227
|
+
);
|
|
2293
2228
|
if (failedTarget) {
|
|
2294
2229
|
const failedTargetDetails = JSON.stringify({
|
|
2295
2230
|
targetId: failedTarget.target_id,
|
|
@@ -2306,27 +2241,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2306
2241
|
}
|
|
2307
2242
|
);
|
|
2308
2243
|
}
|
|
2309
|
-
if (liveTargetIds) {
|
|
2310
|
-
const staleFailedTargets = statusTargets.filter(target => {
|
|
2311
|
-
const targetId = normalizeProtocolV2TargetId(target.target_id) ?? -1;
|
|
2312
|
-
return (
|
|
2313
|
-
expectedTargetIds.has(targetId) &&
|
|
2314
|
-
isProtocolV2TargetStatusFailed(target.status) &&
|
|
2315
|
-
!liveTargetIds.has(targetId)
|
|
2316
|
-
);
|
|
2317
|
-
});
|
|
2318
|
-
if (staleFailedTargets.length > 0) {
|
|
2319
|
-
Log.log(
|
|
2320
|
-
`[FirmwareUpdateV4] ignoring stale failed firmware status until those targets start: ${JSON.stringify(
|
|
2321
|
-
staleFailedTargets.map(target => ({
|
|
2322
|
-
targetId: target.target_id,
|
|
2323
|
-
status: target.status,
|
|
2324
|
-
path: target.path,
|
|
2325
|
-
}))
|
|
2326
|
-
)}`
|
|
2327
|
-
);
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
2244
|
|
|
2331
2245
|
const matchingTargets = statusTargets.filter(target =>
|
|
2332
2246
|
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1)
|
|
@@ -2334,16 +2248,10 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2334
2248
|
const seenTargetIds = new Set<number>();
|
|
2335
2249
|
for (const target of matchingTargets) {
|
|
2336
2250
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
2337
|
-
const pathConflictsWithCurrentInstall =
|
|
2338
|
-
targetId !== undefined &&
|
|
2339
|
-
Boolean(target.path) &&
|
|
2340
|
-
Boolean(resolvedExpectedPaths.get(targetId)) &&
|
|
2341
|
-
target.path !== resolvedExpectedPaths.get(targetId) &&
|
|
2342
|
-
(!liveTargetIds || liveTargetIds.has(targetId));
|
|
2343
2251
|
if (
|
|
2344
2252
|
targetId === undefined ||
|
|
2345
2253
|
seenTargetIds.has(targetId) ||
|
|
2346
|
-
|
|
2254
|
+
(target.path && expectedPaths.get(targetId) && target.path !== expectedPaths.get(targetId))
|
|
2347
2255
|
) {
|
|
2348
2256
|
Log.error(`[FirmwareUpdateV4] install status conflicts with target=${target.target_id}`);
|
|
2349
2257
|
throw ERRORS.TypedError(
|
|
@@ -2356,13 +2264,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2356
2264
|
}
|
|
2357
2265
|
seenTargetIds.add(targetId);
|
|
2358
2266
|
}
|
|
2359
|
-
const completedTargets = matchingTargets.filter(target =>
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
isProtocolV2TargetStatusFinished(target.status) &&
|
|
2363
|
-
(!liveTargetIds || (targetId !== undefined && liveTargetIds.has(targetId)))
|
|
2364
|
-
);
|
|
2365
|
-
});
|
|
2267
|
+
const completedTargets = matchingTargets.filter(target =>
|
|
2268
|
+
isProtocolV2TargetStatusFinished(target.status)
|
|
2269
|
+
);
|
|
2366
2270
|
const completedTargetIds = new Set<number>();
|
|
2367
2271
|
completedTargets.forEach(target => {
|
|
2368
2272
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
@@ -2399,54 +2303,16 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2399
2303
|
}
|
|
2400
2304
|
|
|
2401
2305
|
if (expectedTargetIds.size > 0 && matchingTargets.length > 0) {
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
installTargetId: number;
|
|
2406
|
-
installPhase: 'prepare' | 'install' | 'verify';
|
|
2407
|
-
installPhaseProgress: number;
|
|
2408
|
-
}
|
|
2409
|
-
| undefined;
|
|
2410
|
-
let hasInProgressTarget = false;
|
|
2411
|
-
matchingTargets.forEach(target => {
|
|
2412
|
-
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
2413
|
-
if (
|
|
2414
|
-
targetId === undefined ||
|
|
2415
|
-
completedTargetIds.has(targetId) ||
|
|
2416
|
-
!isProtocolV2TargetStatusInProgress(target.status) ||
|
|
2417
|
-
(liveTargetIds && !liveTargetIds.has(targetId))
|
|
2418
|
-
) {
|
|
2419
|
-
return;
|
|
2420
|
-
}
|
|
2421
|
-
hasInProgressTarget = true;
|
|
2422
|
-
detailedProgress += normalizeProtocolV2ProgressPercent(target.progress_percent) ?? 0;
|
|
2423
|
-
const installPhase = target.phase_info
|
|
2424
|
-
? PROTOCOL_V2_INSTALL_PHASE_BY_DECODED_VALUE.get(target.phase_info.phase)
|
|
2425
|
-
: undefined;
|
|
2426
|
-
const installPhaseProgress = normalizeProtocolV2ProgressPercent(
|
|
2427
|
-
target.phase_info?.progress_percent
|
|
2428
|
-
);
|
|
2429
|
-
if (installPhase && installPhaseProgress !== undefined && !installProgressMetadata) {
|
|
2430
|
-
installProgressMetadata = {
|
|
2431
|
-
installTargetId: targetId,
|
|
2432
|
-
installPhase,
|
|
2433
|
-
installPhaseProgress,
|
|
2434
|
-
};
|
|
2435
|
-
}
|
|
2436
|
-
});
|
|
2306
|
+
const hasInProgressTarget = matchingTargets.some(target =>
|
|
2307
|
+
isProtocolV2TargetStatusInProgress(target.status)
|
|
2308
|
+
);
|
|
2437
2309
|
const completedProgress = Math.floor(
|
|
2438
2310
|
(completedTargetIds.size / expectedTargetIds.size) * 100
|
|
2439
2311
|
);
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
);
|
|
2445
|
-
if (installProgressMetadata) {
|
|
2446
|
-
this.postProgressMessage(progress, 'installingFirmware', installProgressMetadata);
|
|
2447
|
-
} else {
|
|
2448
|
-
this.postProgressMessage(progress, 'installingFirmware');
|
|
2449
|
-
}
|
|
2312
|
+
// The protocol exposes no per-target percentage, so report coarse progress by
|
|
2313
|
+
// completed targets and use 1% once work starts to keep the UI responsive.
|
|
2314
|
+
const progress = Math.min(99, Math.max(completedProgress, hasInProgressTarget ? 1 : 0));
|
|
2315
|
+
this.postProgressMessage(progress, 'installingFirmware');
|
|
2450
2316
|
}
|
|
2451
2317
|
|
|
2452
2318
|
return false;
|
|
@@ -2517,25 +2383,14 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2517
2383
|
) {
|
|
2518
2384
|
const expectedTargetIds = new Set(targets.map(target => target.target_id));
|
|
2519
2385
|
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);
|
|
2523
2386
|
const startTime = Date.now();
|
|
2524
2387
|
let lastError: unknown;
|
|
2525
|
-
//
|
|
2526
|
-
//
|
|
2527
|
-
let shouldReconnect =
|
|
2528
|
-
this.protocolV2InstallNeedsReconnect = false;
|
|
2388
|
+
// DeviceFirmwareUpdateRequest leaves the current loader link usable for status polling.
|
|
2389
|
+
// Reconnecting here probes DeviceInfo, which loaders reject while installation is active.
|
|
2390
|
+
let shouldReconnect = false;
|
|
2529
2391
|
let deviceInfo: ProtocolV2DeviceInfo | undefined;
|
|
2530
|
-
let
|
|
2531
|
-
let installStatusDisconnectObserved = false;
|
|
2532
|
-
let installReconnectObserved = false;
|
|
2533
|
-
let finishedStatusSnapshotKey: string | undefined;
|
|
2534
|
-
let finishedStatusSnapshotPolls = 0;
|
|
2535
|
-
let fastFinishedInstallProgressReported = false;
|
|
2536
|
-
let installEvidenceObserved = this.protocolV2InstallTerminalSuccessObserved;
|
|
2392
|
+
let installEvidenceObserved = false;
|
|
2537
2393
|
let currentInstallStatusObserved = false;
|
|
2538
|
-
const liveTargetIds = new Set<number>();
|
|
2539
2394
|
|
|
2540
2395
|
while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
|
|
2541
2396
|
// A transport release caused by an explicit workflow cancellation must not
|
|
@@ -2543,40 +2398,43 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2543
2398
|
this.throwIfAborted();
|
|
2544
2399
|
try {
|
|
2545
2400
|
if (shouldReconnect) {
|
|
2546
|
-
|
|
2547
|
-
await this.
|
|
2548
|
-
bleInstallLinkReady = isBleInstallReconnect;
|
|
2549
|
-
deviceInfo = isBleInstallReconnect
|
|
2550
|
-
? undefined
|
|
2551
|
-
: await this.verifyProtocolV2ReconnectIdentity();
|
|
2552
|
-
if (isBleInstallReconnect && installStatusDisconnectObserved) {
|
|
2553
|
-
installReconnectObserved = true;
|
|
2554
|
-
}
|
|
2401
|
+
await this.reconnectProtocolV2Device();
|
|
2402
|
+
deviceInfo = await this.verifyProtocolV2ReconnectIdentity();
|
|
2555
2403
|
shouldReconnect = false;
|
|
2556
2404
|
}
|
|
2557
|
-
|
|
2405
|
+
const currentDeviceInfo = deviceInfo;
|
|
2558
2406
|
try {
|
|
2559
2407
|
const statusResponse = await this.device.getCommands().typedCall(
|
|
2560
2408
|
'DeviceFirmwareUpdateStatusGet',
|
|
2561
|
-
'DeviceFirmwareUpdateStatus',
|
|
2409
|
+
['DeviceFirmwareUpdateStatus', 'Success'],
|
|
2562
2410
|
{
|
|
2563
2411
|
fields: {
|
|
2564
2412
|
status: true,
|
|
2565
|
-
progress_percent: true,
|
|
2566
|
-
phase_info: true,
|
|
2567
2413
|
payload_version: true,
|
|
2568
2414
|
path: true,
|
|
2569
2415
|
},
|
|
2570
2416
|
},
|
|
2571
2417
|
{ timeoutMs: PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT }
|
|
2572
2418
|
);
|
|
2573
|
-
if (
|
|
2419
|
+
if (statusResponse.type === 'Success') {
|
|
2574
2420
|
installEvidenceObserved = true;
|
|
2421
|
+
lastError = new Error(
|
|
2422
|
+
'Protocol V2 firmware install acknowledged; waiting for target status'
|
|
2423
|
+
);
|
|
2575
2424
|
}
|
|
2576
|
-
const statusTargets =
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2425
|
+
const statusTargets =
|
|
2426
|
+
statusResponse.type === 'DeviceFirmwareUpdateStatus'
|
|
2427
|
+
? ((statusResponse.message.records ?? []) as ProtocolV2FirmwareUpdateStatusTarget[])
|
|
2428
|
+
: [];
|
|
2429
|
+
const hasInProgressTarget = statusTargets.some(target => {
|
|
2430
|
+
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
2431
|
+
return (
|
|
2432
|
+
targetId !== undefined &&
|
|
2433
|
+
expectedTargetIds.has(targetId) &&
|
|
2434
|
+
isProtocolV2TargetStatusInProgress(target.status)
|
|
2435
|
+
);
|
|
2436
|
+
});
|
|
2437
|
+
if (hasInProgressTarget) {
|
|
2580
2438
|
currentInstallStatusObserved = true;
|
|
2581
2439
|
}
|
|
2582
2440
|
const hasMatchingTargetStatus = statusTargets.some(target => {
|
|
@@ -2593,101 +2451,18 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2593
2451
|
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
2594
2452
|
return targetId !== undefined && expectedTargetIds.has(targetId);
|
|
2595
2453
|
});
|
|
2596
|
-
const matchingFinishedTargetIds = new Set<number>();
|
|
2597
|
-
const matchingFinishedStatus = matchingStatusTargets
|
|
2598
|
-
.map(target => {
|
|
2599
|
-
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
2600
|
-
const expectedPath = targetId === undefined ? undefined : expectedPaths.get(targetId);
|
|
2601
|
-
const expectedVersion =
|
|
2602
|
-
targetId === undefined
|
|
2603
|
-
? undefined
|
|
2604
|
-
: this.getExpectedProtocolV2TargetVersion(targetId);
|
|
2605
|
-
const payloadVersion = toProtocolV2FiniteNumber(target.payload_version);
|
|
2606
|
-
if (
|
|
2607
|
-
targetId === undefined ||
|
|
2608
|
-
matchingFinishedTargetIds.has(targetId) ||
|
|
2609
|
-
!isProtocolV2TargetStatusFinished(target.status) ||
|
|
2610
|
-
(Boolean(target.path) && Boolean(expectedPath) && target.path !== expectedPath) ||
|
|
2611
|
-
(expectedVersion !== undefined &&
|
|
2612
|
-
payloadVersion !== undefined &&
|
|
2613
|
-
payloadVersion !== expectedVersion)
|
|
2614
|
-
) {
|
|
2615
|
-
return undefined;
|
|
2616
|
-
}
|
|
2617
|
-
matchingFinishedTargetIds.add(targetId);
|
|
2618
|
-
return [targetId, target.path ?? null, payloadVersion ?? null] as const;
|
|
2619
|
-
})
|
|
2620
|
-
.filter((target): target is readonly [number, string | null, number | null] => !!target)
|
|
2621
|
-
.sort(([leftTargetId], [rightTargetId]) => leftTargetId - rightTargetId);
|
|
2622
|
-
const hasCompleteMatchingFinishedStatus =
|
|
2623
|
-
matchingFinishedStatus.length === expectedTargetIds.size &&
|
|
2624
|
-
matchingFinishedTargetIds.size === expectedTargetIds.size &&
|
|
2625
|
-
expectedTargetIds.size > 0;
|
|
2626
|
-
if (
|
|
2627
|
-
requireCurrentInstallStatus &&
|
|
2628
|
-
installReconnectObserved &&
|
|
2629
|
-
hasCompleteMatchingFinishedStatus
|
|
2630
|
-
) {
|
|
2631
|
-
const nextSnapshotKey = JSON.stringify(matchingFinishedStatus);
|
|
2632
|
-
if (nextSnapshotKey === finishedStatusSnapshotKey) {
|
|
2633
|
-
finishedStatusSnapshotPolls += 1;
|
|
2634
|
-
} else {
|
|
2635
|
-
finishedStatusSnapshotKey = nextSnapshotKey;
|
|
2636
|
-
finishedStatusSnapshotPolls = 1;
|
|
2637
|
-
}
|
|
2638
|
-
} else {
|
|
2639
|
-
finishedStatusSnapshotKey = undefined;
|
|
2640
|
-
finishedStatusSnapshotPolls = 0;
|
|
2641
|
-
}
|
|
2642
|
-
if (
|
|
2643
|
-
requireCurrentInstallStatus &&
|
|
2644
|
-
installReconnectObserved &&
|
|
2645
|
-
hasCompleteMatchingFinishedStatus &&
|
|
2646
|
-
!currentInstallStatusObserved &&
|
|
2647
|
-
!this.protocolV2InstallTerminalSuccessObserved &&
|
|
2648
|
-
!fastFinishedInstallProgressReported
|
|
2649
|
-
) {
|
|
2650
|
-
// A fast BLE install may finish while disconnected, so IN_PROGRESS can be hidden.
|
|
2651
|
-
// A status response timeout alone is not evidence that the install was accepted.
|
|
2652
|
-
this.postProgressMessage(1, 'installingFirmware');
|
|
2653
|
-
fastFinishedInstallProgressReported = true;
|
|
2654
|
-
}
|
|
2655
|
-
const finishedAfterDisconnectObserved =
|
|
2656
|
-
finishedStatusSnapshotPolls >= PROTOCOL_V2_INSTALL_FINISHED_AFTER_DISCONNECT_POLLS;
|
|
2657
|
-
const hasCurrentInstallEvidence =
|
|
2658
|
-
currentInstallStatusObserved ||
|
|
2659
|
-
this.protocolV2InstallTerminalSuccessObserved ||
|
|
2660
|
-
finishedAfterDisconnectObserved;
|
|
2661
|
-
if (hasCurrentInstallEvidence) {
|
|
2662
|
-
installEvidenceObserved = true;
|
|
2663
|
-
}
|
|
2664
2454
|
const shouldVerifyTargetCompletion =
|
|
2665
|
-
!requireCurrentInstallStatus ||
|
|
2455
|
+
!requireCurrentInstallStatus || currentInstallStatusObserved;
|
|
2666
2456
|
if (
|
|
2667
2457
|
shouldVerifyTargetCompletion &&
|
|
2668
|
-
this.assertProtocolV2TargetStatus(
|
|
2669
|
-
statusTargets,
|
|
2670
|
-
expectedTargetIds,
|
|
2671
|
-
expectedPaths,
|
|
2672
|
-
requireCurrentInstallStatus &&
|
|
2673
|
-
!this.protocolV2InstallTerminalSuccessObserved &&
|
|
2674
|
-
!finishedAfterDisconnectObserved
|
|
2675
|
-
? liveTargetIds
|
|
2676
|
-
: undefined
|
|
2677
|
-
)
|
|
2458
|
+
this.assertProtocolV2TargetStatus(statusTargets, expectedTargetIds, expectedPaths)
|
|
2678
2459
|
) {
|
|
2679
2460
|
return;
|
|
2680
2461
|
}
|
|
2681
2462
|
|
|
2682
|
-
if (!hasCurrentInstallEvidence) {
|
|
2683
|
-
// A successful status poll clears DeviceCommands' cancel action. Keep cancellation
|
|
2684
|
-
// available while UpdateRequest is still waiting for confirmation on the device.
|
|
2685
|
-
this.device.setCancelableAction(() => this.device.getCommands().cancelDevice());
|
|
2686
|
-
}
|
|
2687
|
-
|
|
2688
2463
|
if (
|
|
2689
2464
|
requireCurrentInstallStatus &&
|
|
2690
|
-
!
|
|
2465
|
+
!currentInstallStatusObserved &&
|
|
2691
2466
|
matchingStatusTargets.length > 0
|
|
2692
2467
|
) {
|
|
2693
2468
|
lastError = new Error(
|
|
@@ -2695,18 +2470,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2695
2470
|
);
|
|
2696
2471
|
}
|
|
2697
2472
|
|
|
2698
|
-
if (
|
|
2699
|
-
statusTargets.length === 0 &&
|
|
2700
|
-
!currentDeviceInfo &&
|
|
2701
|
-
bleInstallLinkReady &&
|
|
2702
|
-
installEvidenceObserved
|
|
2703
|
-
) {
|
|
2704
|
-
// BLE install reconnect skips generic probes because loaders may not answer Ping.
|
|
2705
|
-
// Restore the verified identity only after current-install evidence disappears.
|
|
2706
|
-
currentDeviceInfo = await this.verifyProtocolV2ReconnectIdentity();
|
|
2707
|
-
deviceInfo = currentDeviceInfo;
|
|
2708
|
-
}
|
|
2709
|
-
|
|
2710
2473
|
if (statusTargets.length === 0 && currentDeviceInfo) {
|
|
2711
2474
|
const isNormalMode = await this.probeProtocolV2NormalMode(currentDeviceInfo);
|
|
2712
2475
|
if (
|
|
@@ -2724,9 +2487,11 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2724
2487
|
}
|
|
2725
2488
|
|
|
2726
2489
|
if (statusTargets.length === 0) {
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2490
|
+
if (statusResponse.type !== 'Success') {
|
|
2491
|
+
lastError = new Error(
|
|
2492
|
+
'Protocol V2 firmware update is waiting for user confirmation or target status'
|
|
2493
|
+
);
|
|
2494
|
+
}
|
|
2730
2495
|
} else {
|
|
2731
2496
|
const missingTargetIds = this.getProtocolV2MissingTargetIds(
|
|
2732
2497
|
statusTargets,
|
|
@@ -2749,22 +2514,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2749
2514
|
// missing endpoint as completion only after the runtime probe confirms App mode.
|
|
2750
2515
|
if (isProtocolV2FirmwareStatusEndpointUnavailable(error)) {
|
|
2751
2516
|
if (!currentDeviceInfo) {
|
|
2752
|
-
if (!bleInstallLinkReady) {
|
|
2753
|
-
throw ERRORS.TypedError(
|
|
2754
|
-
HardwareErrorCode.RuntimeError,
|
|
2755
|
-
'Protocol V2 device identity is unavailable during install polling'
|
|
2756
|
-
);
|
|
2757
|
-
}
|
|
2758
|
-
deviceInfo = await this.verifyProtocolV2ReconnectIdentity();
|
|
2759
|
-
}
|
|
2760
|
-
const reconnectDeviceInfo = currentDeviceInfo ?? deviceInfo;
|
|
2761
|
-
if (!reconnectDeviceInfo) {
|
|
2762
2517
|
throw ERRORS.TypedError(
|
|
2763
2518
|
HardwareErrorCode.RuntimeError,
|
|
2764
2519
|
'Protocol V2 device identity is unavailable during install polling'
|
|
2765
2520
|
);
|
|
2766
2521
|
}
|
|
2767
|
-
const isNormalMode = await this.probeProtocolV2NormalMode(
|
|
2522
|
+
const isNormalMode = await this.probeProtocolV2NormalMode(currentDeviceInfo);
|
|
2768
2523
|
if (
|
|
2769
2524
|
isNormalMode &&
|
|
2770
2525
|
(installEvidenceObserved ||
|
|
@@ -2787,18 +2542,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2787
2542
|
);
|
|
2788
2543
|
}
|
|
2789
2544
|
} else {
|
|
2790
|
-
if (
|
|
2791
|
-
isBleCoprocessorInstall &&
|
|
2792
|
-
isProtocolV2DeviceDisconnectedError(error) &&
|
|
2793
|
-
!isProtocolV2ResponseTimeout(error)
|
|
2794
|
-
) {
|
|
2795
|
-
installStatusDisconnectObserved = true;
|
|
2796
|
-
finishedStatusSnapshotKey = undefined;
|
|
2797
|
-
finishedStatusSnapshotPolls = 0;
|
|
2798
|
-
}
|
|
2799
2545
|
shouldReconnect = true;
|
|
2800
2546
|
deviceInfo = undefined;
|
|
2801
|
-
bleInstallLinkReady = false;
|
|
2802
2547
|
lastError = error;
|
|
2803
2548
|
Log.log(
|
|
2804
2549
|
'[FirmwareUpdateV4] DeviceFirmwareUpdateStatusGet unavailable during install: ',
|
|
@@ -2822,7 +2567,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2822
2567
|
}
|
|
2823
2568
|
shouldReconnect = true;
|
|
2824
2569
|
deviceInfo = undefined;
|
|
2825
|
-
bleInstallLinkReady = false;
|
|
2826
2570
|
Log.log('Protocol V2 firmware install device readiness probe failed: ', error);
|
|
2827
2571
|
}
|
|
2828
2572
|
await wait(1000);
|
|
@@ -2851,9 +2595,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2851
2595
|
return;
|
|
2852
2596
|
}
|
|
2853
2597
|
} catch (error) {
|
|
2854
|
-
if (isBleStaleBondHardwareError(error)) {
|
|
2855
|
-
throw error;
|
|
2856
|
-
}
|
|
2857
2598
|
Log.log('[FirmwareUpdateV4] unable to confirm App mode before Normal reboot: ', error);
|
|
2858
2599
|
}
|
|
2859
2600
|
await this.protocolV2Reboot(DeviceRebootType.Normal);
|
|
@@ -2945,7 +2686,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2945
2686
|
'Protocol V2 device is still in bootloader mode'
|
|
2946
2687
|
);
|
|
2947
2688
|
} catch (error) {
|
|
2948
|
-
if (
|
|
2689
|
+
if (this.isProtocolV2ReconnectIdentityError(error)) {
|
|
2949
2690
|
throw error;
|
|
2950
2691
|
}
|
|
2951
2692
|
shouldReconnect = true;
|
|
@@ -2963,53 +2704,19 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2963
2704
|
);
|
|
2964
2705
|
}
|
|
2965
2706
|
|
|
2966
|
-
private async reconnectProtocolV2Device(
|
|
2707
|
+
private async reconnectProtocolV2Device() {
|
|
2967
2708
|
if (this.isBleReconnect()) {
|
|
2968
|
-
await this.acquireProtocolV2BleDevice(
|
|
2709
|
+
await this.acquireProtocolV2BleDevice();
|
|
2969
2710
|
return;
|
|
2970
2711
|
}
|
|
2971
2712
|
|
|
2972
2713
|
const deviceDiff = await this.device.deviceConnector?.enumerate();
|
|
2973
2714
|
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
2974
|
-
const env = DataManager.getSettings('env');
|
|
2975
|
-
const isWebUsb = DataManager.isBrowserWebUsb(env) || DataManager.isDesktopWebUsb(env);
|
|
2976
|
-
|
|
2977
|
-
if (isWebUsb && options?.skipProtocolProbe) {
|
|
2978
|
-
const expectedSerialNumber = this.protocolV2ExpectedSerialNumber?.trim();
|
|
2979
|
-
const expectedPath = this.protocolV2ExpectedPath?.trim();
|
|
2980
|
-
const reconnectDescriptor = devicesDescriptor.find(descriptor => {
|
|
2981
|
-
const descriptorPath = descriptor.path?.trim();
|
|
2982
|
-
return (
|
|
2983
|
-
(!!expectedSerialNumber && descriptorPath === expectedSerialNumber) ||
|
|
2984
|
-
(!!expectedPath && descriptorPath === expectedPath)
|
|
2985
|
-
);
|
|
2986
|
-
});
|
|
2987
|
-
if (!reconnectDescriptor?.path) {
|
|
2988
|
-
throw ERRORS.TypedError(HardwareErrorCode.DeviceNotFound);
|
|
2989
|
-
}
|
|
2990
|
-
this.device.updateDescriptor(
|
|
2991
|
-
{
|
|
2992
|
-
...reconnectDescriptor,
|
|
2993
|
-
protocolType: PROTOCOL_V2_CONNECT_PROTOCOL,
|
|
2994
|
-
},
|
|
2995
|
-
true
|
|
2996
|
-
);
|
|
2997
|
-
const mainId = await this.device.deviceConnector?.acquire(
|
|
2998
|
-
reconnectDescriptor.path,
|
|
2999
|
-
null,
|
|
3000
|
-
undefined,
|
|
3001
|
-
PROTOCOL_V2_CONNECT_PROTOCOL,
|
|
3002
|
-
undefined,
|
|
3003
|
-
undefined,
|
|
3004
|
-
true
|
|
3005
|
-
);
|
|
3006
|
-
this.device.mainId = typeof mainId === 'string' ? mainId : reconnectDescriptor.path;
|
|
3007
|
-
this.device.commands.disposed = false;
|
|
3008
|
-
this.device.getCommands().mainId = this.device.mainId;
|
|
3009
|
-
return;
|
|
3010
|
-
}
|
|
3011
2715
|
|
|
3012
|
-
if (
|
|
2716
|
+
if (
|
|
2717
|
+
DataManager.isBrowserWebUsb(DataManager.getSettings('env')) &&
|
|
2718
|
+
devicesDescriptor.length === 1
|
|
2719
|
+
) {
|
|
3013
2720
|
const descriptor = devicesDescriptor[0];
|
|
3014
2721
|
if (!this.protocolV2ExpectedSerialNumber && descriptor.path !== this.protocolV2ExpectedPath) {
|
|
3015
2722
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceNotFound);
|
|
@@ -3127,24 +2834,13 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3127
2834
|
await wait(2000);
|
|
3128
2835
|
}
|
|
3129
2836
|
|
|
3130
|
-
private async acquireProtocolV2BleDevice(
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
if (!skipProtocolProbe) {
|
|
3134
|
-
await connector?.acquire(expectedId, null, true, PROTOCOL_V2_CONNECT_PROTOCOL);
|
|
3135
|
-
return;
|
|
3136
|
-
}
|
|
3137
|
-
await connector?.acquire(
|
|
3138
|
-
expectedId,
|
|
2837
|
+
private async acquireProtocolV2BleDevice() {
|
|
2838
|
+
await this.device.deviceConnector?.acquire(
|
|
2839
|
+
this.device.originalDescriptor.id,
|
|
3139
2840
|
null,
|
|
3140
2841
|
true,
|
|
3141
|
-
PROTOCOL_V2_CONNECT_PROTOCOL
|
|
3142
|
-
undefined,
|
|
3143
|
-
undefined,
|
|
3144
|
-
skipProtocolProbe
|
|
2842
|
+
PROTOCOL_V2_CONNECT_PROTOCOL
|
|
3145
2843
|
);
|
|
3146
|
-
this.device.commands.disposed = false;
|
|
3147
|
-
this.device.getCommands().mainId = expectedId;
|
|
3148
2844
|
}
|
|
3149
2845
|
|
|
3150
2846
|
private async protocolV2StartFirmwareUpdate({
|
|
@@ -3153,11 +2849,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3153
2849
|
targets: Array<{ target_id: number; path: string }>;
|
|
3154
2850
|
}) {
|
|
3155
2851
|
this.protocolV2LastRuntimeProbeFeatures = undefined;
|
|
3156
|
-
this.protocolV2InstallNeedsReconnect = false;
|
|
3157
|
-
this.protocolV2InstallTerminalSuccessObserved = false;
|
|
3158
2852
|
const commands = this.device.getCommands();
|
|
3159
2853
|
await commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
3160
|
-
this.device.setCancelableAction(() =>
|
|
2854
|
+
this.device.setCancelableAction(() => commands.cancelDevice());
|
|
3161
2855
|
const interaction = this.device.createProtocolV2UiPhaseMetadata('button', 'start');
|
|
3162
2856
|
this.postMessage(
|
|
3163
2857
|
createUiMessage(UI_REQUEST.REQUEST_BUTTON, {
|
|
@@ -3170,54 +2864,19 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3170
2864
|
...(interaction ? { interaction } : {}),
|
|
3171
2865
|
})
|
|
3172
2866
|
);
|
|
3173
|
-
|
|
3174
|
-
try {
|
|
3175
|
-
await commands.call(
|
|
3176
|
-
'DeviceFirmwareUpdateRequest',
|
|
3177
|
-
{},
|
|
3178
|
-
{
|
|
3179
|
-
returnAfterWrite: true,
|
|
3180
|
-
expectedTypes: ['Success'],
|
|
3181
|
-
onResponseAfterWrite: response => {
|
|
3182
|
-
if (response.type !== 'Success') return;
|
|
3183
|
-
this.protocolV2InstallTerminalSuccessObserved = true;
|
|
3184
|
-
this.device.clearCancelableAction();
|
|
3185
|
-
Log.log('[FirmwareUpdateV4] firmware install completed by device response');
|
|
3186
|
-
},
|
|
3187
|
-
}
|
|
3188
|
-
);
|
|
3189
|
-
Log.log('[FirmwareUpdateV4] firmware install request written; continue with status polling');
|
|
3190
|
-
} catch (error) {
|
|
3191
|
-
this.throwIfAborted();
|
|
3192
|
-
if (!isProtocolV2DeviceDisconnectedError(error)) {
|
|
3193
|
-
throw error;
|
|
3194
|
-
}
|
|
3195
|
-
Log.log(
|
|
3196
|
-
'[FirmwareUpdateV4] transport released while writing install request; continue status polling'
|
|
3197
|
-
);
|
|
3198
|
-
this.protocolV2InstallNeedsReconnect = true;
|
|
3199
|
-
}
|
|
2867
|
+
await commands.call('DeviceFirmwareUpdateRequest', {}, { returnAfterWrite: true });
|
|
3200
2868
|
}
|
|
3201
2869
|
|
|
3202
2870
|
private async protocolV2Reboot(rebootType: DeviceRebootType) {
|
|
3203
2871
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
3204
2872
|
try {
|
|
3205
|
-
const res = await typedCall(
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
{
|
|
3209
|
-
reboot_type: rebootType,
|
|
3210
|
-
},
|
|
3211
|
-
{ timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT }
|
|
3212
|
-
);
|
|
2873
|
+
const res = await typedCall('DeviceReboot', 'Success', {
|
|
2874
|
+
reboot_type: rebootType,
|
|
2875
|
+
});
|
|
3213
2876
|
this.device.markProtocolV2Reboot(rebootType);
|
|
3214
2877
|
return res.message;
|
|
3215
2878
|
} catch (error) {
|
|
3216
|
-
if (
|
|
3217
|
-
isProtocolV2DeviceDisconnectedError(error) ||
|
|
3218
|
-
isProtocolV2ReconnectProbeError(error) ||
|
|
3219
|
-
isProtocolV2ResponseTimeout(error)
|
|
3220
|
-
) {
|
|
2879
|
+
if (isProtocolV2DeviceDisconnectedError(error) || isProtocolV2ReconnectProbeError(error)) {
|
|
3221
2880
|
this.device.markProtocolV2Reboot(rebootType);
|
|
3222
2881
|
return { message: 'Device rebooted successfully' };
|
|
3223
2882
|
}
|