Skip to content

fix(wlan): move WiFi.disconnect/begin from async_tcp to update() in addCredentials #243

@Phantomias2006

Description

@Phantomias2006

Problem

Wlan::addCredentials() is called from the async_tcp context via WebHandler.cpp:703 (setNetwork) and WebHandler.cpp:732 (addNetwork). Inside addCredentials(), it directly calls WiFi.disconnect() and WiFi.begin() — both are blocking operations that acquire internal WiFi mutexes via xSemaphoreTake(portMAX_DELAY), blocking the async_tcp task for ~100–300 ms.

In combination with the previously fixed CR-003-001 (NVS write from async_tcp), the addNetwork path (force=true) could block async_tcp for >500 ms total, causing the browser to receive the response too late — especially critical in the Captive Portal flow where iOS/Android heuristics may drop the connection.

Additionally, the wifiState = WifiState::AddCredentials assignment in addCredentials() created a race condition between async_tcp and ConnectTask (CR-003-006).

Root Cause

The Pending-Flag pattern (established in B39-fix: wifiModePsPending, wlanSaveConfigPending, recoveryPending) was not applied to the WiFi connect initiation path. WiFi-API calls in the async_tcp handler context are forbidden in ESP-IDF 4.x (CLAUDE.md convention).

Fix

Introduced newCredentialsPending flag (static member). addCredentials() now only stores credentials and sets the flag — no WiFi calls. In update() (ConnectTask context), the pending block performs WiFi.disconnect() + WiFi.begin() + esp_wifi_set_config() safely. Also added return-value check on esp_wifi_get_config() to prevent writing uninitialized stack data on failure.

This also resolves the wifiState write race (CR-003-006 partial fix) since wifiState = AddCredentials now only happens in ConnectTask.

Review-Finding: CR-003-003
Severity: HIGH

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions