Merge remote-tracking branch 'origin/keymindCascade' into keymindCascade

This commit is contained in:
mikecarper committed 2026-10-27 14:11:07 -07:00
commit eab29a12cd
15 files changed
+2067 -166

No files matched your search

+2 -2
View File
@@ -67,7 +67,7 @@
#include "esp_transport.h"
#include "esp_transport_ws.h"
#if defined(STATION_G3_ESP32) && defined(BOARD_HAS_PSRAM)
#if defined(BOARD_HAS_PSRAM)
#include "esp_heap_caps.h"
#include "MQTTConnectionAdmission.h"
#endif
@@ -109,7 +109,7 @@ esp_transport_handle_t __wrap_esp_transport_ws_init(esp_transport_handle_t paren
// The buffer is untouched at this point (allocated moments ago inside
// __real_esp_transport_ws_init), so a swap is safe.
const size_t bytes = CONFIG_WS_BUFFER_SIZE + 1;
#if defined(STATION_G3_ESP32) && defined(BOARD_HAS_PSRAM)
#if defined(BOARD_HAS_PSRAM)
// Upgrade request/response text is CPU-only. Retain this padded buffer
// until the SDK destroys the transport; its ordinary free accepts PSRAM.
char* padded = (char*)heap_caps_malloc(bytes, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
+11 -4
View File
@@ -91,8 +91,8 @@ protected:
#else
FloodAdvertLimiter(Entry* entries, size_t capacity) : _entries(entries), _capacity(capacity) {}
#if MESH_REPEATER_PSRAM_TABLES
// The derived storage owner is initialized after this base. Bind its full
// table before reset() or any limiter operation can inspect the entries.
// Bind the complete table from begin(), after Arduino initializes PSRAM,
// before reset() or any limiter operation can inspect the entries.
void bindStorage(Entry* entries) {
if (!entries || reinterpret_cast<uintptr_t>(entries) % alignof(Entry)) abort();
_entries = entries;
@@ -211,18 +211,25 @@ public:
struct Storage { Entry entries[Capacity]; };
RepeaterPsramStorage<Storage> _storage;
public:
StaticFloodAdvertLimiter() : FloodAdvertLimiter(nullptr, Capacity) {
StaticFloodAdvertLimiter() : FloodAdvertLimiter(nullptr, Capacity) {}
bool begin() {
if (_storage.data()) return true;
// Exhaustion must stop startup rather than disabling advert protection
// or reducing its source/hash history. No full internal array is retained.
if (!_storage.begin("advert source history")) abort();
if (!_storage.begin("advert source history")) return false;
bindStorage(_storage.data()->entries);
reset();
return true;
}
#else
Entry _storage[Capacity];
public:
StaticFloodAdvertLimiter() : FloodAdvertLimiter(_storage, Capacity) { reset(); }
#endif
#if !MESH_REPEATER_PSRAM_TABLES || FLOOD_ADVERT_IRAM_WORD_STORAGE \
|| FLOOD_ADVERT_RTC_FAST_SLOTS || FLOOD_ADVERT_RTC_SLOW_SLOTS
bool begin() { return true; }
#endif
};
} // namespace mesh
+20 -9
View File
@@ -1,7 +1,12 @@
#pragma once
#if defined(ESP32_PLATFORM) && defined(BOARD_HAS_PSRAM)
#include <sdkconfig.h>
#endif
#ifndef MESH_REPEATER_PSRAM_TABLES
#if defined(STATION_G3_ESP32) && defined(ESP32_PLATFORM) && defined(BOARD_HAS_PSRAM) \
#if defined(ESP32_PLATFORM) && defined(BOARD_HAS_PSRAM) \
&& defined(CONFIG_IDF_TARGET_ESP32S3) && CONFIG_IDF_TARGET_ESP32S3 \
&& defined(MESH_CLIENT_REPEATER_ONLY) && MESH_CLIENT_REPEATER_ONLY
#define MESH_REPEATER_PSRAM_TABLES 1
#else
@@ -17,12 +22,14 @@
#if !defined(ESP32_PLATFORM) || !defined(BOARD_HAS_PSRAM)
#error "Repeater PSRAM tables require an ESP32 target with PSRAM support"
#endif
#if !defined(MESH_CLIENT_REPEATER_ONLY) || !MESH_CLIENT_REPEATER_ONLY
#error "Repeater PSRAM tables require the repeater startup path"
#endif
#include <sdkconfig.h>
#if !defined(CONFIG_IDF_TARGET_ESP32S3) || !CONFIG_IDF_TARGET_ESP32S3 \
|| !defined(CONFIG_SPIRAM_BOOT_INIT) || !CONFIG_SPIRAM_BOOT_INIT \
|| !defined(CONFIG_SPIRAM_USE_MALLOC) || !CONFIG_SPIRAM_USE_MALLOC
#error "Repeater PSRAM tables require ESP32-S3 with boot-initialized PSRAM heaps"
#error "Repeater PSRAM tables require ESP32-S3 with PSRAM heaps"
#endif
#include <esp_heap_caps.h>
@@ -34,8 +41,8 @@
namespace mesh {
// Own only CPU data here. ISR state, locks, task stacks and DMA buffers retain
// their existing internal storage. G3's pinned SDK initializes PSRAM-backed
// heaps before global constructors, so tables can keep their startup lifetime.
// their existing internal storage. Allocate from begin(), after initArduino()
// initializes both QSPI and OPI PSRAM. Global constructors own only a pointer.
template<typename T> class RepeaterPsramStorage {
static_assert(std::is_trivial<T>::value,
"Repeater PSRAM tables require zero-initialized trivial data");
@@ -67,10 +74,14 @@ public:
T* data() { return value_; }
const T* data() const { return value_; }
T& require(const char* label) {
// Used only while binding the owner's references during construction.
// Allocation never moves after pointers escape to routing or persistence.
if (!begin(label)) abort();
T& require() {
// Never allocate through a getter: initialization must precede routing
// and persistence, and allocation never moves after pointers escape.
if (!value_) abort();
return *value_;
}
const T& require() const {
if (!value_) abort();
return *value_;
}
};