fix: ArduinoOTA init, reporter mutex, BLE lock scope, NVS type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 10:33:23 -07:00
parent 883b72be77
commit 8a00665e4c
5 changed files with 83 additions and 30 deletions

View File

@@ -5,11 +5,12 @@
#include <NimBLEAdvertisedDevice.h>
#include "mbedtls/md.h"
#include <map>
#include <mutex>
#define RSSI_NEAR -65
#define RSSI_MID -80
static portMUX_TYPE s_mux = portMUX_INITIALIZER_UNLOCKED;
static std::mutex s_mutex;
struct DeviceObs {
int rssi_sum;
@@ -47,7 +48,7 @@ class ScanCallback : public NimBLEAdvertisedDeviceCallbacks {
String hash = sha256_prefix(mac);
int rssi = dev->getRSSI();
portENTER_CRITICAL(&s_mux);
std::lock_guard<std::mutex> lock(s_mutex);
auto it = s_seen.find(hash);
if (it == s_seen.end()) {
s_seen[hash] = {rssi, 1};
@@ -57,7 +58,6 @@ class ScanCallback : public NimBLEAdvertisedDeviceCallbacks {
}
int concurrent = (int)s_seen.size();
if (concurrent > s_max_concurrent) s_max_concurrent = concurrent;
portEXIT_CRITICAL(&s_mux);
}
};
@@ -79,26 +79,30 @@ void ble_scanner_pause() { if (s_scan) s_scan->stop(); }
void ble_scanner_resume() { if (s_scan) s_scan->start(0, nullptr, false); }
BLEHourlyRecord ble_scanner_collect(uint32_t period_start, uint32_t period_end) {
portENTER_CRITICAL(&s_mux);
BLEHourlyRecord rec;
rec.period_start = period_start;
rec.period_end = period_end;
rec.unique_devices = (int)s_seen.size();
rec.max_concurrent = s_max_concurrent;
rec.near_count = 0; rec.mid_count = 0; rec.far_count = 0;
for (auto& kv : s_seen) {
float avg = kv.second.rssi_sum / (float)kv.second.count;
if (avg > RSSI_NEAR) rec.near_count++;
else if (avg > RSSI_MID) rec.mid_count++;
else rec.far_count++;
rec.device_hashes.push_back(kv.first);
// Swap accumulators under lock — minimise time with lock held
std::map<String, DeviceObs> local_seen;
int local_max = 0;
{
std::lock_guard<std::mutex> lock(s_mutex);
std::swap(local_seen, s_seen);
local_max = s_max_concurrent;
s_max_concurrent = 0;
}
s_seen.clear();
s_max_concurrent = 0;
// Process outside the lock — heap allocation safe here
BLEHourlyRecord rec;
rec.period_start = period_start;
rec.period_end = period_end;
rec.unique_devices = (int)local_seen.size();
rec.max_concurrent = local_max;
rec.near_count = 0; rec.mid_count = 0; rec.far_count = 0;
portEXIT_CRITICAL(&s_mux);
for (auto& kv : local_seen) {
float avg_rssi = kv.second.rssi_sum / (float)kv.second.count;
if (avg_rssi > RSSI_NEAR) rec.near_count++;
else if (avg_rssi > RSSI_MID) rec.mid_count++;
else rec.far_count++;
rec.device_hashes.push_back(kv.first);
}
return rec;
}