From 4aa2f24812c4ff87f60aeed47680222ef434be53 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 30 May 2025 14:20:11 +0300 Subject: [PATCH 1/3] feat(ap): Add support for DHCP Captive Portal (opt 114) --- .../examples/CaptivePortal/CaptivePortal.ino | 5 ++- libraries/WiFi/src/AP.cpp | 42 +++++++++++++++++++ libraries/WiFi/src/WiFiAP.h | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino b/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino index d956dc14ad3..7759aa09a1c 100644 --- a/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino +++ b/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino @@ -34,8 +34,9 @@ void handleNotFound() { void setup() { Serial.begin(115200); - WiFi.mode(WIFI_AP); - WiFi.softAP("ESP32-DNSServer"); + WiFi.AP.begin(); + WiFi.AP.create("ESP32-DNSServer"); + WiFi.AP.enableDhcpCaptivePortal(); // by default DNSServer is started serving any "*" domain name. It will reply // AccessPoint's IP to all DNS request (this is required for Captive Portal detection) diff --git a/libraries/WiFi/src/AP.cpp b/libraries/WiFi/src/AP.cpp index 0e7839764ea..c98fe7ec44b 100644 --- a/libraries/WiFi/src/AP.cpp +++ b/libraries/WiFi/src/AP.cpp @@ -305,6 +305,48 @@ bool APClass::enableNAPT(bool enable) { return true; } +bool APClass::enableDhcpCaptivePortal() { +#if CONFIG_ESP_ENABLE_DHCP_CAPTIVEPORTAL + esp_err_t err = ESP_OK; + static char captiveportal_uri[32] = {0,}; + + if (!started()) { + log_e("AP must be first started to enable DHCP Captive Portal"); + return false; + } + + // Create Captive Portal URL: http://192.168.0.4 + strcpy(captiveportal_uri, "http://"); + strcat(captiveportal_uri, String(localIP()).c_str()); + + // Stop DHCPS + err = esp_netif_dhcps_stop(_esp_netif); + if (err && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) { + log_e("DHCPS Stop Failed! 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + + // Enable DHCP Captive Portal + err = esp_netif_dhcps_option(_esp_netif, ESP_NETIF_OP_SET, ESP_NETIF_CAPTIVEPORTAL_URI, captiveportal_uri, strlen(captiveportal_uri)); + if (err) { + log_e("Could not set enable DHCP Captive Portal! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + + // Start DHCPS + err = esp_netif_dhcps_start(_esp_netif); + if (err) { + log_e("DHCPS Start Failed! 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + + return true; +#else + log_e("CONFIG_ESP_ENABLE_DHCP_CAPTIVEPORTAL is not enabled!"); + return false; +#endif +} + String APClass::SSID(void) const { if (!started()) { return String(); diff --git a/libraries/WiFi/src/WiFiAP.h b/libraries/WiFi/src/WiFiAP.h index 540ec87f44f..2b7ce469801 100644 --- a/libraries/WiFi/src/WiFiAP.h +++ b/libraries/WiFi/src/WiFiAP.h @@ -53,6 +53,7 @@ class APClass : public NetworkInterface { bool bandwidth(wifi_bandwidth_t bandwidth); bool enableNAPT(bool enable = true); + bool enableDhcpCaptivePortal(); String SSID(void) const; uint8_t stationCount(); From 444bbc9dc441cd065a25b3851cb8ee5cb7783ac6 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 30 May 2025 14:37:39 +0300 Subject: [PATCH 2/3] feat(ap): No need to guard the function --- libraries/WiFi/src/AP.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/WiFi/src/AP.cpp b/libraries/WiFi/src/AP.cpp index c98fe7ec44b..eac1fb69bcf 100644 --- a/libraries/WiFi/src/AP.cpp +++ b/libraries/WiFi/src/AP.cpp @@ -306,7 +306,6 @@ bool APClass::enableNAPT(bool enable) { } bool APClass::enableDhcpCaptivePortal() { -#if CONFIG_ESP_ENABLE_DHCP_CAPTIVEPORTAL esp_err_t err = ESP_OK; static char captiveportal_uri[32] = {0,}; @@ -341,10 +340,6 @@ bool APClass::enableDhcpCaptivePortal() { } return true; -#else - log_e("CONFIG_ESP_ENABLE_DHCP_CAPTIVEPORTAL is not enabled!"); - return false; -#endif } String APClass::SSID(void) const { From 711ca8820efefc2ca08573fb83cab0acac7ab142 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Wed, 4 Jun 2025 13:28:04 +0000 Subject: [PATCH 3/3] ci(pre-commit): Apply automatic fixes --- libraries/WiFi/src/AP.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/WiFi/src/AP.cpp b/libraries/WiFi/src/AP.cpp index eac1fb69bcf..a649c3898cb 100644 --- a/libraries/WiFi/src/AP.cpp +++ b/libraries/WiFi/src/AP.cpp @@ -307,7 +307,9 @@ bool APClass::enableNAPT(bool enable) { bool APClass::enableDhcpCaptivePortal() { esp_err_t err = ESP_OK; - static char captiveportal_uri[32] = {0,}; + static char captiveportal_uri[32] = { + 0, + }; if (!started()) { log_e("AP must be first started to enable DHCP Captive Portal");