ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
captive_portal.cpp
Go to the documentation of this file.
1#include "captive_portal.h"
2#ifdef USE_CAPTIVE_PORTAL
3#include "esphome/core/log.h"
6#include "captive_index.h"
7
8namespace esphome {
9namespace captive_portal {
10
11static const char *const TAG = "captive_portal";
12
13void CaptivePortal::handle_config(AsyncWebServerRequest *request) {
14 AsyncResponseStream *stream = request->beginResponseStream("application/json");
15 stream->addHeader("cache-control", "public, max-age=0, must-revalidate");
16 stream->printf(R"({"mac":"%s","name":"%s","aps":[{})", get_mac_address_pretty().c_str(), App.get_name().c_str());
17
18 for (auto &scan : wifi::global_wifi_component->get_scan_result()) {
19 if (scan.get_is_hidden())
20 continue;
21
22 // Assumes no " in ssid, possible unicode isses?
23 stream->printf(R"(,{"ssid":"%s","rssi":%d,"lock":%d})", scan.get_ssid().c_str(), scan.get_rssi(),
24 scan.get_with_auth());
25 }
26 stream->print(F("]}"));
27 request->send(stream);
28}
29void CaptivePortal::handle_wifisave(AsyncWebServerRequest *request) {
30 std::string ssid = request->arg("ssid").c_str();
31 std::string psk = request->arg("psk").c_str();
32 ESP_LOGI(TAG, "Requested WiFi Settings Change:");
33 ESP_LOGI(TAG, " SSID='%s'", ssid.c_str());
34 ESP_LOGI(TAG, " Password=" LOG_SECRET("'%s'"), psk.c_str());
37 request->redirect("/?save");
38}
39
41#ifndef USE_ARDUINO
42 // No DNS server needed for non-Arduino frameworks
43 this->disable_loop();
44#endif
45}
47 this->base_->init();
48 if (!this->initialized_) {
49 this->base_->add_handler(this);
50 }
51
52#ifdef USE_ARDUINO
53 this->dns_server_ = make_unique<DNSServer>();
54 this->dns_server_->setErrorReplyCode(DNSReplyCode::NoError);
56 this->dns_server_->start(53, "*", ip);
57 // Re-enable loop() when DNS server is started
58 this->enable_loop();
59#endif
60
61 this->base_->get_server()->onNotFound([this](AsyncWebServerRequest *req) {
62 if (!this->active_ || req->host().c_str() == wifi::global_wifi_component->wifi_soft_ap_ip().str()) {
63 req->send(404, "text/html", "File not found");
64 return;
65 }
66
67 auto url = "http://" + wifi::global_wifi_component->wifi_soft_ap_ip().str();
68 req->redirect(url.c_str());
69 });
70
71 this->initialized_ = true;
72 this->active_ = true;
73}
74
75void CaptivePortal::handleRequest(AsyncWebServerRequest *req) {
76 if (req->url() == "/") {
77#ifndef USE_ESP8266
78 auto *response = req->beginResponse(200, "text/html", INDEX_GZ, sizeof(INDEX_GZ));
79#else
80 auto *response = req->beginResponse_P(200, "text/html", INDEX_GZ, sizeof(INDEX_GZ));
81#endif
82 response->addHeader("Content-Encoding", "gzip");
83 req->send(response);
84 return;
85 } else if (req->url() == "/config.json") {
86 this->handle_config(req);
87 return;
88 } else if (req->url() == "/wifisave") {
89 this->handle_wifisave(req);
90 return;
91 }
92}
93
96 // Before WiFi
97 return setup_priority::WIFI + 1.0f;
98}
99void CaptivePortal::dump_config() { ESP_LOGCONFIG(TAG, "Captive Portal:"); }
100
101CaptivePortal *global_captive_portal = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
102
103} // namespace captive_portal
104} // namespace esphome
105#endif
const std::string & get_name() const
Get the name of this Application set by pre_setup().
void enable_loop()
Enable this component's loop.
void disable_loop()
Disable this component's loop.
std::unique_ptr< DNSServer > dns_server_
CaptivePortal(web_server_base::WebServerBase *base)
void handle_config(AsyncWebServerRequest *request)
web_server_base::WebServerBase * base_
void handleRequest(AsyncWebServerRequest *req) override
void handle_wifisave(AsyncWebServerRequest *request)
std::shared_ptr< AsyncWebServer > get_server() const
void add_handler(AsyncWebHandler *handler)
void save_wifi_sta(const std::string &ssid, const std::string &password)
CaptivePortal * global_captive_portal
WiFiComponent * global_wifi_component
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
Definition helpers.cpp:584
Application App
Global storage of Application pointer - only one Application can exist.
std::string str() const
Definition ip_address.h:52