// OTA command senders. The firmware listens on the WebSocket for two-byte // binary frames [FIRMWARE_UPDATE_CMD_HEAD, cmd_id] (see command_interface.h // in the firmware). The dispatch is currently commented out in // websocket_server.cpp — uncomment it on the firmware side to make these flow. // // Per the firmware retarget choice, the S3 build reuses the P4 enum slots: // 0x00 = REQUEST_AVAILABLE_UPDATES // 0x02 = START_UPDATE (S3 firmware) // 0x03 = START_UPDATE (S3 webinterface) import { $websocket } from "../WebSocketAtom"; const FIRMWARE_UPDATE_CMD_HEAD = 0xBB; const FIRMWARE_UPDATE_CMD_REQUEST_AVAILABLE_UPDATES = 0x00; const FIRMWARE_UPDATE_CMD_START_UPDATE_S3_FIRMWARE = 0x02; // reused P4 slot const FIRMWARE_UPDATE_CMD_START_UPDATE_S3_WEBINTERFACE = 0x03; // reused P4 slot function wsOpen(): WebSocket | null { const ws = $websocket.get(); return ws && (ws as WebSocket).readyState === WebSocket.OPEN ? (ws as WebSocket) : null; } function sendFwCommand(cmdId: number): boolean { const ws = wsOpen(); if (!ws) { console.error("[OTA] WS not open, cannot send command", cmdId); return false; } ws.send(new Uint8Array([FIRMWARE_UPDATE_CMD_HEAD, cmdId])); return true; } export function request_available_updates(): boolean { return sendFwCommand(FIRMWARE_UPDATE_CMD_REQUEST_AVAILABLE_UPDATES); } export function start_firmware_update_s3_fw(): boolean { return sendFwCommand(FIRMWARE_UPDATE_CMD_START_UPDATE_S3_FIRMWARE); } export function start_firmware_update_s3_web(): boolean { return sendFwCommand(FIRMWARE_UPDATE_CMD_START_UPDATE_S3_WEBINTERFACE); } // Sent on WS open so the firmware updates its currentVersion for the // LittleFS image. The bundled web app is the source of truth for this // version (LITTLEFS_VERSION in AppProviderStore.tsx). export function send_webinterface_version(version: string): boolean { const ws = wsOpen(); if (!ws) return false; ws.send(JSON.stringify({ message_type: "set_webinterface_version", version })); return true; }