| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /* Captive Portal Example
- This example code is in the Public Domain (or CC0 licensed, at your option.)
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
- */
- #include <sys/param.h>
- #include "esp_event.h"
- #include "esp_log.h"
- #include "esp_mac.h"
- #include "nvs_flash.h"
- #include "esp_wifi.h"
- #include "esp_netif.h"
- #include "lwip/inet.h"
- #include "esp_http_server.h"
- #include "dns_server.h"
- #define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
- #define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
- #define EXAMPLE_MAX_STA_CONN CONFIG_ESP_MAX_STA_CONN
- extern const char root_start[] asm("_binary_root_html_start");
- extern const char root_end[] asm("_binary_root_html_end");
- static const char *TAG = "example";
- static void wifi_event_handler(void *arg, esp_event_base_t event_base,
- int32_t event_id, void *event_data)
- {
- if (event_id == WIFI_EVENT_AP_STACONNECTED) {
- wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
- ESP_LOGI(TAG, "station " MACSTR " join, AID=%d",
- MAC2STR(event->mac), event->aid);
- } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
- wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
- ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d",
- MAC2STR(event->mac), event->aid);
- }
- }
- static void wifi_init_softap(void)
- {
- wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
- ESP_ERROR_CHECK(esp_wifi_init(&cfg));
- ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
- wifi_config_t wifi_config = {
- .ap = {
- .ssid = EXAMPLE_ESP_WIFI_SSID,
- .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
- .password = EXAMPLE_ESP_WIFI_PASS,
- .max_connection = EXAMPLE_MAX_STA_CONN,
- .authmode = WIFI_AUTH_WPA_WPA2_PSK
- },
- };
- if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
- wifi_config.ap.authmode = WIFI_AUTH_OPEN;
- }
- ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
- ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
- ESP_ERROR_CHECK(esp_wifi_start());
- esp_netif_ip_info_t ip_info;
- esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"), &ip_info);
- char ip_addr[16];
- inet_ntoa_r(ip_info.ip.addr, ip_addr, 16);
- ESP_LOGI(TAG, "Set up softAP with IP: %s", ip_addr);
- ESP_LOGI(TAG, "wifi_init_softap finished. SSID:'%s' password:'%s'",
- EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
- }
- // HTTP GET Handler
- static esp_err_t root_get_handler(httpd_req_t *req)
- {
- const uint32_t root_len = root_end - root_start;
- ESP_LOGI(TAG, "Serve root");
- httpd_resp_set_type(req, "text/html");
- httpd_resp_send(req, root_start, root_len);
- return ESP_OK;
- }
- static const httpd_uri_t root = {
- .uri = "/",
- .method = HTTP_GET,
- .handler = root_get_handler
- };
- // HTTP Error (404) Handler - Redirects all requests to the root page
- esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
- {
- // Set status
- httpd_resp_set_status(req, "302 Temporary Redirect");
- // Redirect to the "/" root directory
- httpd_resp_set_hdr(req, "Location", "/");
- // iOS requires content in the response to detect a captive portal, simply redirecting is not sufficient.
- httpd_resp_send(req, "Redirect to the captive portal", HTTPD_RESP_USE_STRLEN);
- ESP_LOGI(TAG, "Redirecting to root");
- return ESP_OK;
- }
- static httpd_handle_t start_webserver(void)
- {
- httpd_handle_t server = NULL;
- httpd_config_t config = HTTPD_DEFAULT_CONFIG();
- config.max_open_sockets = 13;
- config.lru_purge_enable = true;
- // Start the httpd server
- ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
- if (httpd_start(&server, &config) == ESP_OK) {
- // Set URI handlers
- ESP_LOGI(TAG, "Registering URI handlers");
- httpd_register_uri_handler(server, &root);
- httpd_register_err_handler(server, HTTPD_404_NOT_FOUND, http_404_error_handler);
- }
- return server;
- }
- void app_main(void)
- {
- /*
- Turn of warnings from HTTP server as redirecting traffic will yield
- lots of invalid requests
- */
- esp_log_level_set("httpd_uri", ESP_LOG_ERROR);
- esp_log_level_set("httpd_txrx", ESP_LOG_ERROR);
- esp_log_level_set("httpd_parse", ESP_LOG_ERROR);
- // Initialize networking stack
- ESP_ERROR_CHECK(esp_netif_init());
- // Create default event loop needed by the main app
- ESP_ERROR_CHECK(esp_event_loop_create_default());
- // Initialize NVS needed by Wi-Fi
- ESP_ERROR_CHECK(nvs_flash_init());
- // Initialize Wi-Fi including netif with default config
- esp_netif_create_default_wifi_ap();
- // Initialise ESP32 in SoftAP mode
- wifi_init_softap();
- // Start the server for the first time
- start_webserver();
- // Start the DNS server that will redirect all queries to the softAP IP
- start_dns_server();
- }
|