OTA update

OTA update - filesystem and ZIP helpers.

Module-level functions and constants of firmware_core.py that findylab.findyIoT.findyIoT.downloadUpdate(), findylab.findyIoT.findyIoT.update() and boot.py build on. The package is a ZIP archive that must be stored uncompressed - build it with zip -0 -r -X fw.zip .; DEFLATE entries are only handled when the device build ships the deflate module.

Download and apply are two independent, restartable phases and the final swap onto the live tree is committed at boot from a staging directory, so a power loss or network drop at any point is safe:

  • drop while downloading - resume from the byte offset already on flash;

  • drop while extracting - no OTA_COMMIT marker, the package is discarded, retry command 52;

  • drop while boot-committing - marker still present, the copy re-runs (idempotent);

  • new firmware will not import - boot.py falls back to base.py.

See Over-the-air update for the whole flow.

findylab.ota.OTA_CHUNK = 1460

Download chunk size in bytes (LTE MTU-sized; was 512 on 2G).

findylab.ota._ota_busy = False

Re-entrancy guard for downloadUpdate().

findylab.ota.OTA_ZIP = '/update.zip'

The package being downloaded.

findylab.ota.OTA_META = '/update.meta'

JSON pinning the partial download to a package name, size and chunk size.

findylab.ota.OTA_STAGE = '/next'

Staging directory the package is extracted into.

findylab.ota.OTA_COMMIT = '/update.commit'

Commit marker - boot.py copies OTA_STAGE onto the live tree while it exists.

findylab.ota.OTA_APPLIED = '/update.applied'

Written by boot.py after a successful commit; consumed by the next report.

findylab.ota._ZIP_LOCAL_SIG = b'PK\x03\x04'

ZIP local file header signature.

findylab.ota._ota_mkdirs(path)[source]

mkdir -p for a ‘/a/b/c’ path (ignores already-existing dirs).

findylab.ota._ota_rmtree(path)[source]

rm -rf, tolerant of a missing path.

findylab.ota._zip_entries(f)[source]

Yield (name, method, crc, csize, usize, data_pos) for every local file header in an open zip, seeking f to the next header after each item. Stops at the central directory. Raises ValueError on a streaming data descriptor (flag bit 3): zip -0 -X never sets it, but a wrongly built archive would, and we must not guess sizes for an OTA image.

findylab.ota._ota_inflate_crc(f, csize, sink)[source]

Inflate a DEFLATE entry (f positioned at its data), pushing plaintext into sink(bytes) if given and returning its CRC32 - or None if the build has no deflate module.

findylab.ota.ota_zip_ok(path)[source]

Verify every entry’s CRC32 end-to-end. True if the whole archive is intact, False on any mismatch/parse error, None if it needs DEFLATE support the build lacks.

findylab.ota.ota_extract(path, dest)[source]

Extract every entry of path under dest, verifying each file’s CRC32 as it is written. True only if all files extracted and matched. Writes into a staging dir only - never touches live files.