mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-05-25 00:25:25 +00:00
BLE P2P stability: PSRAM zero-init, pool sizing, stuck-state recovery
Root cause: Bytes objects stored in PSRAM-allocated BLEInterface had corrupted shared_ptr members from uninitialized memory, causing crashes in processDiscoveredPeers(). Fixed by using heap_caps_calloc instead of heap_caps_malloc for PSRAM placement-new allocation. Additional fixes: - Reduce pool sizes to fit memory budget (reassembler 134KB→17KB, fragmenters 8→4, handshakes 32→4, pending data 64→8) - Store local MAC as BLEAddress struct instead of Bytes to avoid heap allocation in PSRAM-resident object - Move setLocalMac after platform start (NimBLE needs to be running for valid random address), add lazy MAC init fallback in loop() - Add stuck-state detector: resets GAP state machine if hardware is idle but state machine thinks it's busy - Enhance getLocalAddress with 3 fallback methods (NimBLE API, ble_hs_id_copy_addr RANDOM, esp_read_mac efuse) - Fix C++17 structured binding to C++11 compatibility - Increase BLE task stack 8KB→12KB for string ops in debug logs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -90,9 +90,6 @@ bool BLEInterface::start() {
|
||||
// Set identity data for peripheral mode
|
||||
_platform->setIdentityData(_local_identity);
|
||||
|
||||
// Set local MAC in peer manager
|
||||
_peer_manager.setLocalMac(_platform->getLocalAddress().toBytes());
|
||||
|
||||
// Start platform
|
||||
if (!_platform->start()) {
|
||||
ERROR("BLEInterface: Failed to start BLE platform");
|
||||
@@ -100,6 +97,14 @@ bool BLEInterface::start() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set local MAC in peer manager (must be after start() when NimBLE has a valid address)
|
||||
auto local_addr = _platform->getLocalAddress();
|
||||
auto local_mac_bytes = local_addr.toBytes();
|
||||
INFO("BLEInterface: Local address from platform: " + local_addr.toString() +
|
||||
" bytes_size=" + std::to_string(local_mac_bytes.size()) +
|
||||
" isZero=" + std::to_string(local_addr.isZero()));
|
||||
_peer_manager.setLocalMac(local_mac_bytes);
|
||||
|
||||
_online = true;
|
||||
_last_scan = 0; // Trigger immediate scan
|
||||
_last_keepalive = Utilities::OS::time();
|
||||
@@ -131,8 +136,19 @@ void BLEInterface::stop() {
|
||||
|
||||
void BLEInterface::loop() {
|
||||
static double last_loop_log = 0;
|
||||
static bool local_mac_set = false;
|
||||
double now = Utilities::OS::time();
|
||||
|
||||
// Lazy init: set local MAC once NimBLE has a valid random address
|
||||
if (!local_mac_set && _platform) {
|
||||
auto addr = _platform->getLocalAddress();
|
||||
if (!addr.isZero()) {
|
||||
_peer_manager.setLocalMac(addr.toBytes());
|
||||
local_mac_set = true;
|
||||
INFO("BLEInterface: Local MAC resolved: " + addr.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Process any pending handshakes (deferred from callback for stack safety)
|
||||
if (_pending_handshake_count > 0) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
@@ -827,7 +843,7 @@ void BLEInterface::processDiscoveredPeers() {
|
||||
if (now - last_peer_log >= 10.0) {
|
||||
auto all_peers = _peer_manager.getAllPeers();
|
||||
DEBUG("BLEInterface: Peer count=" + std::to_string(all_peers.size()) +
|
||||
" localMAC=" + _peer_manager.getLocalMac().toHex());
|
||||
" localMAC=" + _peer_manager.getLocalMac().toString());
|
||||
for (PeerInfo* peer : all_peers) {
|
||||
bool should_initiate = _peer_manager.shouldInitiateConnection(peer->mac_address);
|
||||
DEBUG("BLEInterface: Peer " + BLEAddress(peer->mac_address.data()).toString() +
|
||||
@@ -1026,7 +1042,7 @@ bool BLEInterface::start_task(int priority, int core) {
|
||||
BaseType_t result = xTaskCreatePinnedToCore(
|
||||
ble_task,
|
||||
"ble",
|
||||
8192, // 8KB stack
|
||||
12288, // 12KB stack (string ops in debug logs need headroom)
|
||||
this,
|
||||
priority,
|
||||
&_task_handle,
|
||||
|
||||
Reference in New Issue
Block a user