123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- /*
- FSPage.ino - Example PageBuilder with HTML page stored SPIFFS
- Copyright (c) 2017 Hieromon Ikasamo. All rights reserved.
- This software is released under the MIT License.
- http://opensource.org/licenses/mit-license.php
- This is a sample sketch that connects to an existing WiFi router already
- connected Internet and makes ESP8266 join the network.
- After writing this sketch, probably you can access 192.168.4.1 from
- your smartphone and it will be listed the WiFi AP that you can connect.
- You can select and connect the listed SSID.
- It is using Web page transition in the dialogue procedure for connecting
- to SSID, and its HTML source is stored in SPIFFS or LittleFS file.
- Before executing this sketch, you need to upload the data folder to SPIFFS
- or LittleFS of ESP8266 by the tool as "ESP8266 Sketch Data Upload" in Tools
- menu in Arduino IDE.
- */
- #if defined(ARDUINO_ARCH_ESP8266)
- #include <ESP8266WiFi.h>
- #include <ESP8266WebServer.h>
- #define WIFI_EVENT_STA_CONNECTED WIFI_EVENT_STAMODE_CONNECTED
- #define WIFI_EVENT_STA_DISCONNECTED WIFI_EVENT_STAMODE_DISCONNECTED
- #define WIFI_EVENT_AP_STACONNECTED WIFI_EVENT_SOFTAPMODE_STACONNECTED
- #define WIFI_EVENT_AP_STADISCONNECTED WIFI_EVENT_SOFTAPMODE_STADISCONNECTED
- #define WIFI_EVENT_ALL WIFI_EVENT_ANY
- #define WIFI_AUTH_OPEN ENC_TYPE_NONE
- #elif defined(ARDUINO_ARCH_ESP32)
- #include <WiFi.h>
- #include <WebServer.h>
- #define WIFI_EVENT_STA_CONNECTED SYSTEM_EVENT_STA_CONNECTED
- #define WIFI_EVENT_STA_DISCONNECTED SYSTEM_EVENT_STA_DISCONNECTED
- #define WIFI_EVENT_AP_STACONNECTED SYSTEM_EVENT_AP_STACONNECTED
- #define WIFI_EVENT_AP_STADISCONNECTED SYSTEM_EVENT_AP_STADISCONNECTED
- #define WIFI_EVENT_ALL SYSTEM_EVENT_MAX
- #endif
- #include "PageBuilder.h"
- #define AP_NAME "esp-ap"
- #define AP_PASS "12345678"
- #if defined(ARDUINO_ARCH_ESP8266)
- #ifdef PB_USE_SPIFFS
- #include <FS.h>
- FS& FlashFile = SPIFFS;
- #else
- #include <LittleFS.h>
- FS& FlashFile = LittleFS;
- #endif
- ESP8266WebServer server;
- #elif defined(ARDUINO_ARCH_ESP32)
- #include <FS.h>
- #include <SPIFFS.h>
- fs::SPIFFSFS& FlashFile = SPIFFS;
- WebServer server;
- #endif
- bool CONNECT_REQ;
- String CONN_SSID;
- String CONN_PSK;
- String REDIRECT_URI;
- String CURRENT_HOST;
- // Page URIs
- #define URI_ROOT "/"
- #define URI_JOIN "/join"
- #define URI_REQ "/request"
- #define URI_RESULT "/result"
- #define URI_WELCOME "/welcome"
- #define URI_FAILED "/failed"
- // Connection request redirector
- String reqConnect(PageArgument&);
- PageElement REQ_ELM("{{REQ}}", { {"REQ", reqConnect} });
- PageBuilder REQ_PAGE(URI_REQ, {REQ_ELM});
- // Connection result redirector
- String resConnect(PageArgument&);
- PageElement CONNRES_ELM("{{CONN}}", { {"CONN", resConnect} });
- PageBuilder CONNRES_PAGE(URI_RESULT, {CONNRES_ELM});
- // Convert RSSI dBm to signal strength
- unsigned int toWiFiQuality(int32_t rssi) {
- unsigned int qu;
- if (rssi <= -100)
- qu = 0;
- else if (rssi >= -50)
- qu = 100;
- else
- qu = 2 * (rssi + 100);
- return qu;
- }
- // This callback function would be invoked from the root page and scans nearby
- // WiFi-AP to make a connectable list.
- String listSSID(PageArgument& args) {
- String s_ssid_list = "";
- int8_t nn = WiFi.scanNetworks(false, true);
- for (uint8_t i = 0; i < nn; i++) {
- String ssid = WiFi.SSID(i);
- if (ssid.length() == 0)
- ssid = "?";
- s_ssid_list += "<div class=\"ssid_list\"><a href=\"" + String(URI_JOIN) + String("?ssid=");
- s_ssid_list += ssid == "?" ? "%3F" : ssid;
- s_ssid_list += "&psk_type=" + String(WiFi.encryptionType(i)) + "\">" + ssid + "</a>";
- s_ssid_list += String(toWiFiQuality(WiFi.RSSI(i))) + "%";
- if (WiFi.encryptionType(i) != WIFI_AUTH_OPEN)
- s_ssid_list += "<span class=\"img_lock\" />";
- s_ssid_list += "</div>";
- }
- CONNECT_REQ = false;
- return s_ssid_list;
- }
- // Accepting connection request.
- // Flag the occurrence of the connection request and response a redirect to
- // the connection result page.
- String reqConnect(PageArgument& args) {
- if (CONN_SSID == "?")
- CONN_SSID = args.arg("ssid");
- CONN_PSK = args.arg("psk");
- // Leave from the AP currently.
- if (WiFi.status() == WL_CONNECTED) {
- WiFi.disconnect();
- while (WiFi.status() == WL_CONNECTED);
- }
- // Available upon connection request.
- CONNECT_REQ = true;
- REDIRECT_URI = "";
- CURRENT_HOST = "";
- // Redirect http request to connection result page.
- server.sendHeader("Location", String("http://") + WiFi.softAPIP().toString() + String(URI_RESULT), true);
- server.send(302, "text/plain", "");
- REQ_PAGE.cancel();
- return "";
- }
- // Performing AP connection procedure.
- void connWiFi() {
- // Starts connecting the ap as WIFI_STA
- Serial.print("Connect to " + CONN_SSID + "/" + CONN_PSK + " ");
- WiFi.begin(CONN_SSID.c_str(), CONN_PSK.c_str());
- unsigned long tm = millis();
- do {
- delay(500);
- Serial.print('.');
- if (millis() - tm > 30000)
- break;
- } while (WiFi.status() != WL_CONNECTED);
- Serial.print(String(WiFi.status()) + ":");
- // Dynamically switch the result page URL according to the connection result.
- // If it connected to the AP, redirect localIP () as the host address.
- // Connection failed, redirect to a failed page addressed on softAPIP().
- if (WiFi.status() == WL_CONNECTED) {
- // Connection established, makes a response page into a new IP address.
- CURRENT_HOST = WiFi.localIP().toString();
- REDIRECT_URI = URI_WELCOME;
- Serial.println("OK");
- }
- else {
- // Connection refused, a fails page keeps on softAPIP.
- CURRENT_HOST = WiFi.softAPIP().toString();
- REDIRECT_URI = URI_FAILED;
- Serial.println("Failed");
- }
- }
- // Responds redirect destination according to the connection result of success
- // or failure to the AP.
- String resConnect(PageArgument& args) {
- String redirect = String("http://") + CURRENT_HOST + REDIRECT_URI;
- Serial.println("Redirect: " + redirect);
- server.sendHeader("Location", redirect, true);
- server.sendHeader("Connection", "keep-alive");
- server.send(302, "text/plain", "");
- server.client().stop();
- CONNRES_PAGE.cancel();
- Serial.println();
- WiFi.printDiag(Serial);
- return "";
- }
- // WiFi event determination and echo back.
- void broadcastEvent(WiFiEvent_t event) {
- static const char eventText_APSTA_CONN[] PROGMEM = "SoftAP station connected.";
- static const char eventText_APSTA_DISC[] PROGMEM = "SoftAP station disconnected.";
- static const char eventText_STA_CONN[] PROGMEM = "WiFi AP connected.";
- static const char eventText_STA_DISC[] PROGMEM = "WiFi AP disconnected.";
- const char* eventText;
- switch (event) {
- case WIFI_EVENT_AP_STACONNECTED:
- eventText = eventText_APSTA_CONN;
- break;
- case WIFI_EVENT_AP_STADISCONNECTED:
- eventText = eventText_APSTA_DISC;
- break;
- case WIFI_EVENT_STA_CONNECTED:
- eventText = eventText_STA_CONN;
- break;
- case WIFI_EVENT_STA_DISCONNECTED:
- eventText = eventText_STA_DISC;
- break;
- default:
- eventText = nullptr;
- }
- if (eventText)
- Serial.println(String("[event] ") + String(FPSTR(eventText)));
- }
- // Get an architecture of compiled
- String getArch(PageArgument& args) {
- #if defined(ARDUINO_ARCH_ESP8266)
- return "ESP8266";
- #elif defined(ARDUINO_ARCH_ESP32)
- return "ESP32";
- #endif
- }
- // HTML page declarations.
- // root page
- PageElement SSID_ELM("file:/root.htm", {
- { "SSID_LIST", listSSID },
- { "URI_ROOT", [](PageArgument& args) { return URI_ROOT; }}
- });
- PageBuilder SSID_PAGE(URI_ROOT, { SSID_ELM });
- // SSID & Password entry page
- PageElement ENTRY_ELM("file:/entry.htm", {
- { "ESP_ARCH", getArch },
- { "ENTRY", [](PageArgument& args) { CONN_SSID = args.arg("ssid"); return "AP"; } },
- { "URI_REQ", [](PageArgument& args) { return URI_REQ; } },
- { "SSID", [](PageArgument& args) { return CONN_SSID == "?" ? "placeholder=\"SSID\"" : String("value=\"" + CONN_SSID + "\" readonly"); } },
- { "PSK", [](PageArgument& args) { return args.arg("psk_type") != "7" ? "<input type=\"text\" name=\"psk\" placeholder=\"Password\" />" : ""; } }
- });
- PageBuilder ENTRY_PAGE(URI_JOIN, {ENTRY_ELM});
- // Connection successful page
- PageElement WELCOME_ELM("file:/connect.htm", {
- { "ESP-AP", [](PageArgument& args) { return AP_NAME; } },
- { "SSID", [](PageArgument& args) { return WiFi.SSID(); } },
- { "IP", [](PageArgument& args) { return WiFi.localIP().toString(); } },
- { "GATEWAY", [](PageArgument& args) { return WiFi.gatewayIP().toString(); } },
- { "SUBNET", [](PageArgument& args) { return WiFi.subnetMask().toString(); } }
- });
- PageBuilder WELCOME_PAGE(URI_WELCOME, {WELCOME_ELM});
- // Connection failed page
- PageElement FAILED_ELM("file:/failed.htm", {
- { "SSID", [](PageArgument& args) { return CONN_SSID; } },
- { "RESULT", [](PageArgument& args) { return String(WiFi.status()); } }
- });
- PageBuilder FAILED_PAGE(URI_FAILED, {FAILED_ELM});
- void setup() {
- delay(1000);
- Serial.begin(115200);
- Serial.println();
- // Prepare HTML page
- SSID_PAGE.insert(server);
- ENTRY_PAGE.insert(server);
- REQ_PAGE.insert(server);
- CONNRES_PAGE.insert(server);
- WELCOME_PAGE.insert(server);
- FAILED_PAGE.insert(server);
- // Start WiFi soft AP.
- WiFi.softAPdisconnect();
- WiFi.disconnect();
- delay(100);
- WiFi.mode(WIFI_AP_STA);
- WiFi.softAP(AP_NAME, AP_PASS);
- while (WiFi.softAPIP() == IPAddress(0, 0, 0, 0)) {
- yield();
- delay(100);
- }
- Serial.print(AP_NAME " started. IP:");
- Serial.println(WiFi.softAPIP());
- // Start http server.
- FlashFile.begin();
- server.begin();
- // Turn on WiFi event handling.
- // It is deprecated in ESP8266, but it remains because the alternative
- // API's onSoftAPModeStationConnected event does not fire properly in
- // SoftAP + STA mode.
- WiFi.onEvent(broadcastEvent, WIFI_EVENT_ALL);
- }
- void loop() {
- server.handleClient();
- if (CONNECT_REQ) {
- connWiFi();
- CONNECT_REQ = false;
- }
- }
|