The Arduino network client treats a half-closed connection as closed,
so the device's reply after the sender's EOF was lost. The header
already carries the image size: UpdateParser::complete() lets the
device finish and answer while the connection is open. ota_push.py
half-closes only if no answer comes within 3 s, for older firmware.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
lib/ota: a 160-byte header (magic, format, image size and SHA-256,
version, ECDSA signature over the first 80 bytes) then the image.
UpdateParser checks the header and signature before writing anything,
hashes the image as it streams into an UpdateSink, and only finishes
the sink when the hash matches. Downgrades are flagged, not refused.
Includes a dependency-free SHA-256 and semver comparison.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT