Classic ESP32 links into a dram0_0_seg of only 124,580 bytes: memory.ld
carves the BT controller's 0xdb5c (56,156) reservation off the 0x2c200
window before the application gets any. Three large objects dominated what
was left, and Tbeam_SX1262_repeater_observer_mqtt overran the build's 8 KiB
static reserve by 4,744 bytes.
Heap-allocate them instead, each with a defined behaviour when the
allocation fails:
- OtaContext: generalize the Companion's borrowed-storage path behind
OTA_DYNAMIC_CONTEXT and add OTA_HEAP_CONTEXT, which allocates the context
on first use and frees it once no transfer, apply or folder link needs it.
A repeater is idle nearly all the time, so the workspace is usually absent.
Exhaustion is reported to the caller and the operation declines.
- ClientACL: the client table becomes a pointer with a live capacity;
capacity 0 refuses new clients rather than writing through a null table.
- MyMesh flood packet filters: likewise, with flood_packet_filter_slots as
the live bound for every rule loop. At capacity 0 the node forwards
unfiltered, and both save paths refuse to write so a stored ruleset is
never replaced by an empty file.
Also override the Arduino SDK's weak btInUse() in simple_repeater so
initArduino() releases the BT controller memory to the heap. That grows the
runtime heap these tables now come from; it cannot recover the same
reservation from the linker's static window.
Static DRAM, classic ESP32:
Heltec_v2_repeater 108,332 -> 70,732
Tbeam_SX1262_repeater_observer_mqtt 121,132 -> 83,532 (was failing)
Reserve board-specific GPIOs, make ESP-NOW channel/format handling configurable, and coordinate WiFi, BLE, NTP, MQTT, and host actions safely.
Add the Indicator message page, exclusive transport selector, dynamic 480/320 rendering, larger transport typography, pairing cleanup, and corresponding tests and documentation.
Add durable TempRadio, ACL, clock, bridge, GPS/I2C, USB logging, and Indicator recovery safeguards together with expanded automation, build/profile contracts, release metadata, and the hardware validation ledger.
Add selectable shared ESP-NOW channels, raw/wrapped bridge compatibility, and bounded fragmentation for maximum-size packets.\n\nGive ESP32 Full profiles WiFi coexistence, stabilize WebConfig and USB terminal lifecycles, and keep disabled bridges stopped during observer updates.\n\nUpdate generated UI, firmware selection, documentation, and regression coverage.
Add the framed BLE mOTA transport and companion control path, complete the full-profile build and runtime fixes, and document and test the OTA workflow.
Expose the Full Companion terminal over TCP and add an authenticated, replay-resistant host command service with documented CPU temperature, reboot, and allowlisted program examples.\n\nImprove LoRa OTA diagnostics and persistent CLI handling, reduce clock correction drift to ten minutes, and make mOTA stream flush behavior an explicit transport policy with regression coverage.
Picks up upstream MeshCore 1.17.1.
Notable upstream content:
- 1.17.1 version/build-date bump in the example MyMesh headers.
- nRF52: combine radio entropy with CC310 RNG.
- Companion FEM prefs: load/save of fem_ properties commented out until they
can be set from the client.
- Scoped reply routing: replies no longer dropped when flood.max.unscoped is
low (RoutingPolicy + unit tests).
- nRF52 unused-pin sweep (T1, T-Echo Lite, MeshPocket).
No conflicts.
Brings in the external FEM gain preferences (fem_txgain, PR #3137 plus the
companion-side port), the AGC reset rxgain fix, the LR2021 preamble/IRQ
timeout logic, and assorted variant fixes (T096, T-Echo Card TCXO, promicro
pinmap, minewsemi, R1 Neo).
Conflict resolutions:
- SH1106Display: both sides fixed T-Beam Supreme startup independently. Kept
our _initialized guard and DISPLAY_ADDRESS_ALT override, took upstream's
SA0-pair fallback and its unconditional display.begin() so the frame buffer
is allocated even when no panel answers.
- MyMesh/SensorMesh/CommonCLI: took upstream's fem_txgain default and wiring,
kept our comments and the observer-side prefs layout.
Also fixes CustomLLCC68Wrapper, which upstream missed when sx126xResetAGC
gained its rx_boost_gain parameter. No variant builds that wrapper today, so
neither tree failed to compile.