From 3404bc06de0cc580397e6dcf1c670f2efbdb6aae Mon Sep 17 00:00:00 2001 From: mikecarper Date: Fri, 14 Aug 2026 00:54:08 +0000 Subject: [PATCH] deploy: cd824765b4a5a4d041168a876d05f5fecdbdc7e9 --- ota_easy/index.html | 7 +- ota_protocol/index.html | 108 +++++++++++++---------- ota_user_guide/index.html | 19 ++-- rak3401_mota_chain/index.html | 159 ++++++++++++++++++++-------------- search/search_index.json | 2 +- sitemap.xml | 56 ++++++------ sitemap.xml.gz | Bin 485 -> 485 bytes 7 files changed, 199 insertions(+), 152 deletions(-) diff --git a/ota_easy/index.html b/ota_easy/index.html index 461a6effe..2bc2a2deb 100644 --- a/ota_easy/index.html +++ b/ota_easy/index.html @@ -1694,9 +1694,10 @@ entry 1, run:

Monitor the transfer:

ota status
 
-

The update is ready when the status says ready to install. OTA is deliberately the lowest-priority mesh -traffic. At the temporary-radio settings in this guide, allow roughly one hour for a typical ESP32 full -image over a quiet, direct link. That is a planning estimate, not an upper bound: repeaters, retries, weak +

The update is ready when the status says ready to install. Discovery is background traffic, while an +active OTA download is primary mesh traffic. At the temporary-radio settings in this guide, allow roughly +one hour for a typical ESP32 full image over a quiet, direct link. That is a planning estimate, not an +upper bound: repeaters, retries, weak links, and normal mesh traffic can extend it well past an hour. The 120-minute example window is intentional. If necessary, start another overlapping tempradio window; the download resumes rather than starting over.

