Repository navigation
Conversation
xfer.begin/chunk/end/cancel over the VibeBuddy Protocol, so the same transfer runs over USB, the local network and the Relay (inside the Noise session off the cable). The box writes the OTA slot it isn't running from, erasing one sector ahead of the writes, acknowledges each chunk of up to 3072 bytes with the next offset it expects, and keeps the progress in memory: an xfer.begin for the same image carries on from there, over any way of carrying the link. On xfer.end it reads the slot back and checks the SHA-256 before it writes otadata, then restarts; the new image boots once and confirms itself, or the bootloader goes back (ADR-0013). ota.rs learns which slot is running, how to select the other one (in the sector that keeps the running entry, so there is something to go back to), and whether the last update was rolled back. The box answers hello with TRANSFER 1, and FIRMWARE ROLLED BACK after a rollback. Lines from a computer may now be 4608 bytes, so a chunk fits one; a sealed line on the local network 8192. Refs #138 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The daemon sends the app image as xfer.chunk lines of 3072 bytes, four ahead of the box's acknowledgements, to any box that reports TRANSFER 1, on the cable as well as over the local network and the Relay. When the link drops or moves it waits up to three minutes for it to come back and asks again with xfer.begin; the box answers with where it got to. After xfer.done it waits for the box to report its build again, and reports a failure if the box says FIRMWARE ROLLED BACK. Older firmware keeps the ROM flasher, and still needs the cable. The protocol's line limit goes from 1024 to 4608 bytes so a chunk fits one line; only chunks come near it, and only firmware that reports TRANSFER 1 gets them. /v1/status reports device.transfer and device.rolled_back. The Mac and Linux apps keep their Update and Flash from file... buttons as they are; after a failed update they show the hold-K0-and-replug advice only for firmware that updates through the ROM. Docs: Firmware over the link in docs/protocol.md, the update flow in docs/app.md; resuming large writes is no longer undecided in docs/relay-protocol.md. Refs #138 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a box over USB, an image that failed before confirming itself had already printed its build, so the daemon reported the update done while the bootloader was going back. The daemon now waits 8 s after the new build and reads the box's answer after that: a rollback restarts it within about 2 s and says FIRMWARE ROLLED BACK. Over the network the box is only reached once it has confirmed itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a box a 2.8 MB image took 38 s over USB, 115 s over the local network and about 4 minutes through the Relay. The box erased one 4 KB sector per chunk, about 690 erases; it read the network 256 bytes at a time, each piece an event for the main loop; and four chunks in flight were too few for the Relay's round trip. The box now erases what the image needs before it answers xfer.begin, one 64 KB block per main-loop pass, and only writes while chunks arrive. That also keeps erases, which stop interrupts, away from bytes arriving on the UART bridge. It reads the network 1 KB at a time. The daemon keeps up to 16 chunks in flight and sends at most 40 a second, under the Relay's 50 messages a second, and gives xfer.ready 60 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third step of #138: the chunked, resumable transfer from ADR-0016, used first for firmware.
What changes
firmware-rs/core/src/transfer.rs,ota.rs):xfer.begin/chunk/end/cancel. The box writes the OTA slot it isn't running from, erasing one 4 KB sector ahead of the writes, acks each chunk (≤ 3072 B) with the next offset it expects, keeps progress in memory so a repeatedxfer.beginfor the same image resumes, over any link. Onxfer.endit reads the slot back, checks SHA-256, then selects the slot inotadata(state NEW, in the sector that keeps the running entry) and restarts. Rollback is ADR-0013's. New hello lines:TRANSFER 1,FIRMWARE ROLLED BACK.daemon/src/transfer.rs): window of 4 chunks; on a drop or a link move it waits up to 3 min and resumes withxfer.begin.POST /v1/device/firmwaretakes this path whenever the box reportsTRANSFER 1(cable too), the ROM flasher otherwise. Success = the box reports its build again withoutFIRMWARE ROLLED BACK./v1/statusaddsdevice.transferanddevice.rolled_back.TRANSFER 1firmware.docs/protocol.md"Firmware over the link",docs/app.mdupdate flow,docs/relay-protocol.md.Not in this PR (deviations from ADR-0016)
UPDATING n%overlay and cancelling with a long K2. Follow-up.xfer.*(kind: characteranswersunsupported); they still usevoice.*.Checked
cargo test --workspace, clippy (no new warnings),swift build+ SelfTest,check-localization.py,tools/build-firmware.sh(app 2,820,896 B).xfer.doneafter the SHA-256 check.On a box
With dragon's go-ahead (App quit, this branch's daemon):
FIRMWARE ROLLED BACK, daemon reports the update failedThe rollback test found a bug, fixed in this branch: over USB the failing image prints its build before it confirms itself, so the daemon reported success. It now waits 8 s and reads the box's answer after that.
Too slow over the network: the ADR expected under a minute. To look at next, before merging or as a follow-up: the box reads the LAN in 256-byte pieces through a 16-deep channel drained once per main-loop pass, and erases 4 KB sectors one at a time (~690 erases for 2.8 MB, ~30 s on their own, which also caps USB); over the Relay the window of 4 chunks is small for its round trip.
The box is back on main's firmware with the previous App running.
Refs #138
🤖 Generated with Claude Code