mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-22 14:11:18 +00:00
Record qualified G2 OTA transitions and power-saving idle checks
This commit is contained in:
1 parent
95913c5301
commit
c88885a315
2 files changed
+192
-10
No files matched your search
@@ -1,5 +1,7 @@
|
||||
# MeshCore 1.17.1.9 USA Cascade
|
||||
|
||||
This release remains held and unpublished.
|
||||
|
||||
USA Cascade defaults are 910.525 MHz, 62.5 kHz bandwidth, SF7 and CR5. Saved
|
||||
radio settings take precedence. Match the exact board, role and storage
|
||||
layout before installing an image.
|
||||
@@ -16,6 +18,14 @@ layout before installing an image.
|
||||
- The pinned ESP32-S3 framework releases retained TinyUSB PHY ownership when
|
||||
starting hardware CDC after a software restart. KISS clears incomplete
|
||||
host frames on a USB session reset while preserving active radio work.
|
||||
- Browser OTA uploads allow 30 seconds of body inactivity after admission.
|
||||
An upload error stays attached to its HTTP request and stops further flash
|
||||
writes. Error callbacks avoid raw USB printing that could block the shared
|
||||
network task when a connected host stops reading.
|
||||
- Infrastructure WebConfig retries its saved WiFi when MQTT has no running
|
||||
worker. Ownership follows the actual worker state while canonical WiFi
|
||||
credentials and 64-hex password support remain independent of that state.
|
||||
Companion's manual WiFi startup behavior is preserved.
|
||||
- Companion packet streaming supports stock serial MQTT consumers. Text CLI
|
||||
and Binary Companion handoff and reply deadlines are covered against the
|
||||
official app's protocol behavior.
|
||||
@@ -65,9 +75,12 @@ rules into the supported slots and save them before installing a smaller
|
||||
table. An over-capacity policy is retained on storage but remains inactive
|
||||
until compatible firmware is installed.
|
||||
|
||||
Native hardware CDC can change the USB product name and Linux `/dev/serial/by-id`
|
||||
path. Update serial consumers to the new device path after the first upgrade.
|
||||
Do not identify a radio solely by a changing `/dev/ttyACM` number.
|
||||
Switching from TinyUSB to native hardware CDC changes the USB product name and
|
||||
Linux `/dev/serial/by-id` path. Update serial consumers to the new device path
|
||||
after the first upgrade.
|
||||
Hardware CDC descriptors are fixed in silicon; firmware cannot retain a custom
|
||||
TinyUSB product name. Do not identify a radio solely by a changing `/dev/ttyACM`
|
||||
number. See [Espressif's explanation](https://github.com/espressif/arduino-esp32/issues/11394#issuecomment-3778833461).
|
||||
|
||||
nRF52 application UF2 and DFU ZIP files do not install a bootloader. Use the
|
||||
exact board/storage OTAFIX mapping in the [firmware picker](../firmware_picker.md).
|
||||
@@ -83,12 +96,37 @@ families. The G2 passed physical USB command/reconnect tests with its original
|
||||
identity and settings preserved. A separate RAK4631 recovery admin was verified
|
||||
by passwordless LoRa login, remote status and a remote version reply.
|
||||
|
||||
The attempted old-TinyUSB Wi-Fi OTA transition did not reach an upload: its
|
||||
WebConfig/Wi-Fi handoff and a subsequent old-firmware USB timeout prevented
|
||||
that path. The G2 was restored over USB and its hardware CDC runtime passed
|
||||
444 strict-deadline queries and a 150-second closed-port idle/reconnect test.
|
||||
The retained-PHY transition is covered synthetically; this attempt does not
|
||||
establish a successful physical TinyUSB-to-hardware-CDC OTA upgrade.
|
||||
Earlier old-firmware handoff attempts did not qualify an OTA migration. After
|
||||
USB restoration, hardware CDC passed 444 strict-deadline queries and a
|
||||
150-second closed-port idle/reconnect test. Those results remain separate from
|
||||
the subsequent physical OTA qualification.
|
||||
|
||||
On 2026-10-05, the G2 passed an app-only HTTP OTA upgrade from a real TinyUSB
|
||||
build to normal hardware CDC, both built from `95913c53`. The test drained the
|
||||
same TCP socket's outstanding bytes before pausing the upload for 4.510 seconds.
|
||||
HTTP returned 200 after 22.559 seconds. Firmware restarted itself, the host
|
||||
observed the USB product change, and the first ordinary website `time` command
|
||||
was acknowledged in 2.997 seconds against the unchanged 5-second deadline.
|
||||
Identity, saved runtime settings, and the original and recovery Admin ACLs
|
||||
were preserved. No cable, power, reset, ROM or rescue action was used during
|
||||
the measured upgrade; the Pi's original WiFi connection was restored.
|
||||
|
||||
This is a controlled current-source TinyUSB baseline, not proof of an upgrade
|
||||
from released stock 1.17.1. A separate earlier LAN upload reset mid-transfer;
|
||||
continuous uptime and a later successful AP retry showed no CPU crash, but
|
||||
the LAN failure's cause remains unproven. The synthetic regressions execute
|
||||
production upload callbacks, preserve queued errors, and distinguish the old
|
||||
3-second body timeout from the bounded 30-second allowance. Local uploader,
|
||||
OTA startup, WiFi lifecycle and station ownership tests passed. The latest
|
||||
`95913c53` hardware CDC application passed quiet 180-second power-saving trials
|
||||
with the port open and closed, without keepalives or a CPU restart. First
|
||||
replies took 18.551 ms and 14.728 ms; original power-saving off and other saved
|
||||
settings were restored. A plain `start ota` then advertised a working LAN
|
||||
endpoint, reported the WebConfig handoff, and served its page and exact G2
|
||||
identity over HTTP. OTA stopped cleanly and the original WebConfig, settings,
|
||||
Admin ACLs, Pi network and host services were restored. The earlier radio CAD
|
||||
warning remained unchanged; the earlier LAN upload failure's cause is still
|
||||
unproven. The current GitHub unit workflow remains pending for this held release.
|
||||
|
||||
Build qualification does not establish physical compatibility on every board.
|
||||
Hardware CDC has finite buffers, and closing a Linux TTY does not necessarily
|
||||
|
||||
@@ -197,12 +197,16 @@ port while leaving USB connected is not proof of a new firmware session; a
|
||||
partial command may survive that close. Bus reset/unplug cleanup and protocol
|
||||
client leases must be tested separately. Hosts should rediscover the port after
|
||||
the backend change: the USB product and `/dev/serial/by-id` path can change.
|
||||
Espressif confirms that hardware CDC descriptors are fixed in silicon, so
|
||||
firmware cannot preserve a custom TinyUSB product name.
|
||||
[Arduino-ESP32 maintainer comment](https://github.com/espressif/arduino-esp32/issues/11394#issuecomment-3778833461),
|
||||
[ESP-IDF maintainer comment](https://github.com/espressif/esp-idf/issues/18516#issuecomment-4316973953).
|
||||
|
||||
Upstream reports checked for this transition:
|
||||
|
||||
| Report | Documented behavior | Relevance and mitigation |
|
||||
| --- | --- | --- |
|
||||
| [ESP-IDF #9826](https://github.com/espressif/esp-idf/issues/9826) | S3 retains TinyUSB PHY ownership across software/watchdog restart, preventing USB Serial/JTAG operation. | Pinned HWCDC initialization now explicitly restores the official S3 hardware PHY route and detaches the former OTG connection first. Executed initialization tests seed the retained RTC state; real OTA transition remains a separate hardware check. |
|
||||
| [ESP-IDF #9826](https://github.com/espressif/esp-idf/issues/9826) | S3 retains TinyUSB PHY ownership across software/watchdog restart, preventing USB Serial/JTAG operation. | Pinned HWCDC initialization restores the official S3 hardware PHY route and detaches the former OTG connection first. Initialization fixtures seed retained RTC state; the controlled physical G2 OTA transition below also passed. |
|
||||
| [Meshtastic #10955](https://github.com/meshtastic/firmware/issues/10955) | Tracker V2 watchdog reboot after a serial reader closes; raw log writes block while the USB bus remains alive. Reproduced on Arduino 2.x and 3.x. | Applies to the same hardware/backend combination. Our bounded writer and diagnostic admission prevent waiting for a host to drain output; synthetic negative controls exercise unsafe raw writes. |
|
||||
| [Meshtastic #10975](https://github.com/meshtastic/firmware/issues/10975) | Tracker V2 binary synchronization corrupted by interleaved diagnostics and abandoned short-write suffixes. | Companion/KISS tests retain suffixes across short writes; KISS disables diagnostics before board initialization. |
|
||||
| [Arduino-ESP32 #12782](https://github.com/espressif/arduino-esp32/issues/12782) | Open report of HWCDC failing to reconnect after about two minutes idle on C3/C6/C61/S3, latest master / IDF 5.5.4. | Reported SDK differs from our pinned Arduino 2.0.17 / IDF 4.4. Synthetic tests cover idle lease expiry and reply admission, not physical enumeration on that SDK. |
|
||||
@@ -239,3 +243,143 @@ radio service rather than real peripheral recovery.
|
||||
Native KISS tests also exercise the full modem's radio lifecycle during reset.
|
||||
These tests do not establish physical USB timing or host compatibility for
|
||||
boards that were not connected to the lab.
|
||||
|
||||
## Physical G2 HTTP OTA and USB transition (2026-10-05)
|
||||
|
||||
The latest OTA qualification used commit `95913c5301318fb738fb8f50e314a57a2dd9eb07`,
|
||||
including the uploader fix from `d2983762` and the station ownership fix.
|
||||
A current-source build explicitly selected TinyUSB; the target selected the
|
||||
normal HWCDC backend. Both ran on the physical Station G2 with the same existing
|
||||
partition table and two `0x640000` application slots. The independent audit
|
||||
checked packaged application hashes against metadata and matching preserved
|
||||
ELFs, the USB SDK transforms, and linked RAM requirements. Both ELFs contain
|
||||
the production 30-second admitted-upload timeout, queued-response guards and
|
||||
specific write-failure text; neither links the removed raw `Update.printError`
|
||||
calls. This is a controlled same-source transition, not released stock 1.17.1
|
||||
migration evidence.
|
||||
|
||||
| Artifact | App bytes | SHA-256 |
|
||||
| --- | ---: | --- |
|
||||
| TinyUSB observer, `95913c53` | 1,978,200 | `cf72b3ce872fb0887273022255fe5826070b5b40f5aa8057f50e90e7c92d4b72` |
|
||||
| Normal HWCDC observer, `95913c53` | 1,950,824 | `aeeadb1f165164c5b01d5855918e20bb0dc37bedcb9f0a8b88f52faa4c435486` |
|
||||
|
||||
The AP upload used the actual multipart `/update` handler and an app-only
|
||||
image. Its HTTP identity endpoint was matched to the node read over USB before
|
||||
the POST. USB topology was sampled every 20 ms without serial reads or writes
|
||||
across the upload/restart boundary. After 65,536 wire body bytes, Linux's
|
||||
`SIOCOUTQ` on that same HTTP socket fell from 59,987 outstanding bytes to zero
|
||||
in 0.554 seconds. Only then did the host pause body sends for 4.510 seconds;
|
||||
there were no serial operations during that pause. TCP acknowledgement was
|
||||
observed; the firmware's application receive timestamp was not directly
|
||||
instrumented.
|
||||
|
||||
| Measured gate | Result |
|
||||
| --- | --- |
|
||||
| App-only multipart upload with the intentional body pause | HTTP 200, 22.559 seconds |
|
||||
| Firmware-owned software restart and USB backend change | TinyUSB device 120 disappeared; a transient TinyUSB device 121 preceded hardware CDC device 122 on the same physical topology |
|
||||
| First plain website `time <epoch>` after HWCDC discovery | Clock-set acknowledgement in 2,997.319 ms; strict deadline 5,000 ms |
|
||||
| Extra post-restart settling, serial commands during upload, external recovery | None |
|
||||
| Identity and saved runtime settings | Preserved against the original preflight |
|
||||
| Admin access | Exactly the original and recovery Admin ACL entries remained |
|
||||
| Core diagnostics after the upgrade | Error flags 0, uptime 4 seconds |
|
||||
| Pi WiFi rollback | Original connection restored and temporary AP profile deleted; runner completed in 35.598 seconds |
|
||||
|
||||
The final `95913c53` hardware CDC application passed two quiet 180-second trials
|
||||
with power saving enabled. There were no serial reads, writes or keepalives
|
||||
during either interval. With the handle open, the first core reply took
|
||||
18.551 ms and uptime advanced from 43 to 223 seconds. With the handle closed,
|
||||
the first plain website clock request after reopening was acknowledged in
|
||||
14.728 ms and uptime advanced from 224 to 404 seconds. No CPU restart occurred.
|
||||
The preexisting radio CAD warning `0x02` remained unchanged throughout these
|
||||
trials; this was not a zero-error radio test. Original power saving off, other
|
||||
saved settings and both Admin ACL entries were restored and verified.
|
||||
|
||||
After those trials, a single plain `start ota` command used the connected
|
||||
station's advertised LAN address. The actual `/update` page returned HTTP 200
|
||||
in 1.365 seconds and `/update/identity` returned HTTP 200 in 0.084 seconds with
|
||||
the exact G2 identity. The command reported WiFi on and WebConfig stopped.
|
||||
Stopping OTA and restoring the original WebConfig were verified; no firmware
|
||||
was uploaded in this endpoint probe. Uptime continued from 533 to 535 seconds,
|
||||
the station remained connected at -80 dBm, and identity, original settings,
|
||||
both Admins and power saving off were retained. These HTTP measurements use a
|
||||
separate diagnostic bound; the first USB website request still uses 5 seconds.
|
||||
|
||||
Final restoration also verified the Pi's original WiFi connection, no temporary
|
||||
OTA profiles or return timers, and active `mctomqtt`, `ModemManager` and
|
||||
`mesh-logger` services. Each service reported exit status 0 and no restarts.
|
||||
This verifies service health; MQTT packet delivery was not measured in this run.
|
||||
|
||||
Baseline preparation also used app-only HTTP OTA: hardware CDC `d2983762`
|
||||
installed TinyUSB `95913c53` in 19.083 seconds, and its first plain clock
|
||||
acknowledgement took 3,163.722 ms. Original identity, settings and both Admins
|
||||
were verified before and after this reverse transition; no rescue action was
|
||||
used. Its Pi WiFi rollback completed in 31.958 seconds.
|
||||
|
||||
The first query used the stock website's plain clock command immediately after
|
||||
opening the discovered hardware CDC port. Later queries were tagged to keep
|
||||
unrelated diagnostics from satisfying a response. Neither a longer command
|
||||
deadline nor an arbitrary startup delay was added.
|
||||
|
||||
The uploader fix addresses a separate bounded-gap problem: the pinned HTTP
|
||||
listener gives ordinary clients a 3-second receive timeout, which remained in
|
||||
effect while an admitted multipart upload was receiving its body. OTA now
|
||||
extends only that admitted request to 30 seconds after MD5 validation. Normal,
|
||||
unauthorized, malformed-MD5 and concurrent requests retain ordinary admission
|
||||
behavior. `send()` queues a response before it reaches the wire, so both the
|
||||
upload and completion callbacks preserve an already queued error. Begin/end
|
||||
errors and short writes return HTTP errors without calling raw USB prints
|
||||
from the shared AsyncTCP task.
|
||||
|
||||
Three ASan/UBSan uploader tests passed, together with eight OTA startup tests
|
||||
and fifteen WiFi lifecycle tests. The uploader fixture executes production
|
||||
callbacks and the pinned AsyncTCP inactivity condition. A 4-second body pause
|
||||
survives, an abandoned owner remains open at 29.999 seconds and aborts at
|
||||
30 seconds, ownership is released without reboot, and a later upload completes.
|
||||
Negative controls fail when the timeout extension or queued-response guards
|
||||
are removed, or when raw USB error prints are restored.
|
||||
|
||||
Historical results remain distinct:
|
||||
|
||||
- The earlier same-source `d2983762` forward transition also passed its
|
||||
4.510-second upload pause: HTTP 200 in 23.211 seconds and the first website
|
||||
clock acknowledgement in 2,976.119 ms.
|
||||
- Earlier legacy-firmware WebConfig/WiFi handoff attempts failed before upload
|
||||
and required USB restoration; they did not establish an OTA transition.
|
||||
- An earlier controlled `e971beab` LAN attempt reset its upload socket after
|
||||
1,277,952 of 1,950,796 wire bytes, with weak LAN signal. USB stayed on TinyUSB,
|
||||
uptime continued, and an AP retry later passed. The cause of that LAN failure
|
||||
is unproven; neither a socket reset nor radio CAD error flag `0x02` establishes
|
||||
a CPU crash.
|
||||
- Same-backend setup attempt 1 installed the fixed TinyUSB application over
|
||||
HTTP, but the first product-matching USB rediscovery preceded the firmware's
|
||||
delayed restart. Its version gate correctly failed while the old application
|
||||
still answered. A later read-only version check confirmed `d2983762` without
|
||||
rescue, and the measured forward transition verified that source version
|
||||
before uploading. This setup report remains failed and is not counted as
|
||||
migration or startup-latency evidence.
|
||||
|
||||
The earlier `d2983762` hardware CDC application passed two quiet 180-second trials
|
||||
with power saving enabled. There were no serial reads, writes or keepalives
|
||||
during either interval. With the handle open, the first core reply took
|
||||
17.353 ms and uptime advanced 180 seconds. With the handle closed, the first
|
||||
plain website clock request after reopening was acknowledged in 8.905 ms and
|
||||
uptime advanced 181 seconds. Original power saving off, other saved settings
|
||||
and both Admin ACL entries were restored and verified.
|
||||
|
||||
A normal `start ota` probe while the station was disconnected correctly
|
||||
reported its fallback AP address; a Pi still on its original LAN could not
|
||||
reach that separate AP. This does not qualify the LAN endpoint. Source review
|
||||
then identified a missing WebConfig retry owner when MQTT is compiled in but
|
||||
has no running worker. The infrastructure fix refreshes ownership from actual
|
||||
MQTT worker state on the mesh loop. Constructor credential loading, browser
|
||||
credential writes and the 64-hex password capability use a separate immutable
|
||||
storage choice, so taking over reconnects cannot truncate or reroute saved
|
||||
credentials. An active external worker retains its connection; a stopped
|
||||
worker releases it for a fresh portal attempt. Six ASan/UBSan tests exercise
|
||||
production role startup, connection fallback, retry, worker handoff and
|
||||
credential paths, including the existing manual Companion startup behavior.
|
||||
The `95913c53` OTA transition, quiet power-saving trials and normal LAN endpoint
|
||||
checks passed as reported above. The current GitHub unit workflow has not yet
|
||||
completed. Release 1.17.1.9 remains held and unpublished. These results qualify
|
||||
this G2, Linux host and pinned framework; they do not establish physical
|
||||
compatibility for every affected board or host operating system.
|
||||
Reference in new issue
Block a user