Cache verified nRF52 metadata for OTA status displays

This commit is contained in:
mikecarper committed 2026-10-04 17:34:16 -07:00
1 parent 0e25a1f15e
commit fed810ff50
6 files changed
+468 -5

No files matched your search

+2 -2
View File
@@ -223,7 +223,7 @@ bool handle_ota_command(const char* command, char* reply, mesh::MainBoard& board
c.folder_active ? c.folder_dest_info : "not connected",
(unsigned)c.manager.servedCount(), dighx);
#else
SelfFwInfo fi; bool s = ota_self_firmware(fi);
SelfFwInfo fi; bool s = ota_self_firmware_for_display(fi);
char selfhx[9]; if (s && fi.valid) mesh::Utils::toHex(selfhx, fi.body_hash, 4); else strcpy(selfhx, "?");
OtaManager::FetchState fs = c.manager.fetchState();
char dl[80];
@@ -303,7 +303,7 @@ bool handle_ota_command(const char* command, char* reply, mesh::MainBoard& board
const OtaManager::ServeEntry* e = c.manager.servedEntry(i);
if (e && e->is_self) { self = e; break; }
}
SelfFwInfo fi; bool sok = ota_self_firmware(fi);
SelfFwInfo fi; bool sok = ota_self_firmware_for_display(fi);
char midhx[9], bodyhx[9], verbuf[20], dighx[9];
if (self) mesh::Utils::toHex(midhx, self->mid, 4); else strcpy(midhx, "?");
if (sok && fi.valid) mesh::Utils::toHex(bodyhx, fi.body_hash, 4); else strcpy(bodyhx, "?");
+43
View File
@@ -106,6 +106,49 @@ bool ota_self_firmware(SelfFwInfo& out) {
}
#endif
bool ota_self_firmware_for_display(SelfFwInfo& out) {
#if defined(NRF52_PLATFORM)
struct DisplayCache {
bool valid = false;
uint32_t app_base = 0;
uint32_t stage_ceiling = 0;
SelfFwInfo info;
};
static DisplayCache cache;
out = SelfFwInfo();
const uint32_t app_base = mota_nrf52_app_base();
const uint32_t stage_ceiling =
#if defined(OTA_SD_STORE)
MOTA_NRF52_APP_END;
#else
mota_nrf52_layout_stage_ceiling();
#endif
if (!mota_nrf52_layout_valid(app_base, stage_ceiling)) {
cache.valid = false;
return false;
}
if (cache.valid && cache.app_base == app_base && cache.stage_ceiling == stage_ceiling) {
out = cache.info;
return true;
}
// App updates reboot, so only diagnostic metadata needs a per-boot snapshot. Keep all explicit
// verification and apply/base/headroom checks on the fresh accessor: a display hit proves nothing
// about later flash mutations. Never cache failure or retain metadata from a different layout.
cache.valid = false;
if (!ota_self_firmware(out) || !out.valid) {
out = SelfFwInfo();
return false;
}
cache.app_base = app_base;
cache.stage_ceiling = stage_ceiling;
cache.info = out;
cache.valid = true;
return true;
#else
return ota_self_firmware(out);
#endif
}
#if defined(ESP32_PLATFORM)
bool ota_self_read(uint32_t off, uint8_t* buf, uint32_t len) {
const esp_partition_t* p = esp_ota_get_running_partition();
+5
View File
@@ -15,6 +15,11 @@ namespace ota {
// missing partitions, changed geometry and read failures are never cached. OTA writes inactive flash.
bool ota_self_firmware(SelfFwInfo& out);
// Display-only snapshot for status/stats polling. nRF52 caches successful, body-verified metadata
// for this boot while the app base and staging ceiling match; invalid geometry or failed scans are
// never cached. Use ota_self_firmware(), not this accessor, for explicit verification or OTA safety.
bool ota_self_firmware_for_display(SelfFwInfo& out);
// Read `len` bytes of the running firmware image at offset `off` (ESP32: running partition via
// esp_partition_read; nRF52: memory-mapped app region). false on unsupported platforms.
bool ota_self_read(uint32_t off, uint8_t* buf, uint32_t len);