Skip to content

fix(wifi): stop STA scan churn from breaking SoftAP DHCP during setup - #40

Merged
bring42 merged 1 commit into
mainfrom
claude/ap-connection-c3-issues-955c8b
Jul 27, 2026
Merged

fix(wifi): stop STA scan churn from breaking SoftAP DHCP during setup#40
bring42 merged 1 commit into
mainfrom
claude/ap-connection-c3-issues-955c8b

Conversation

@bring42

@bring42 bring42 commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Problem

Connecting to the LUME-Setup AP for provisioning was flaky on the C3: clients got a 169.254.x.x link-local address instead of a DHCP lease, couldn't reach 192.168.4.1, and appeared to "jump between addresses."

Root cause (confirmed on hardware)

The device had a saved station network (Untz) that was unreachable from where it sat. Every WIFI_RETRY_INTERVAL_MS it called WiFi.begin(), whose full-band scan channel-hops the single C3 radio off the SoftAP's channel. When a scan lands during a client's DHCP handshake, the lease never completes → link-local fallback → "jumping addresses." The IDF's own auto-reconnect was scanning behind our back as well, so the prior "back off to 120s while a client is on the AP" mitigation wasn't enough.

Confirmed via serial: a lone Attempting WiFi reconnection... every ~30s with no successful Connected!, i.e. continuous scan churn against an out-of-range network.

Fix

  • Own STA reconnection: setAutoReconnect(false) + persistent(false) so the IDF stops scanning / auto-connecting a stale SSID on its own.
  • Skip reconnect entirely while a client is on the SoftAP (softAPgetStationNum() == 0 gate) instead of just lengthening the interval — an active setup session is never interrupted by a scan. Retries resume once the client leaves, so an idle client can't wedge the device offline and the link still self-heals when a reachable network appears.
  • Drop the now-unused WIFI_RETRY_INTERVAL_AP_BUSY_MS constant.

Verification (XIAO ESP32-C3, saved SSID unreachable)

  • Clean boot on new firmware; AP IP: 192.168.4.1.
  • Phone connects to LUME-Setup → gets a proper 192.168.4.x lease (no more 169.254).
  • http://192.168.4.1 loads the webapp.
  • 0 reconnection attempts fire across a 40s window while a client is parked on the AP.

🤖 Generated with Claude Code

A saved-but-unreachable station network made the SoftAP unusable for
provisioning: every WIFI_RETRY_INTERVAL_MS the device ran WiFi.begin(),
whose full-band scan channel-hops the single C3 radio off the SoftAP's
channel. When that scan lands during a client's DHCP handshake the lease
never completes — the client falls back to a 169.254 link-local address,
can't reach 192.168.4.1, and appears to "jump between addresses" as it
re-associates and re-tries. The IDF's own auto-reconnect scanned behind
our back too, so the previous "back off to 120s while a client is on the
AP" mitigation wasn't enough.

- Take ownership of STA reconnection: setAutoReconnect(false) +
  persistent(false) so the IDF stops scanning/auto-connecting on its own.
- handleWifiMaintenance() now SKIPS the reconnect entirely while a client
  is parked on the SoftAP (station count > 0), instead of just lengthening
  the interval. Retries resume once the client leaves, so an idle client
  can't wedge the device offline and the link still self-heals when a
  reachable network appears.
- Drop the now-unused WIFI_RETRY_INTERVAL_AP_BUSY_MS constant.

Verified on a XIAO ESP32-C3 (saved SSID unreachable): phone now gets a
192.168.4.x lease, http://192.168.4.1 loads, and 0 reconnection attempts
fire while a client is connected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 27, 2026 13:46
@bring42
bring42 merged commit 9efa74a into main Jul 27, 2026
2 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves provisioning reliability on single-radio ESP32 variants by preventing STA reconnect scans from channel-hopping the radio while a client is using the LUME-Setup SoftAP, which can otherwise disrupt DHCP and lead to 169.254.x.x link-local addresses during setup.

Changes:

  • Disable IDF/Arduino auto-reconnect and WiFi persistence so STA reconnect behavior is owned by handleWifiMaintenance().
  • Skip STA reconnect attempts entirely while a SoftAP client is connected (softAPgetStationNum() != 0).
  • Remove the now-unused “AP busy” retry interval constant and document the new cadence.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/network/wifi.cpp Disables auto-reconnect/persistence and gates STA reconnect attempts on SoftAP station count to avoid DHCP disruption during provisioning.
src/constants.h Removes the unused “AP busy” retry interval and updates documentation for the reconnect cadence.

Comment thread src/network/wifi.cpp
Comment on lines +105 to +108
// unusable). Once the client leaves (station count back to 0) the retry resumes, so
// an idle phone parked on the AP can't wedge the device offline forever and the
// link still self-heals when the saved network (or a freshly-provisioned one)
// returns.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants