Companion manifest OTA (ota check / ota update)
The Wi-Fi companions (*_companion_radio_usb_tcp envs) can look up and install the
newest published build themselves, instead of being handed a URL with ota url.
The logic is ported from the DMC observer firmware (Dutch-MeshCore/MeshCore, branch
dmc-observer-dev) and uses the same OTA server and manifest format.
Commands
Send these to the meshcomod command contact (the same place as ota url).
| Command | What it does |
|---|---|
ota check |
Fetches this build's manifest and reports up to date, update available: <running> -> <published>, or why it cannot update. Works from any transport while Wi-Fi is connected. |
ota update |
Runs the same check and, when an installable update exists, downloads and flashes it through the ota url path (progress lines, reboot on success). Like ota url, it must be started from a Wi-Fi TCP or WebSocket session on multi-transport builds. |
ota update does nothing when:
- the running build is the published one (
up to date); - the running build is newer than the published one (no downgrades);
- the published build was made for a different partition layout (
needs a USB flash). OTA only rewrites the app slot, so a layout change needs the merged image over USB.
A build with the same version but a different commit counts as an update
(same version, other build), so a local build can be moved back onto the release.
How it works
build.shbakes two values into*companion_radio_usb_tcp*envs:OTA_VARIANT: the env name, which selects the manifest file.OTA_MANIFEST_BASE: defaulthttps://ota.dutchmeshcore.nl/meshcomod/v, overridable withOTA_MANIFEST_BASE_URL.- The device fetches
<base>/<env>.jsonover plain HTTP (no TLS, so it is cheap on RAM-tight builds). The manifest looks like:
json
{"file":"https://ota.dutchmeshcore.nl/meshcomod/fw/<tag>/<env>-<version>-<hash>.bin",
"version":"v1.18.0.2","hash":"abc1234","partSig":"1:2:9000:5000,..."}
- The version is compared numerically (
v1.18.0.1<v1.18.0.2<v1.19.0.0), then by commit hash when the versions match. partSigis compared with the partition table flashed on the device.build.shwrites it toout/<env>.partsigwithscripts/partition_signature.py, and the firmware computes the same string at runtime (ota_partsig_formatinsrc/helpers/OtaManifest.h). Manifests withoutpartSigskip this check.- The image URL must sit under the server's firmware path for this product
(
<base>with the trailing/vreplaced by/fw/); anything else is refused. The download then runs throughstartHttpOtaFromUrl, the same code asota url.
Builds made without build.sh have no manifest base and answer
ERR: OTA manifest not configured (build via build.sh).
Publishing
The OTA server mirrors this repo's GitHub releases tagged companion-* (see
CI_RELEASES.md). A release needs, per env:
<env>-<version>-<hash>.bin(the app image;-merged.binis ignored), and<env>.partsig(optional, enables the partition-layout check).
The companion workflow uploads all of out/, so both come along with a normal tagged
build. Pre-releases (companion-v1.18.0.1-pre42, -rc1) are not served over the air.
A device running a pre-release is offered the stable build of the same or a newer
version (v1.18.0.1-pre42 counts as v1.18.0.1 with another commit). Keep FIRMWARE_VERSION free of - (for example v1.18.0.2, not
v1.18.0.2-DMC-EV): the server splits asset names on - to find the env, version and
hash.
Notes
- The firmware download uses HTTPS without certificate checks, exactly like
ota urltoday. The ESP32 image checksum still catches a corrupted download. - The touch env (
heltec_v4_tft_companion_radio_usb_tcp_touch) compiles with these commands, but touch boards are released from wadamesh, not from this repo's CI, so there is no published manifest for it here.