UNPKG

@ledgerhq/live-common

Version:
64 lines 2.86 kB
import { log } from "@ledgerhq/logs"; import { Observable, from, of, EMPTY, concat, throwError } from "rxjs"; import { concatMap, delay, scan, distinctUntilChanged, throttleTime } from "rxjs/operators"; import { CantOpenDevice, DeviceInOSUExpected } from "@ledgerhq/errors"; import { withDevicePolling, withDevice } from "./deviceAccess"; import getDeviceInfo from "./getDeviceInfo"; import flash from "./flash"; import installFinalFirmware from "./installFinalFirmware"; import { hasFinalFirmware } from "./hasFinalFirmware"; const wait2s = of({ type: "wait", }).pipe(delay(2000)); const main = (deviceId, { final, shouldFlashMCU }) => { log("hw", "firmwareUpdate-main started"); const withFinal = hasFinalFirmware(final); const withDeviceInfo = withDevicePolling(deviceId)(transport => from(getDeviceInfo(transport)), () => true); const withDeviceInstall = install => withDevicePolling(deviceId)(install, e => e instanceof CantOpenDevice); const waitForBootloader = withDeviceInfo.pipe(concatMap(deviceInfo => (deviceInfo.isBootloader ? EMPTY : concat(wait2s, waitForBootloader)))); const potentialAutoFlash = withDeviceInfo.pipe(concatMap(deviceInfo => deviceInfo.isOSU ? EMPTY : withDevice(deviceId)(transport => new Observable(o => { const timeout = setTimeout(() => { log("firmware", "potentialAutoFlash timeout"); o.complete(); }, 20000); const disconnect = () => { log("firmware", "potentialAutoFlash disconnect"); o.complete(); }; transport.on("disconnect", disconnect); return () => { clearTimeout(timeout); transport.off("disconnect", disconnect); }; })))); const bootloaderLoop = withDeviceInfo.pipe(concatMap(deviceInfo => deviceInfo.isBootloader ? concat(withDeviceInstall(flash(final)), wait2s, bootloaderLoop) : EMPTY)); const finalStep = !withFinal ? EMPTY : withDeviceInfo.pipe(concatMap(deviceInfo => !deviceInfo.isOSU ? throwError(() => new DeviceInOSUExpected()) : withDeviceInstall(installFinalFirmware))); const all = shouldFlashMCU ? concat(waitForBootloader, bootloaderLoop, finalStep) : concat(potentialAutoFlash, finalStep); return all.pipe(scan((acc, e) => { if (e.type === "install") { return { installing: e.step, progress: 0, }; } if (e.type === "bulk-progress") { return { ...acc, progress: e.progress }; } return acc; }, { progress: 0, installing: null, }), distinctUntilChanged(), throttleTime(100)); }; export default main; //# sourceMappingURL=firmwareUpdate-main.js.map