zwischenstand
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { FRAME, DATA, ZEPHYR_ERRORS } from './constants';
|
||||
import { protocolInfo, fsInfo, transferStats, resetTransferStats, transferDetails } from '../store';
|
||||
import { protocolInfo, deviceInfo, fsInfo, transferStats, fwInfo, resetTransferStats, transferDetails } from '../store';
|
||||
import { addToast } from '../toast';
|
||||
import { SETTINGS } from '../settings';
|
||||
import { crc32 } from './crc32';
|
||||
@@ -48,20 +48,42 @@ export function parseIncomingFrame(view: DataView, sender: FrameSender) {
|
||||
switch (frameType) {
|
||||
case FRAME.RESPONSE:
|
||||
const dataType = view.getUint8(3);
|
||||
|
||||
if (dataType === DATA.PROTO_INFO && payloadLength >= 5) {
|
||||
const version = view.getUint16(4, true);
|
||||
const maxChunkSize = view.getUint16(6, true);
|
||||
protocolInfo.set({ version, maxChunkSize });
|
||||
} else if (dataType === DATA.FS_INFO && payloadLength >= 14) {
|
||||
const totalSizeBytes = view.getUint32(4, true);
|
||||
const freeSizeBytes = view.getUint32(8, true);
|
||||
const maxPathLength = view.getUint8(12);
|
||||
const sysPathLength = view.getUint8(13);
|
||||
const audioPathLength = view.getUint8(14);
|
||||
const sysPath = new TextDecoder().decode(new Uint8Array(view.buffer, 15, sysPathLength));
|
||||
const audioPath = new TextDecoder().decode(new Uint8Array(view.buffer, 15 + sysPathLength, audioPathLength));
|
||||
fsInfo.set({ totalSize: totalSizeBytes / 1024 / 1024, freeSize: freeSizeBytes / 1024 / 1024, maxPathLength, sysPath, audioPath });
|
||||
switch (dataType) {
|
||||
case DATA.PROTO_INFO:
|
||||
const version = view.getUint16(4, true);
|
||||
const maxChunkSize = view.getUint16(6, true);
|
||||
protocolInfo.set({ version, maxChunkSize });
|
||||
break;
|
||||
case DATA.FS_INFO:
|
||||
const totalSizeBytes = view.getUint32(4, true);
|
||||
const freeSizeBytes = view.getUint32(8, true);
|
||||
const maxPathLength = view.getUint8(12);
|
||||
const sysPathLength = view.getUint8(13);
|
||||
const audioPathLength = view.getUint8(14);
|
||||
const sysPath = new TextDecoder().decode(new Uint8Array(view.buffer, 15, sysPathLength));
|
||||
const audioPath = new TextDecoder().decode(new Uint8Array(view.buffer, 15 + sysPathLength, audioPathLength));
|
||||
fsInfo.set({ totalSize: totalSizeBytes / 1024 / 1024, freeSize: freeSizeBytes / 1024 / 1024, maxPathLength, sysPath, audioPath });
|
||||
break;
|
||||
case DATA.DEVICE_INFO:
|
||||
const deviceId = [0, 2, 4, 6]
|
||||
.map(offset => view.getUint16(4 + offset, false).toString(16).padStart(4, '0').toUpperCase())
|
||||
.join('-');
|
||||
const boardNameLength = view.getUint8(12);
|
||||
const boardRevisionLength = view.getUint8(13);
|
||||
const socNameLength = view.getUint8(14);
|
||||
const boardName = new TextDecoder().decode(new Uint8Array(view.buffer, 15, boardNameLength));
|
||||
const boardRevision = new TextDecoder().decode(new Uint8Array(view.buffer, 15 + boardNameLength, boardRevisionLength));
|
||||
const socName = new TextDecoder().decode(new Uint8Array(view.buffer, 15 + boardNameLength + boardRevisionLength, socNameLength));
|
||||
deviceInfo.set({ deviceId, boardName, boardRevision, socName });
|
||||
break;
|
||||
case DATA.FW_INFO:
|
||||
const fwStatus = view.getUint8(4);
|
||||
const slot1Size = view.getUint32(5, true);
|
||||
const fw_version_length = view.getUint8(9);
|
||||
const kernel_version_length = view.getUint8(10);
|
||||
const fwVersion = new TextDecoder().decode(new Uint8Array(view.buffer, 11, fw_version_length));
|
||||
const kernelVersion = new TextDecoder().decode(new Uint8Array(view.buffer, 11 + fw_version_length, kernel_version_length));
|
||||
fwInfo.set({ fwStatus, slot1Size, fwVersion, kernelVersion });
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -92,9 +114,10 @@ export function parseIncomingFrame(view: DataView, sender: FrameSender) {
|
||||
console.warn(`LS Stream: Erwartete Anzahl Einträge laut Header: ${total}, tatsächlich empfangen: ${lsBuffer.length}`);
|
||||
addToast(`Warnung: LS Stream erwartete ${total} Einträge, aber nur ${lsBuffer.length} empfangen.`, 'warning');
|
||||
} else if (lsResolve) {
|
||||
lsResolve([...lsBuffer]);
|
||||
const currentResolve = lsResolve;
|
||||
lsResolve = null;
|
||||
lsReject = null;
|
||||
currentResolve([...lsBuffer]);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -137,10 +160,12 @@ export function parseIncomingFrame(view: DataView, sender: FrameSender) {
|
||||
|
||||
addToast("Dateitransfer abgebrochen (Timeout)", "error");
|
||||
|
||||
if (fileGetReject) {
|
||||
fileGetReject(new Error("Timeout beim Dateitransfer"));
|
||||
fileGetResolve = null;
|
||||
fileGetReject = null;
|
||||
const currentReject = fileGetReject;
|
||||
fileGetResolve = null;
|
||||
fileGetReject = null;
|
||||
|
||||
if (currentReject) {
|
||||
currentReject(new Error("Timeout beim Dateitransfer"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -206,34 +231,39 @@ export function parseIncomingFrame(view: DataView, sender: FrameSender) {
|
||||
|
||||
if (fileTransfer.mode === 'file') {
|
||||
const fileName = get(transferStats).currentFileName;
|
||||
const currentResolve = fileGetResolve;
|
||||
const currentReject = fileGetReject;
|
||||
|
||||
// Direkt hier aufräumen, um Race Conditions bei schnellen Folge-Transfers zu vermeiden
|
||||
fileGetResolve = null;
|
||||
fileGetReject = null;
|
||||
|
||||
saveLocalFile(fileName, fileBlob, fileTransfer.totalBytes)
|
||||
.then(() => {
|
||||
refreshLocal();
|
||||
if (fileGetResolve) {
|
||||
fileGetResolve({ success: true });
|
||||
if (currentResolve) {
|
||||
currentResolve({ success: true });
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Datenbankfehler:", err);
|
||||
addToast(`Speichern von ${fileName} fehlgeschlagen.`, 'error');
|
||||
if (fileGetReject) fileGetReject(err);
|
||||
})
|
||||
.finally(() => {
|
||||
fileGetResolve = null;
|
||||
fileGetReject = null;
|
||||
if (currentReject) currentReject(err);
|
||||
});
|
||||
} else {
|
||||
// TAGS Modus: Blob direkt zurückgeben, nichts speichern
|
||||
if (fileGetResolve) fileGetResolve({ success: true, blob: fileBlob });
|
||||
const currentResolve = fileGetResolve;
|
||||
fileGetResolve = null;
|
||||
fileGetReject = null;
|
||||
if (currentResolve) currentResolve({ success: true, blob: fileBlob });
|
||||
}
|
||||
} else {
|
||||
console.error("[CRC] Mismatch! Datei beschädigt.");
|
||||
addToast("CRC Fehler: Datei wurde fehlerhaft übertragen.", "error");
|
||||
if (fileGetReject) fileGetReject(new Error("CRC Mismatch"));
|
||||
const currentReject = fileGetReject;
|
||||
fileGetResolve = null;
|
||||
fileGetReject = null;
|
||||
if (currentReject) currentReject(new Error("CRC Mismatch"));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -260,16 +290,18 @@ export function parseIncomingFrame(view: DataView, sender: FrameSender) {
|
||||
console.error(`Received error frame with code: 0x${errorCode.toString(16)}`);
|
||||
showErrorToast(errorCode);
|
||||
if (lsReject) {
|
||||
lsReject(new Error(`Buzzer Error 0x${errorCode.toString(16)}`));
|
||||
const currentReject = lsReject;
|
||||
lsResolve = null;
|
||||
lsReject = null;
|
||||
currentReject(new Error(`Buzzer Error 0x${errorCode.toString(16)}`));
|
||||
}
|
||||
if (fileGetReject && fileTransfer.active) {
|
||||
if (fileTransfer.metricsTimer) clearInterval(fileTransfer.metricsTimer);
|
||||
fileTransfer.active = false;
|
||||
fileGetReject(new Error(`Buzzer Error 0x${errorCode.toString(16)}`));
|
||||
const currentReject = fileGetReject;
|
||||
fileGetResolve = null;
|
||||
fileGetReject = null;
|
||||
currentReject(new Error(`Buzzer Error 0x${errorCode.toString(16)}`));
|
||||
}
|
||||
if (uploadState.active && uploadState.onError) {
|
||||
uploadState.onError(new Error(`Buzzer Error 0x${errorCode.toString(16)}`));
|
||||
@@ -293,6 +325,17 @@ export function buildProtocolInfoRequest(): ArrayBuffer {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
export function buildDeviceInfoRequest(): ArrayBuffer {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
|
||||
view.setUint8(0, FRAME.REQUEST);
|
||||
view.setUint16(1, 1, true);
|
||||
view.setUint8(3, DATA.DEVICE_INFO);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
export function buildFSInfoRequest(): ArrayBuffer {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
@@ -304,6 +347,17 @@ export function buildFSInfoRequest(): ArrayBuffer {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
export function buildFWInfoRequest(): ArrayBuffer {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
|
||||
view.setUint8(0, FRAME.REQUEST);
|
||||
view.setUint16(1, 1, true);
|
||||
view.setUint8(3, DATA.FW_INFO);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
export function buildLSRequest(path: string): ArrayBuffer {
|
||||
const encoder = new TextEncoder();
|
||||
const pathBytes = encoder.encode(path);
|
||||
@@ -342,9 +396,10 @@ function resetLsWatchdog() {
|
||||
addToast("Verzeichnis-Streaming abgebrochen (Timeout)", "warning");
|
||||
lsBuffer = [];
|
||||
if (lsReject) {
|
||||
lsReject(new Error("Timeout beim Lesen des Verzeichnisses"));
|
||||
const currentReject = lsReject;
|
||||
lsResolve = null;
|
||||
lsReject = null;
|
||||
currentReject(new Error("Timeout beim Lesen des Verzeichnisses"));
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user