2#ifdef USE_CAPTIVE_PORTAL
16static const char *
const TAG =
"captive_portal";
19 AsyncResponseStream *stream = request->beginResponseStream(ESPHOME_F(
"application/json"));
20 stream->addHeader(ESPHOME_F(
"cache-control"), ESPHOME_F(
"public, max-age=0, must-revalidate"));
21 char mac_s[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
24 stream->print(ESPHOME_F(
"{\"mac\":\""));
25 stream->print(mac_str);
26 stream->print(ESPHOME_F(
"\",\"name\":\""));
28 stream->print(ESPHOME_F(
"\",\"aps\":[{}"));
30 stream->printf(R
"({"mac":"%s","name":"%s","aps":[{})", mac_str, App.get_name().c_str());
35 char escaped_ssid[32 * JSON_ESCAPE_MAX_EXPANSION + 1];
41 for (
const auto &scan : results) {
42 bool with_auth =
false;
48 stream->print(ESPHOME_F(
",{\"ssid\":\""));
49 stream->print(escaped_ssid);
50 stream->print(ESPHOME_F(
"\",\"rssi\":"));
51 stream->print(scan.get_rssi());
52 stream->print(ESPHOME_F(
",\"lock\":"));
53 stream->print(with_auth);
54 stream->print(ESPHOME_F(
"}"));
56 stream->printf(R
"(,{"ssid":"%s","rssi":%d,"lock":%d})", escaped_ssid, scan.get_rssi(), with_auth);
60 stream->print(ESPHOME_F(
"]}"));
61 request->send(stream);
64 const auto &ssid = request->arg(
"ssid");
65 const auto &psk = request->arg(
"psk");
67 "Requested WiFi Settings Change:\n"
69 " Password=" LOG_SECRET(
"'%s'"),
70 ssid.c_str(), psk.c_str());
78 request->send(200, ESPHOME_F(
"text/plain"), ESPHOME_F(
"Saved. Connecting..."));
84#ifdef USE_PROVISIONING
92 ESP_LOGD(TAG,
"Provisioning window closed; stopping captive portal");
107#if defined(USE_ESP32)
111#elif defined(USE_ARDUINO)
113 this->
dns_server_->setErrorReplyCode(DNSReplyCode::NoError);
123 ESP_LOGV(TAG,
"Captive portal started");
128 char url_buf[AsyncWebServerRequest::URL_BUF_SIZE];
131 const auto &url = req->url();
133 if (url == ESPHOME_F(
"/config.json")) {
136 }
else if (url == ESPHOME_F(
"/wifisave")) {
145 auto *response = req->beginResponse(200, ESPHOME_F(
"text/html"), INDEX_GZ,
sizeof(INDEX_GZ));
147 auto *response = req->beginResponse_P(200, ESPHOME_F(
"text/html"), INDEX_GZ,
sizeof(INDEX_GZ));
149#ifdef USE_CAPTIVE_PORTAL_GZIP
150 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"gzip"));
152 response->addHeader(ESPHOME_F(
"Content-Encoding"), ESPHOME_F(
"br"));
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
void enable_loop()
Enable this component's loop.
void defer(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call with a const char* name.
void disable_loop()
Disable this component's loop.
StringRef is a reference to a string owned by something else.
constexpr const char * c_str() const
float get_setup_priority() const override
std::unique_ptr< DNSServer > dns_server_
void dump_config() override
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)
void add_on_closed_callback(F &&callback)
void add_handler_without_auth(AsyncWebHandler *handler)
WARNING: Registers a handler that bypasses the USE_WEBSERVER_AUTH middleware.
Guards WiFiComponent::scan_result_.
void save_wifi_sta(const std::string &ssid, const std::string &password)
network::IPAddress wifi_soft_ap_ip()
const wifi_scan_vector_t< WiFiScanResult > & get_scan_result() const
Main-loop callers may read this directly.
CaptivePortal * global_captive_portal
ProvisioningManager * global_provisioning_manager
bool should_show_scan_entry(const Results &results, const Entry &scan, bool &with_auth)
WiFiComponent * global_wifi_component
const char * get_mac_address_pretty_into_buffer(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > buf)
Get the device MAC address into the given buffer, in colon-separated uppercase hex notation.
const char * json_escape_into_buffer(std::span< char > buf, StringRef value, bool short_control_escapes)
Copy value into buf, escaping the characters that cannot appear raw inside a JSON string literal.
Application App
Global storage of Application pointer - only one Application can exist.