From 49820b57aa4ff42f60aeea4fa1770a646c2d73b1 Mon Sep 17 00:00:00 2001 From: Valentin Kivachuk Burda Date: Thu, 2 Jul 2026 08:52:40 +0200 Subject: [PATCH] docs: pull a firmware .mota off the mesh into a motatool folder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document `ota pull <#> ` (flash|folder, destination mandatory), the folder pull that captures a device's exact firmware to the host as .mota (for delta-building), the paused/resume-on-reconnect behaviour, and that a `motatool serve` link doubles as the pull-to-folder store. (protocol §10, user guide, motatool README) --- docs/ota_protocol.md | 8 ++++++++ docs/ota_user_guide.md | 21 +++++++++++++++------ tools/motatool/README.md | 2 +- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/docs/ota_protocol.md b/docs/ota_protocol.md index 4e7f5a28..d60140c6 100644 --- a/docs/ota_protocol.md +++ b/docs/ota_protocol.md @@ -482,6 +482,14 @@ verify everything). The serve side (`OtaManager`) keeps a lightweight registry o resident "views": `view0` (its own firmware) and one on-demand view loaded from a source when a request targets an external mota. Every fetch message carries `manifest_id`, so dispatch is a registry lookup. +The same host-folder link is also a **pull destination** (the reverse direction): `ota pull <#> folder` +fetches a `.mota` off the mesh and streams it onto the host as `.mota` via the seeder STORAGE ops +(`OP_STAT/BEGIN/WRITE/SREAD/FIN`, see `MotaSeederProto.h`), using a `FolderMotaStore` as the fetch's +`OtaStore` instead of RAM/flash. This captures an exact copy of a device's firmware — e.g. to build a delta +against firmware you don't have. Resume is bookkeeping-free: `BEGIN` 0xFF-fills the file and, on reconnect +after a link drop (the fetch PAUSES, holding progress on the host — no RAM/flash fallback), `STAT`+`SREAD` +let the fetcher recompute and refill only the missing blocks. + ### 10.1 The `MotaSource` abstraction (`OtaSource.h`) Transport-agnostic provider of one or more complete `.mota` as random-access bytes. The same serve code diff --git a/docs/ota_user_guide.md b/docs/ota_user_guide.md index 0235be23..c24de359 100644 --- a/docs/ota_user_guide.md +++ b/docs/ota_user_guide.md @@ -75,17 +75,26 @@ downloaded yet; this is just looking around. (`ota neighbors` / `ota updates` al ### 3. Download an update -Pick one from the list by its **number**: +Pick one from the list by its **number**, and say **where** to put it: ``` -ota get 1 +ota pull 1 flash # stage it in this node's flash, to install here +ota pull 1 folder # capture it onto a connected motatool folder as .mota (don't install here) ``` -The node starts fetching it in the background, **at low priority**, a piece at a time — possibly from -several neighbours at once. Check progress any time with `ota status` (you'll see it climb, e.g. -`download: downloading 120/525 (23%)`). You can keep using your node normally meanwhile. +The destination is required — `ota pull 1` on its own just shows the choices. **`flash`** is always +available (stage here, then `ota install`). **`folder`** appears only while a `motatool serve` link is +attached (it shows the link, e.g. `folder: tcp 192.168.4.5`); it streams the firmware straight onto the +host folder — nothing is staged on this node. That's how you grab an **exact copy of another device's +firmware** off the mesh (to a `.mota` file) so you can later build a *delta* against firmware you don't +otherwise have. (`ota get` is an alias.) -To **stop** a download you no longer want: +The node fetches in the background, **at low priority**, a piece at a time — possibly from several +neighbours at once. Check progress with `ota status`. You can keep using your node normally meanwhile. + +If a `folder` pull loses its link mid-transfer, `ota status` shows **paused** — the host keeps the +partial and the pull resumes (filling only what's missing) the moment you reconnect motatool; it never +falls back to flash. To **stop** a download you no longer want: ``` ota cancel diff --git a/tools/motatool/README.md b/tools/motatool/README.md index 235d8af4..80276d40 100644 --- a/tools/motatool/README.md +++ b/tools/motatool/README.md @@ -16,7 +16,7 @@ cross-checked byte-for-byte against the Python reference packager `tools/mota/mo | `build` | Create a **full** or **delta** `.mota` from a firmware (local file **or** http(s) URL). | | `verify` | Validate one or more `.mota` (merkle tree, leaves vs payload, image hash, Ed25519 signature). `--pub` requires a specific signer; `--base` confirms a sequential delta rebuilds its image. | | `inspect`| Print every field of a `.mota`'s manifest (debugging). | -| `serve` | Serve a **folder** of `.mota` to a node over USB serial (`--serial`) or WiFi (`--tcp`). Invalid files are warned about and skipped — one corrupt file never sinks the rest. | +| `serve` | Serve a **folder** of `.mota` to a node over USB serial (`--serial`) or WiFi (`--tcp`). Invalid files are warned about and skipped — one corrupt file never sinks the rest. The same link also **stores** a node's `ota pull … folder` captures into that folder as `.mota` — pull a device's exact firmware off the mesh to build deltas against firmware you don't otherwise have. | | `keygen` | Generate an Ed25519 signing keypair (hex). | Every command has detailed, example-rich help: `motatool --help`.