fix(firmware): make STACKCHAN.RON writeback work via short-name overwrite#579
Conversation
…rite The config writeback was as broken as the read path: STAGING_FILE "STACKCHAN.NEW" (9-char base) couldn't be created by embedded-sdmmc, and the final copy targeted the un-creatable "STACKCHAN.RON". embedded-sdmmc cannot create long-named files at all, but it CAN overwrite an existing one opened by its short name. Stage to an 8.3 name (STKCFG.NEW), resolve the existing STACKCHAN.RON short name via the shared LFN helper, and truncate-write the rendered config onto it — which preserves the long-name directory entry, so it stays readable as STACKCHAN.RON.
🤖 I have created a release *beep* *boop* --- <details><summary>stackchan-firmware: 0.113.4</summary> ## [0.113.4](stackchan-firmware-v0.113.3...stackchan-firmware-v0.113.4) (2026-05-29) ### Bug Fixes * **firmware:** make STACKCHAN.RON writeback work via short-name overwrite ([#579](#579)) ([ec7b458](ec7b458)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: release-kun[bot] <276042328+release-kun[bot]@users.noreply.github.com>
Greptile SummaryThis PR completes the SD config writeback feature by fixing the root cause that broke
Confidence Score: 4/5Safe to merge — the core logic is well-reasoned and on-device tested; only two stale doc-comment references to the old staging filename remain. The writeback mechanism is sound: staging to an 8.3-creatable name, resolving the LFN short name, and truncate-writing in place correctly preserves the long-name directory entry. The lfn_short_name refactor is clean. The only issues found are two doc comments that still name STACKCHAN.NEW. No files require special attention beyond the two stale doc comments in storage.rs. Important Files Changed
|
… pool sizing (#581) ## Summary Once a real `STACKCHAN.RON` loaded (after #575/#577), Wi-Fi never came up — `start_async` failed with `InternalError(NoMem)`. This fixes the bring-up end to end. **Root cause (measured on-device):** only **~1.5 KiB** of internal SRAM was free when the Wi-Fi MAC started. PSRAM (8 MiB free) can't back Wi-Fi DMA buffers; the bootloader-reclaimed heap is hard-capped at **~72 KiB** (already full); and the only other internal heap shares the DRAM segment with the **stack** (growing it overflowed the stack in the BLE+Wi-Fi coex path). **Fix 1 — BLE/Wi-Fi mutual exclusion.** With a Wi-Fi SSID configured, skip BLE bring-up entirely. Frees **~36 KiB** internal (1.5 KiB → 37 KiB) for the Wi-Fi stack and removes coex stack pressure. BLE (Hardware Buddy) still runs when no SSID is set, so provisioning over BLE is unaffected. **Fix 2 — socket pool.** Wi-Fi connecting then exposed a second latent bug: `STACK_SOCKETS` was 6, predating the 4-worker HTTP pool, so `smoltcp` panicked (`adding a socket to a full SocketSet`) the instant the link came up. Sized to real demand (`HTTP_WORKER_COUNT` + mDNS + SNTP + DHCP/DNS + optional outbound clients). Also reflows one `write_config` line that merged slightly un-formatted in #579. ## Test plan - `just clippy-firmware` (`-D warnings`) — clean. - **On-device (CoreS3, `STACKCHAN.RON` with `ssid=Interweb`):** flashed `--release`; defmt log shows: - `ble: skipped — Wi-Fi SSID configured` and free internal **37 KiB** before start (was 1.5 KiB). - `wifi: connecting → wifi: connected`, HTTP workers listening, **DHCP lease acquired**, and `sntp: synced via pool.ntp.org` — i.e. full internet reachability. - **Boots once, no reboot loop;** zero `NoMem`, stack-guard, or `SocketSet` panics (all three were reproduced before the fix). ## Follow-ups (noted, out of scope) - `coex` feature is now dead weight when an SSID is set (BLE never co-runs); dropping it would reclaim more internal RAM and could be revisited. - `sidecar session: persist failed (Write)` (separate file) and the BLE-only path's behavior are unchanged here. Greptile: please review.
Summary
Completes the SD config feature: it could mount (#575) and read (#577) but not save.
PUT /settingswriteback was broken the same way the read path was — the staging fileSTACKCHAN.NEW(9-char base) couldn't be created by embedded-sdmmc, and the final copy targeted the un-creatableSTACKCHAN.RON.embedded-sdmmc cannot create long-named files at all, but it can overwrite an existing file opened by its short name. So:
STKCFG.NEW) the firmware can create.STACKCHAN.RONshort name via the sharedlfn_short_namehelper (factored out of the read path).STACKCHAN.RONnext boot.Writeback updates an existing config (the realistic lifecycle — the file must already be present for Wi-Fi/auth to come up). If
STACKCHAN.RONis absent,write_configreturnsFileNotFoundwith a clear log rather than silently writing a differently-named file.Test plan
just clippy-firmware(-D warnings) — clean.STACKCHAN.RONon the card): a temporary idempotent self-test (rewrite the just-read config, then re-read) — removed before commit — logged:dbg writeback: write_config OKdbg writeback: re-read OK ssid=Interweb hostname=stackchan— round-trip intact, long name preserved.Surfaced by config now loading (separate, not addressed here)
sidecar session: persist failed (Write)— a different persisted file; needs its own look.wifi: start_async failed (InternalError(NoMem))— Wi-Fi now actually starts (there's an SSID); a pre-existing init path that was never exercised while config never loaded.Greptile: please review.