ESPHome 2025.5.0
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, "Captive Portal 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
42 this->base_->init();
43 if (!this->initialized_) {
44 this->base_->add_handler(this);
45 this->base_->add_ota_handler();
46 }
47
48#ifdef USE_ARDUINO
50 this->dns_server_->setErrorReplyCode(DNSReplyCode::NoError);
52 this->dns_server_->start(53, "*", ip);
53#endif
54
55 this->base_->get_server()->onNotFound([this](AsyncWebServerRequest *req) {
56 if (!this->active_ || req->host().c_str() == wifi::global_wifi_component->wifi_soft_ap_ip().str()) {
57 req->send(404, "text/html", "File not found");
58 return;
59 }
60
61 auto url = "http://" + wifi::global_wifi_component->wifi_soft_ap_ip().str();
62 req->redirect(url.c_str());
63 });
64
65 this->initialized_ = true;
66 this->active_ = true;
67}
68
69void CaptivePortal::handleRequest(AsyncWebServerRequest *req) {
70 if (req->url() == "/") {
71 auto *response = req->beginResponse_P(200, "text/html", INDEX_GZ, sizeof(INDEX_GZ));
72 response->addHeader("Content-Encoding", "gzip");
73 req->send(response);
74 return;
75 } else if (req->url() == "/config.json") {
76 this->handle_config(req);
77 return;
78 } else if (req->url() == "/wifisave") {
79 this->handle_wifisave(req);
80 return;
81 }
82}
83
86 // Before WiFi
87 return setup_priority::WIFI + 1.0f;
88}
89void CaptivePortal::dump_config() { ESP_LOGCONFIG(TAG, "Captive Portal:"); }
90
91CaptivePortal *global_captive_portal = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
92
93} // namespace captive_portal
94} // namespace esphome
95#endif
const std::string & get_name() const
Get the name of this Application set by pre_setup().
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::unique_ptr< T > make_unique(Args &&...args)
Definition helpers.h:85
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
Definition helpers.cpp:732
Application App
Global storage of Application pointer - only one Application can exist.
std::string str() const
Definition ip_address.h:52