Skip to content

feat: web firmware update with verification and rollback (Firmware tab) - #17

Merged
mcamposv merged 1 commit into
mainfrom
feature/issue-16-web-update
Nov 2, 2026
Merged

mcamposv merged 1 commit into
mainfrom
feature/issue-16-web-update

Conversation

@mcamposv

@mcamposv mcamposv commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Closes #16

Summary

  • New Firmware tab (/firmware): installed version, running partition (app0/app1), validation state, free space, disclaimer and upload form.
  • Browser checks before uploading: ESP32 app image (0xE9, ESP32 chip; tells you to use firmware.bin if factory.bin is picked), project marker MBPXY-FW:<ver>;, size, version comparison (newer / same / downgrade). The button is enabled only with a valid file and the disclaimer accepted.
  • ESP32 checks while receiving: writes to the free OTA partition; scans the stream for the project marker and aborts without touching the boot partition if missing; Update.end() validates SHA-256.
  • Rollback: new image stays pending validation until it has run 30 s with network (or reached the Setup portal); an earlier reboot makes the bootloader return to the previous image. Also applies to ArduinoOTA.
  • Proxy paused during the upload, OLED progress; ArduinoOTA shares the same helpers.
  • Version in #define FW_VERSION (firmware, CI and pre_upload.py); /api/status adds firmware_version.
  • Release notes, READMEs (ES/EN), changelog and i18n updated. Firmware 6.2-0.

Test plan (test proxy .213 + EMMA emulator)

  • Build with no new warnings (flash 75.8 %)
  • OTA 6.1-0 → 6.2-0, config preserved, /firmware renders
  • Rejected without reboot (uptime kept, proxy resumed): random data (Wrong Magic Byte), fake 0xE9 header (no marker), 6.1-0 factory.bin, 6.1-0 firmware.bin (pre-marker)
  • Valid web upload: HTTP 200 in ~12.5 s, partition switched, state Pending validation at 3 s → Validated at 30 s
  • Rollback: uploaded a test build 6.2-99 that reboots at 10 s → bootloader returned to 6.2-0, stable and validated
  • Found and fixed: verifyRollbackLater() needed extern "C" — without it the core's weak C symbol won and rollback was silently disabled
  • Page JS: syntax-checked and run against real files in Node (valid, newer/older, pre-marker, factory, random)
  • Manual check in a browser

Note: devices on < 6.2-0 have no Firmware tab, so the first update to 6.2-0 must be via OTA or USB (stated in the release notes).

🤖 Generated with Claude Code

…b) — closes #16

New "Firmware" tab (/firmware) showing installed version, running
partition, validation state and free space, plus an upload form for the
modbusproxy-<ver>-firmware.bin from GitHub Releases.

Verification:
- Browser, before uploading: ESP32 app image header (0xE9, chip ESP32;
  warns when factory.bin is picked), project marker MBPXY-FW:<ver>;,
  size, version comparison (newer / same / downgrade) and a mandatory
  disclaimer checkbox.
- ESP32, while receiving: writes to the free OTA partition via Update,
  scans the stream for the project marker and aborts without touching
  the boot partition if it is missing; Update.end() checks the SHA-256.

Rollback: verifyRollbackLater() (extern "C", so it overrides the core's
weak C symbol) keeps a freshly installed image pending until it has run
30 s with network (or reached the Setup portal). If it reboots earlier
the bootloader returns to the previous image. Also covers ArduinoOTA.

The proxy pauses during the upload and the OLED shows progress, sharing
helpers with ArduinoOTA. The version now lives in #define FW_VERSION,
read by the firmware, CI and pre_upload.py; FW_MARKER embeds it in the
binary. /api/status adds firmware_version. Release notes explain the
web update. i18n ES/EN/DE, READMEs and changelog updated. Bump to 6.2-0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mcamposv
mcamposv merged commit 48071b3 into main Nov 2, 2026
2 checks passed
@mcamposv
mcamposv deleted the feature/issue-16-web-update branch November 2, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: actualización de firmware desde la web (pestaña Firmware)

1 participant