Skip to content

WPA2-Enterprise networks cannot be joined: ESP_WIFI_ENTERPRISE_SUPPORT is disabled, and the failure is silent #117

Description

@isaka1022

Summary

WPA2-Enterprise (802.1X) networks cannot be joined, and the way it fails is misleading. firmware/sdkconfig.defaults:44 sets

CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=n

With that off, the esp_eap_client_* functions compile to stubs that return ESP_OK, so nothing reports an error, but the station never leaves PSK mode. Every association then fails with reason 210 (WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY) even though the scan found the AP:

I (582903) WifiStation: Found AP: <SSID>, BSSID: ee:38:83:6b:2c:a2, RSSI: -72, Channel: 1, Authmode: 5
I (582963) WifiBoard: WiFi connecting to <SSID>
W (585373) StackChanEap: disconnected from <SSID>, reason=210
I (585373) WifiStation: Reconnecting <SSID> (attempt 1 / 5)

Authmode: 5 is WIFI_AUTH_WPA2_ENTERPRISE, so the AP is clearly identified as enterprise; the station just has no EAP support to answer with. I spent a while chasing PMF and scan settings before finding the sdkconfig line, so I think this is worth an issue even if you decide not to support enterprise networks — the silent ESP_OK is what makes it hard to diagnose.

It works once enterprise support is enabled

I have a working build on a CoreS3 (K151) with ESP-IDF v5.5.4 joining a PEAP/MSCHAPv2 network, reconnecting on reboot, and reaching MQTT and OTA normally:

I (162868) esp_netif_handlers: sta ip: 192.168.17.181, mask: 255.255.252.0, gw: 192.168.16.1
I (162868) WifiBoard: Connected to WiFi: <SSID>
I (170978) MQTT: Connected to endpoint

The firmware side is small: three esp_eap_client_set_* calls plus esp_wifi_sta_enterprise_enable() before starting the station, and wpa_supplicant added to the component requirements. I put it behind a Kconfig option that does select ESP_WIFI_ENTERPRISE_SUPPORT, defaulting to n, so the flash cost is only paid by people who ask for it. Enabling it adds roughly 34 KB.

Questions before I send a PR

I would rather agree on the shape first than send something you would have to redesign.

1. How should credentials reach the device?

  • (a) Extend the BLE setWifi message with optional identity and username fields. A message without username takes the existing PSK path unchanged, so the current app keeps working. This is what I am running now, driven by a small Python BLE client. It needs matching fields in the Flutter app to be usable by normal users.
  • (b) Keep it build-time only: put the credentials in Kconfig for people who build their own firmware, and leave the app alone.

2. Where should the enterprise credentials be stored?

SsidManager comes from 78/esp-wifi-connect, and SsidItem only holds an SSID and a password:

// managed_components/78__esp-wifi-connect/include/ssid_manager.h:7-10
struct SsidItem {
    std::string ssid;
    std::string password;
};

The identity and username have nowhere to go there, so after a reboot the normal WifiBoard::StartNetwork() path retries as PSK and fails.

  • (a) Store them in a StackChan-owned NVS namespace keyed by SSID, and apply them in the StartNetwork() override in firmware/main/hal/board/stackchan.cc. Self-contained in this repository. This is what I am running.
  • (b) Extend SsidItem upstream in 78/esp-wifi-connect. Arguably the right home, but it means a PR there, a release, and a dependency bump here before anything can land.

I lean towards (a) for both, but the second one in particular feels like your call, since managed_components/ is regenerated from dependencies.lock and a local patch would not survive.

One thing I could not test

I cannot verify any app-side change end to end, because stackChanBluePrivateKey in app/lib/util/value_constant.dart:311-312 is an empty string in this repository. select_blue_device.dart:174 tries an RSA-OAEP decrypt with it, the key parse throws, and activateDevice() is never reached, so the official app cannot complete pairing when built from source. If you want the app-side fields as well, I can write them and confirm flutter analyze and the build, but I would have to say plainly in the PR that the flow itself is unverified.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions