fix(firmware): upgrade NimBLE to 2.x + DNS fallback for unreliable resolvers

NimBLE-Arduino 1.4.2 had an init/fire race in its FreeRTOS callout porting
layer where os_callout_timer_cb dispatched a queued TimerHandle expiry
against a not-yet-initialized event (NULL fn pointer), causing PC=0
InstrFetchProhibited within ~1s of boot when the camera task starved the
timer service. Confirmed by ets_printf instrumentation. Upgrading to
^2.0.0 rewrites the porting layer and eliminates the race; verified clean
on the customer network for 1+ hour.

Also rolls in DNS-resilience work that surfaced the BLE crash during
provisioning: pin lwIP/esp-netif resolvers to 1.1.1.1/8.8.8.8 across DHCP
renewals, add three-tier resolver fallback in reporter with a hardcoded
IP of last resort, and switch to raw WiFiClient with manual Host header
to bypass HTTPClient's brittle DNS path.

Migration touches for NimBLE 2.x:
- NimBLEAdvertisedDeviceCallbacks -> NimBLEScanCallbacks
- onResult signature now takes const NimBLEAdvertisedDevice*
- setAdvertisedDeviceCallbacks -> setScanCallbacks
- start(0, nullptr, false) -> start(0, false, false)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 11:34:17 -07:00
parent 461ed7d888
commit a585a56cff
9 changed files with 1434 additions and 31 deletions

View File

@@ -11,8 +11,13 @@ struct CameraHourlyRecord {
int exits;
};
static const int REPORTER_MAX_BUFFER = 24;
static const char* REPORTER_API_HOST = "http://logs.research.bike";
static const int REPORTER_MAX_BUFFER = 24;
static const char* REPORTER_API_HOST_NAME = "logs.research.bike";
static const uint16_t REPORTER_API_PORT = 80;
// Hardcoded fallback used when DNS fails (some customer networks intercept
// :53 with a transparent proxy that mangles responses). Update if the
// server's IP changes — but a successful hostByName() always wins over this.
static const char* REPORTER_API_FALLBACK_IP = "5.78.114.131";
void reporter_init();
void reporter_submit_camera(const DeviceConfig& cfg, const CameraHourlyRecord& rec);