UNPKG

@ledgerhq/live-common

Version:
162 lines • 8.33 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.repairChoices = void 0; const logs_1 = require("@ledgerhq/logs"); const errors_1 = require("@ledgerhq/errors"); const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const semver_1 = __importDefault(require("semver")); const api_1 = __importDefault(require("../manager/api")); const deviceAccess_1 = require("./deviceAccess"); const provider_1 = require("../manager/provider"); const getDeviceInfo_1 = __importDefault(require("./getDeviceInfo")); const deviceWordings_1 = require("../deviceWordings"); const getDeviceRunningMode_1 = require("./getDeviceRunningMode"); const fetchMcusUseCase_1 = require("../device/use-cases/fetchMcusUseCase"); const wait2s = (0, rxjs_1.of)({ type: "wait", }).pipe((0, operators_1.delay)(2000)); exports.repairChoices = [ { id: "mcuOutdated", label: deviceWordings_1.mcuOutdated, forceMCU: "0.7", }, { id: "mcuNotGenuine", label: deviceWordings_1.mcuNotGenuine, forceMCU: "0.7", }, { id: "followDeviceRepair", label: deviceWordings_1.followDeviceRepair, forceMCU: "0.9", }, { id: "followDeviceUpdate", label: deviceWordings_1.followDeviceUpdate, forceMCU: "0.9", }, ]; const repair = (deviceId, forceMCU_) => { (0, logs_1.log)("hw", "firmwareUpdate-repair"); const mcusPromise = (0, fetchMcusUseCase_1.fetchMcusUseCase)(); const withDeviceInfo = (0, deviceAccess_1.withDevicePolling)(deviceId)(transport => (0, rxjs_1.from)((0, getDeviceInfo_1.default)(transport)), () => true); const waitForBootloader = withDeviceInfo.pipe((0, operators_1.concatMap)(deviceInfo => (deviceInfo.isBootloader ? rxjs_1.EMPTY : (0, rxjs_1.concat)(wait2s, waitForBootloader)))); const loop = (forceMCU) => (0, rxjs_1.concat)(withDeviceInfo.pipe((0, operators_1.concatMap)(deviceInfo => { const installMcu = (version) => (0, deviceAccess_1.withDevice)(deviceId)(transport => api_1.default.installMcu(transport, "mcu", { targetId: deviceInfo.targetId, version, })); if (!deviceInfo.isBootloader) { // finish earlier return rxjs_1.EMPTY; } // This is a special case where user is in firmware 1.3.1 // and the device shows MCU Not Genuine. // User needs to press both keys three times to go back to dashboard // and continue the update process if (forceMCU && forceMCU === "0.7" && (deviceInfo.majMin === "0.6" || deviceInfo.majMin === "0.7")) { // finish earlier return (0, rxjs_1.throwError)(() => new errors_1.MCUNotGenuineToDashboard()); } if (forceMCU) { return (0, rxjs_1.concat)(installMcu(forceMCU), wait2s, loop()); } switch (deviceInfo.majMin) { case "0.0": return (0, rxjs_1.concat)(installMcu("0.6"), wait2s, loop()); case "0.6": return installMcu("1.5"); case "0.7": return installMcu("1.6"); case "0.9": return installMcu("1.7"); default: return (0, rxjs_1.from)(mcusPromise).pipe((0, operators_1.concatMap)(mcus => { let next; const { seVersion, seTargetId, mcuBlVersion } = deviceInfo; // This is a special case where a user with LNX version >= 2.0.0 // comes back with a broken updated device. We need to be able // to patch MCU or Bootloader if needed if (seVersion && seTargetId) { (0, logs_1.log)("hw", "firmwareUpdate-repair seVersion and seTargetId found", { seVersion, seTargetId, }); const provider = (0, provider_1.getProviderId)(deviceInfo); /** * filter the MCUs that are available on the provider and * have a "from_bootloader_version" different from "none" * */ const availableMcus = mcus.filter(mcu => mcu.providers.includes(provider) && mcu.from_bootloader_version !== "none"); (0, logs_1.log)("hw", `firmwareUpdate-repair available mcus on provider ${provider}`, { availableMcus, }); return (0, rxjs_1.from)(api_1.default.getDeviceVersion(seTargetId, (0, provider_1.getProviderId)(deviceInfo))).pipe((0, operators_1.mergeMap)((deviceVersion) => (0, rxjs_1.from)(api_1.default.getCurrentFirmware({ deviceId: deviceVersion.id, version: seVersion, provider: (0, provider_1.getProviderId)(deviceInfo), }))), (0, operators_1.mergeMap)((finalFirmware) => { (0, logs_1.log)("hw", "firmwareUpdate-repair got final firmware", { finalFirmware, }); const mcu = api_1.default.findBestMCU(availableMcus.filter(({ id }) => finalFirmware.mcu_versions.includes(id))); (0, logs_1.log)("hw", "firmwareUpdate-repair got mcu", { mcu }); if (!mcu) return rxjs_1.EMPTY; const expectedBootloaderVersion = semver_1.default.coerce(mcu.from_bootloader_version)?.version; const currentBootloaderVersion = semver_1.default.coerce(mcuBlVersion)?.version; (0, logs_1.log)("hw", "firmwareUpdate-repair bootloader versions", { currentBootloaderVersion, expectedBootloaderVersion, }); if (expectedBootloaderVersion === currentBootloaderVersion) { next = mcu; (0, logs_1.log)("hw", "firmwareUpdate-repair bootloader versions are the same", { next, }); } else { next = { name: mcu.from_bootloader_version, }; (0, logs_1.log)("hw", "firmwareUpdate-repair bootloader versions are different", { next, }); } return installMcu(next.name); })); } else { next = api_1.default.findBestMCU(api_1.default.compatibleMCUForDeviceInfo(mcus, deviceInfo, (0, provider_1.getProviderId)(deviceInfo))); if (next) return installMcu(next.name); } return rxjs_1.EMPTY; })); } })), (0, rxjs_1.from)((0, getDeviceRunningMode_1.getDeviceRunningMode)({ deviceId, unresponsiveTimeoutMs: 4000, cantOpenDeviceRetryLimit: 2, })).pipe((0, operators_1.mergeMap)(result => { if (result.type === "bootloaderMode") { return loop(forceMCU); } else { return rxjs_1.EMPTY; } }))); // TODO ideally we should race waitForBootloader with an event "display-bootloader-reboot", it should be a delayed event that is not emitted if waitForBootloader is fast enough.. return (0, rxjs_1.concat)(waitForBootloader, loop(forceMCU_)).pipe((0, operators_1.filter)((e) => e.type === "bulk-progress"), (0, operators_1.map)(e => ({ progress: e.progress, })), (0, operators_1.throttleTime)(100)); }; exports.default = repair; //# sourceMappingURL=firmwareUpdate-repair.js.map