diff --git a/ota_protocol/index.html b/ota_protocol/index.html index 0322bfcb0..78f6eda8e 100644 --- a/ota_protocol/index.html +++ b/ota_protocol/index.html @@ -1703,8 +1703,8 @@ document is the technical/wire specification.

  • Trustless mesh relay: repeaters may forward packets while the source alone serves firmware data; integrity is content-addressed against a signed merkle root, so a relay need not be trusted and never needs the signing keys.
  • -
  • Lowest priority, always: OTA traffic is enqueued behind all mesh traffic - "eventually upgradable". - A busy node delays OTA indefinitely rather than competing with real traffic.
  • +
  • Primary while transferring: periodic discovery stays at background priority, but manifest, block, + data, and proof packets for an active fetch use primary queue priority at every relay hop.
  • Portable: the engine (src/helpers/ota/OtaManager) is Arduino/radio/crypto-free and host-testable, so the same logic drives a device, a simulation, or a third-party implementation.
  • @@ -1853,9 +1853,14 @@ document is the technical/wire specification.

    block_size_log2 = 0x0A -OTA TX priority +OTA discovery TX priority 250 -lowest (OTA_TX_PRIORITY, src/Mesh.h) +background (OTA_TX_PRIORITY, src/Mesh.h) + + +OTA active-transfer TX priority +0 +primary (OTA_TRANSFER_TX_PRIORITY, src/Mesh.h) @@ -2083,9 +2088,10 @@ while n > 1: idx //= 2 ; n = (n + 1) // 2 accept iff h == merkle_root and p == len(proof) -

    Over LoRa, leaves[] are omitted from the manifest transfer; a serving node computes a block's proof -on demand from its stored leaves[] (OTA_REQ_PROOF/OTA_PROOF, Section 8.5), and the fetcher fills its own -leaves[i] as each verified block lands.

    +

    Over LoRa, leaves[] are omitted from the manifest transfer. A serving node computes a block's proof +on demand from its stored leaves[] and normally sends OTA_PROOF immediately after that block's paced +OTA_DATA. OTA_REQ_PROOF remains the fallback for an older source or a lost proactive proof. The fetcher +fills its own leaves[i] as each verified block lands.


    7. Block availability, staging & resume

    There is no separate availability structure. Block i is present <=> leaves[i] is non-erased @@ -2122,67 +2128,67 @@ small delta that fits page 0 does zero flash I/O until COMPLETE.

    OTA_ADV 0x01 -flood +discovery tiny per-node beacon (discovery tier 1) OTA_QUERY 0x02 -flood +discovery ask a source for its catalog (discovery tier 2) OTA_HAVE 0x03 -flood +discovery the catalog reply (fragmented, digest-tagged) OTA_GET_MANIFEST 0x04 -direct +transfer request a manifest's fragments (want_mask) by manifest_id OTA_MANIFEST 0x05 -direct +transfer the manifest-minus-leaves, fragmented OTA_REQ 0x06 -direct +transfer request specific DATA fragments of one block (want_mask) OTA_DATA 0x07 -direct +transfer one self-describing fragment of a block's data OTA_REQ_PROOF 0x08 -direct -request the merkle proof for one block +transfer +request/re-request a missing proof OTA_PROOF 0x09 -direct +transfer the merkle proof for one block OTA_GET_LEAVES 0x0A -direct +transfer request the target's leaves[] fragments (want_mask) - warm-start only OTA_LEAVES 0x0B -direct +transfer a fragment of the leaves[] array (for host-side seed leaf-diff) @@ -2190,20 +2196,23 @@ small delta that fits page 0 does zero flash I/O until COMPLETE.

    8.1 Two-tier discovery

    Because a node may serve many mOTAs (its own firmware plus an external folder - Section 10), discovery is split @@ -2261,8 +2270,8 @@ pattern), all in OtaManager:

    OTA_REQ(mid, block_idx, want_mask) > (want_mask=all fragments first; only the holes on retry) <------- OTA_DATA(mid, block_idx, frag_off, data) x requested frags (reassemble block from frag_off slices) - OTA_REQ_PROOF(mid, block_idx) ----> - <------- OTA_PROOF(mid, block_idx, n_proof, proof) + <------- OTA_PROOF(mid, block_idx, n_proof, proof) (proactive) + [if proof is absent after grace: OTA_REQ_PROOF(mid, block_idx) -> legacy/loss fallback] (verify proof vs merkle_root -> write block -> write leaves[i]) when all blocks present: verify full merkle_root + image_hash -> COMPLETE @@ -2293,7 +2302,7 @@ OTA_LEAVES: manifest_id[4] frag_idx(1) frag_total(1) bytes[] # up is answering OTA_GET_LEAVES with leaves the node already holds, so any node's firmware can be captured.

  • -

    Block <-> fragments: a 1 KB block is split into self-describing OTA_DATA fragments. frag_off is the +

    Block <-> fragments: a 1 KB block remains split into self-describing OTA_DATA fragments. frag_off is the byte offset of data within the block, so the global position is block_idx*block_size + frag_off - a fragment is self-placing when returned by the source. The fetcher tracks a per-block slice bitmap and reassembles before requesting the proof.

    @@ -2308,10 +2317,12 @@ OTA_LEAVES: manifest_id[4] frag_idx(1) frag_total(1) bytes[] # up with the tail of the in-flight burst and drop the same fragment forever - a hang. Requesting only the hole removes the burst, so there is nothing to collide with. The block/manifest mask matches the 16-bit reassembly bitmap (<=16 fragments/block; 1 KB blocks = 7). OTA_PROOF is a single packet and needs no mask.
  • -
  • Data and proof are separate phases. OTA_DATA carries no proof; the proof is fetched once per block - via OTA_REQ_PROOF/OTA_PROOF after that block's data is complete. The receiver keeps a bounded two-block - window, so one block can await its proof or flash commit while DATA for the next block arrives. Slots retry - independently and only one stalled slot is retried per service tick.
  • +
  • Data and proof remain separate packets, without a normal extra round trip. A server retains requested + blocks in a bounded descriptor queue, admits at most one response per main-loop pass, and sends one + OTA_PROOF after the requested fragments. The receiver waits 500 ms after completing a block, then uses + OTA_REQ_PROOF only as a loss/legacy-server fallback. It keeps a bounded multi-block window, so one block + can await proof or flash commit while DATA for the next block arrives. Slots retry independently and only + one stalled slot is retried per service tick.
  • 8.5 Sizing against MAX_PACKET_PAYLOAD = 184

    @@ -2350,17 +2361,21 @@ payload); larger self-images pass a bigger scratch buffer.

    8.6 Temporary-radio and transfer boundary

    OTA packets may cross normal mesh relay hops, but each participating node processes or relays them only while its tempradio window is actually running. A receiver selects missing blocks in serial order into a bounded -two-block pipeline. It never serves partial blocks. A normal install receiver never re-advertises its completed +request pipeline. The default capacity is two blocks. Targets with a larger compiled capacity begin at two, +grow the live window by one after four clean verified blocks, and shrink it after two consecutive no-progress +service ticks; the RAK3401 LoRa-OTA target currently adapts from two through four blocks. It never serves +partial blocks. A normal install receiver never re-advertises its completed download. An SD archive node is the deliberate exception: after a fully proof-verified container is published to its persistent archive, it registers that complete file as a MotaSource and advertises it as a new seeder. This keeps each active transfer as one transmitter and one receiver while still allowing active temporary-radio repeaters between them and persistent archive nodes to improve future availability.

    -

    Because TempRadio is a bounded channel dedicated to this transfer, an accepted OTA flood normally relays after -a randomized 0.25 to 0.5 packet-airtime delay. Repeated requests for the same manifest block or proof provide -congestion feedback without changing the wire format. Frequent retries widen the local relay window through -0.5-1.0, 0.75-2.0, and finally 1.0-3.0 airtimes. The maximum is hard-capped at three packet airtimes. Each -30-second interval without another observed retry lowers the window one level. Other flood payloads retain the -role's normal randomized delay, and CAD still applies when enabled.

    +

    TempRadio is treated as a private maintenance network. Active transfer packets use priority 0, bypass the +public-flood receive holdoff and relay jitter, and do not schedule generic flood retries. The bounded serving +queue admits at most two DATA/PROOF packets ahead of the radio while preserving at least four free packet-pool +entries. CAD remains enabled to arbitrate the half-duplex channel, but its busy retry is scaled to one-quarter +of a packet airtime and clamped to 5-50 ms instead of the ordinary 120-360 ms cadence. Discovery traffic keeps +collision jitter and background priority. These changes remove software waits and duplicate bursts; they do +not remove the one required forwarding transmission per hop.


    9. Identity, trust & versioning