Browse Source

Full reinstall toggle

Malte Grimm 3 years ago
parent
commit
1825845110
  1. 12
      src/components/Dashboard.tsx
  2. 34
      src/core/flashing/Flasher.ts
  3. 10
      src/core/stores/appStore.ts

12
src/components/Dashboard.tsx

@ -42,6 +42,7 @@ import { Subtle } from '@components/UI/Typography/Subtle.js';
import { ISerialConnection } from '@meshtastic/meshtasticjs';
import { ConfigSelectButton } from './UI/ConfigSelectButton';
import { Label } from './UI/Label';
import {
Select,
SelectContent,
@ -50,6 +51,7 @@ import {
SelectTrigger,
SelectValue,
} from './UI/Select';
import { Switch } from './UI/Switch';
let initTest: boolean = false;
@ -108,6 +110,7 @@ export const Dashboard = () => {
const DeviceList = ({devices, rootConfig, totalConfigCount}: {devices: Device[], rootConfig: ConfigPreset, totalConfigCount: number}) => {
const { setConnectDialogOpen, overallFlashingState, setOverallFlashingState, selectedFirmware, selectedDeviceModel, firmwareList, setFirmwareList } = useAppStore();
const [deviceSelectedToFlash, setDeviceSelectedToFlash] = useState(devices.map(d => d.flashState));
const [ fullFlash, setFullFlash ] = useState(false);
// const [flashingState, setFlashingState]: any = useState([]);
const cancelButtonVisible = overallFlashingState.state != "idle";
const firmware = firmwareList.find(f => f.name == selectedFirmware);
@ -144,9 +147,12 @@ const DeviceList = ({devices, rootConfig, totalConfigCount}: {devices: Device[],
</div>}
</ul>
<div className="flex flex-col gap-3">
<div className="flex gap-3">
<div className="flex gap-3 w-full">
<DeviceModelSelection/>
<FirmwareSelection/>
<div className='flex w-full items-center gap-3'>
<Switch checked={fullFlash} onCheckedChange={setFullFlash}/>
<Label>Force full wipe and reinstall</Label>
</div>
</div>
<div className="flex gap-3">
<FirmwareSelection/>
@ -156,7 +162,7 @@ const DeviceList = ({devices, rootConfig, totalConfigCount}: {devices: Device[],
onClick={async () => {
rootConfig.children[0].getFinalConfig(); // FIXME
if(overallFlashingState.state == "idle")
await setup(rootConfig.getAll(), selectedDeviceModel, firmware!, (state: OverallFlashingState, progress?: number) => {
await setup(rootConfig.getAll(), selectedDeviceModel, firmware!, fullFlash, (state: OverallFlashingState, progress?: number) => {
if(state == 'busy') {
isStoredInDb(firmware!.tag).then(b => {
// All FirmwareVersion objects are immutable here so we'll have to re-create each entry

34
src/core/flashing/Flasher.ts

@ -25,13 +25,16 @@ let firmwareToUse: FirmwareVersion;
let operations: FlashOperation[] = [];
let callback: OverallFlashingCallback;
let selectedDeviceModel: string;
let fullFlash: boolean;
export async function setup(configs: ConfigPreset[], deviceModelName: string, firmware: FirmwareVersion, overallCallback: OverallFlashingCallback) {
export async function setup(configs: ConfigPreset[], deviceModelName: string, firmware: FirmwareVersion,
forceFullFlash: boolean, overallCallback: OverallFlashingCallback) {
dataSections = {};
selectedDeviceModel = deviceModelName;
callback = overallCallback;
console.log(`Firmware to use: ${firmware?.name} - ${firmware?.id}`);
firmwareToUse = firmware;
fullFlash = forceFullFlash;
await loadFirmware();
for(const c in configs) {
const config = configs[c];
@ -142,26 +145,35 @@ async function loadFirmware() {
zipFile = await JSZip.loadAsync(zip);
}
async function getSection(name: string): Promise<Uint8Array> {
async function getSection(name: string): Promise<Uint8Array | undefined> {
if(!(name in dataSections)) {
const dataSection = await zipFile.file(name)?.async("uint8array");
if(dataSection === undefined)
throw `File ${name} missing from firmware directory`;
if(dataSection === undefined) {
console.warn(`Firmware file ${name} not found.`);
return undefined;
}
dataSections[name] = dataSection;
}
return dataSections[name];
}
async function getFirmwareSections(deviceModel: string) {
debugger;
async function getFirmwareSections(deviceModel: string, alreadyFlashed: boolean) {
if(alreadyFlashed && !fullFlash) {
const updateFilename = `firmware-${deviceModel}-${firmwareToUse.tag}-update.bin`;
const mainUpdate = await getSection(updateFilename);
if(mainUpdate !== undefined) {
return [ { offset: 0x10000, data: mainUpdate } ];
}
}
const filename = `firmware-${deviceModel}-${firmwareToUse.tag}.bin`;
const mainFile = await getSection(filename);
const main = await getSection(filename);
const bleoata = await getSection("bleota.bin");
const littlefs = await getSection(`littlefs-${firmwareToUse.tag}.bin`);
if(main === undefined || bleoata === undefined || littlefs === undefined)
throw "Missing firmware files.";
return [ // TODO: Is this correct for all device models?
{ offset: 0, data: mainFile },
{ offset: 0, data: main },
{ offset: 0x260000, data: bleoata },
{ offset: 0x300000, data: littlefs }
];
@ -192,6 +204,8 @@ export class FlashOperation {
public async flash() {
let port;
try {
debugger;
const updatePossible = this.device.nodes.get(this.device.hardware.myNodeNum) !== undefined;
port = await (this.device.connection! as ISerialConnection).freePort();
if(port === undefined)
throw "Port unavailable";
@ -200,7 +214,7 @@ export class FlashOperation {
throw "Could not detect device model";
const info = port.getInfo();
console.log(`Device info: vendor ${info.usbVendorId}, product ${info.usbProductId}`);
const sections = await getFirmwareSections(deviceModel);
const sections = await getFirmwareSections(deviceModel, updatePossible);
await port!.open({baudRate: 115200});
this.loader = new EspLoader(port!);
const loader = this.loader;

10
src/core/stores/appStore.ts

@ -186,6 +186,7 @@ interface AppState {
firmwareList: FirmwareVersion[];
selectedFirmware: string;
selectedDeviceModel: string;
fullFlash: boolean;
setRasterSources: (sources: RasterSource[]) => void;
addRasterSource: (source: RasterSource) => void;
@ -205,6 +206,7 @@ interface AppState {
setFirmwareList: (state: FirmwareVersion[]) => void;
setSelectedFirmware: (state: string) => void;
setSelectedDeviceModel: (state: string) => void;
setFullFlash: (state: boolean) => void;
}
export const useAppStore = create<AppState>()((set) => ({
@ -224,6 +226,7 @@ export const useAppStore = create<AppState>()((set) => ({
firmwareList: loadFirmwareListFromStorage(),
selectedFirmware: "latest",
selectedDeviceModel: "auto",
fullFlash: false,
setRasterSources: (sources: RasterSource[]) => {
set(
@ -337,4 +340,11 @@ export const useAppStore = create<AppState>()((set) => ({
})
)
},
setFullFlash(state: boolean) {
set(
produce<AppState>((draft) => {
draft.fullFlash = state;
})
)
}
}));
Loading…
Cancel
Save