Fix V4-R8 crash on Wi-Fi association with BLE on; widen companion ATT MTU
Wi-Fi power save: remove the preference, always use DTIM modem sleep.
An R8 with saved credentials and Bluetooth enabled aborted every time Wi-Fi
associated. Coredump: crashing task "wifi", abort() inside pm_set_sleep_type,
with nimble_host and btController both live.
WIFI_PS_NONE is not a legal sleep mode while the BT controller is running --
modem sleep is precisely what yields airtime to BLE -- and the Wi-Fi PM blob
aborts rather than refusing. 844d8c3 made power save a preference defaulting
OFF on the V4-R8, which is why only that board crashed; the comment above the
apply site already stated the invariant it broke ("gives BLE coexistence
airtime").
The latency it was buying does not exist either. Profiling the companion link
on hardware: an app sync is ~40 CMD_GET_CHANNEL round trips (the device reports
MAX_GROUP_CHANNELS=40 and the app reads every slot individually), 165ms each,
with this firmware accounting for 28ms of 8264ms -- 0.3%. Sync cost is
round-trip COUNT, not link latency, so there was nothing to trade away.
Guarding the setting was considered and rejected: it would have to be silently
inert whenever Bluetooth is on, which is a confusing thing to leave in a
Settings screen. Removed instead -- toggle, prefs accessors and R8 default.
The stored wifi_ps NVS key is simply never read again; no migration needed.
Companion BLE: ATT MTU MAX_FRAME_SIZE -> MAX_FRAME_SIZE + 3.
A notification payload is ATT_MTU-3, so SerialBLEInterface::begin()'s
setMTU(MAX_FRAME_SIZE) left a full-length frame 3 bytes too big and NimBLE
silently dropped the overflow (ble_att_truncate_to_mtu). MyMesh::queueMessage()
clamps message text to exactly MAX_FRAME_SIZE, so maximum-length messages lost
their last 3 bytes -- over BLE only; USB/TCP/WS were unaffected. Applied from
the vendored transport rather than the core: setMTU() is a public static, so
MeshCore needs no change. Verified on an M9, which now negotiates 179.
All 8 environments build. R8 flashed and confirmed to be the booting slot
(otadata seq 1 -> ota_0); its boot log is not observable over USB because
opening the port drops that board into ROM download mode.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
844d8c3357
commit
7060a38dba
5 files changed
+21
-58
No files matched your search
+11
-6
@@ -1691,14 +1691,19 @@ void loop() {
|
||||
// BLE coexistence airtime). Deferred to here on purpose: enabling it on the
|
||||
// unassociated STA naps the radio through a scan dwell and breaks the setup
|
||||
// wizard's WiFi.scanNetworks() ("no networks found"). One-shot.
|
||||
// Persisted preference (Wi-Fi settings -> "Power save"): default ON, except the V4-R8
|
||||
// where it defaults OFF (perf pass 2026-08-20 — lower-latency app link, steadier
|
||||
// association on its weak 2.4 GHz path). The toggle also applies live once associated.
|
||||
//
|
||||
// Unconditional, and deliberately NOT a user preference. This was briefly
|
||||
// configurable (default off on the V4-R8, for a lower-latency app link), but
|
||||
// WIFI_PS_NONE is not a legal sleep mode while the BT controller is running --
|
||||
// modem sleep is exactly what yields airtime to BLE, and the Wi-Fi PM blob
|
||||
// aborts rather than refusing. An R8 with saved credentials and Bluetooth on
|
||||
// crashed on association every time: task "wifi", abort() in pm_set_sleep_type.
|
||||
// The latency it was buying did not exist either: profiling the companion link
|
||||
// showed sync cost is round-trip COUNT (~40 CMD_GET_CHANNEL), with the firmware
|
||||
// accounting for 0.3% of it. So there is nothing to trade away here.
|
||||
static bool modem_sleep_set = false;
|
||||
if (!modem_sleep_set) {
|
||||
const bool ps = wifiConfigGetPowerSave();
|
||||
WiFi.setSleep(ps);
|
||||
Serial.printf("[wifi] modem power save %s\n", ps ? "on" : "off");
|
||||
WiFi.setSleep(true);
|
||||
modem_sleep_set = true;
|
||||
}
|
||||
if (!sntp_kicked) {
|
||||
|
||||
Reference in new issue
Block a user