From b697c0f2c4f2f810fcdccac8c5f9e495d0043f0f Mon Sep 17 00:00:00 2001 From: dfry-lhzn Date: Tue, 19 May 2026 13:29:04 -0400 Subject: [PATCH 1/2] Add optional WPA3/PMF configuration parameters for Station mode (#111) - Adds CONFIG_REQUIRE_PMF_S to allow users with modern hotspots (like Pixel 9 Pro) to enforce Protected Management Frames. - Defaults PMF to capable but not required to preserve compatibility with legacy WPA2 networks. - Sets sae_pwe_h2e to WPA3_SAE_PWE_BOTH where available to enable WPA3 SAE flow. --- LoggerFirmware/include/Configuration.h | 3 ++- LoggerFirmware/src/Configuration.cpp | 3 ++- LoggerFirmware/src/WiFiAdapter.cpp | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/LoggerFirmware/include/Configuration.h b/LoggerFirmware/include/Configuration.h index 3d11cdab..1e47a3f2 100644 --- a/LoggerFirmware/include/Configuration.h +++ b/LoggerFirmware/include/Configuration.h @@ -99,7 +99,8 @@ class Config { CONFIG_UPLOAD_INTERVAL_S,/* String: interval (seconds) between upload attempts */ CONFIG_UPLOAD_DURATION_S,/* String: duration (seconds) for each upload event */ CONFIG_UPLOAD_CERT_S, /* String: certificate to pass to upload server for authentication */ - CONFIG_MDNS_NAME_S /* String: recognition name for mDNS responder (hostname: name.local) */ + CONFIG_MDNS_NAME_S, /* String: recognition name for mDNS responder (hostname: name.local) */ + CONFIG_REQUIRE_PMF_S /* String: Require PMF for WPA3 connections (true/false) */ }; /// \brief Extract a configuration string for the specified parameter diff --git a/LoggerFirmware/src/Configuration.cpp b/LoggerFirmware/src/Configuration.cpp index 2b3a9d08..a3a4556e 100644 --- a/LoggerFirmware/src/Configuration.cpp +++ b/LoggerFirmware/src/Configuration.cpp @@ -86,7 +86,8 @@ const String lookup[] = { "UploadInterval", ///< Interval (seconds) between upload attempts "UploadDuration", ///< Time (seconds) for upload activity before diverting back to other efforts "UploadCert", ///< Certificate to pass to the upload server for TLS - "mDNSName" + "mDNSName", + "RequirePMF" ///< Require PMF for WPA3 (string) }; /// Default constructor. This sets up for a dummy parameter store, which is configured diff --git a/LoggerFirmware/src/WiFiAdapter.cpp b/LoggerFirmware/src/WiFiAdapter.cpp index 9bbc332d..12a40610 100644 --- a/LoggerFirmware/src/WiFiAdapter.cpp +++ b/LoggerFirmware/src/WiFiAdapter.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -322,6 +323,25 @@ class ConnectionStateMachine { Serial.print("ERR: attempting to join a WiFi network as a station without a specified SSID\n"); return false; } + + // Configure WPA3/PMF fallback & parameters for modern hotspots + WiFi.mode(WIFI_STA); + wifi_config_t conf; + esp_wifi_get_config(WIFI_IF_STA, &conf); + + bool require_pmf = false; + String require_pmf_str; + if (logger::LoggerConfig.GetConfigString(logger::Config::ConfigParam::CONFIG_REQUIRE_PMF_S, require_pmf_str)) { + require_pmf = require_pmf_str.equalsIgnoreCase("true") || require_pmf_str == "1"; + } + + conf.sta.pmf_cfg.capable = true; + conf.sta.pmf_cfg.required = require_pmf; +#ifdef WPA3_SAE_PWE_BOTH + conf.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH; +#endif + esp_wifi_set_config(WIFI_IF_STA, &conf); + wl_status_t status = WiFi.begin(ssid.c_str(), password.c_str()); WiFi.setSleep(false); m_lastConnectAttempt = millis(); From 97137352bf37aa01a12dd52ec0933c404ecc96cb Mon Sep 17 00:00:00 2001 From: dfry-lhzn Date: Tue, 19 May 2026 13:41:37 -0400 Subject: [PATCH 2/2] Add debug logging for PMF configuration --- LoggerFirmware/src/WiFiAdapter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/LoggerFirmware/src/WiFiAdapter.cpp b/LoggerFirmware/src/WiFiAdapter.cpp index 12a40610..cafef38e 100644 --- a/LoggerFirmware/src/WiFiAdapter.cpp +++ b/LoggerFirmware/src/WiFiAdapter.cpp @@ -335,6 +335,10 @@ class ConnectionStateMachine { require_pmf = require_pmf_str.equalsIgnoreCase("true") || require_pmf_str == "1"; } + if (m_verbose) { + Serial.printf("DBG: WPA3 PMF configured as %s\n", require_pmf ? "REQUIRED" : "CAPABLE-ONLY"); + } + conf.sta.pmf_cfg.capable = true; conf.sta.pmf_cfg.required = require_pmf; #ifdef WPA3_SAE_PWE_BOTH