Merge PR #7 with reviewed ExpressLRS power and memory fixes

Integrate ExpressLRS TX module support and its stacked ESP32 heap changes.
Use the approved Linkflow calibration (17-30 dBm), preserve the PA drive
and output path after radio recovery, and keep LoRa OTA enabled.

Preserve stored ACLs and filters on allocation failure, release owned
client/filter buffers, service heap OTA contexts on Companions, release
self-serving workspaces after TempRadio, and reset staged-resume state
when a context is released. Keep manual staging and active operations
alive. Account for all moved allocations in the runtime RAM gate.

Validation: 1,393 native cases; radio-power, heap-context, ACL persistence,
shared-queue transfer, display/inbox, radio receive, and memory regressions.
Firmware builds passed for Linkflow, Heltec V2 Companion, T-Beam MQTT
repeater, Heltec V4 R8 MQTT repeater, RAK4631 repeater, and Indicator Full.
Physical verification awaits access to the currently offline lab Pi.
This commit is contained in:
mikecarper
2026-09-10 22:06:16 -07:00
26 changed files with 1072 additions and 74 deletions
+4 -3
View File
@@ -160,14 +160,15 @@ static void listing_does_not_mutate_acl() {
mesh::LocalIdentity self;
acl.load(&fs, self);
for (unsigned i = 0; i < 5; ++i) add(acl, i, uint8_t(i));
const auto before = acl;
std::vector<ClientInfo> before;
for (int i = 0; i < acl.getNumClients(); ++i) before.push_back(*acl.getClientByIdx(i));
const auto writes = fs.bytes_written;
for (const char* command : {"get acl", "get acl 2", "get acl 3", "get acl 0"}) {
query(acl, command);
}
CHECK(acl.getNumClients() == before.getNumClients());
CHECK(acl.getNumClients() == int(before.size()));
for (int i = 0; i < acl.getNumClients(); ++i) {
CHECK(memcmp(acl.getClientByIdx(i), before.getClientByIdx(i), sizeof(ClientInfo)) == 0);
CHECK(memcmp(acl.getClientByIdx(i), &before[i], sizeof(ClientInfo)) == 0);
}
CHECK(fs.bytes_written == writes);
}