@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
64 lines • 2.86 kB
JavaScript
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