Supports AutoConnectAux

pull/41/head
Hieromon Ikasamo 6 years ago
parent 3d0d397bf1
commit 4de6dfb101
  1. 2
      .travis.yml
  2. 6
      keywords.txt
  3. 2
      library.json
  4. 2
      library.properties
  5. 46
      src/AutoConnect.cpp
  6. 38
      src/AutoConnect.h
  7. 135
      src/AutoConnectAux.cpp
  8. 156
      src/AutoConnectAux.h
  9. 101
      src/AutoConnectPage.cpp

@ -20,7 +20,7 @@ before_install:
- if [[ "$BOARD" =~ "esp32:esp32:" ]]; then - if [[ "$BOARD" =~ "esp32:esp32:" ]]; then
arduino --install-boards esp32:esp32; arduino --install-boards esp32:esp32;
fi fi
- arduino --install-library PubSubClient,PageBuilder:1.1.0 - arduino --install-library PubSubClient,PageBuilder:1.1.1
- buildExampleSketch() { arduino --verbose-build --verify --board $BOARD $PWD/examples/$1/$1.ino; } - buildExampleSketch() { arduino --verbose-build --verify --board $BOARD $PWD/examples/$1/$1.ino; }
install: install:
- mkdir -p ~/Arduino/libraries - mkdir -p ~/Arduino/libraries

@ -4,6 +4,11 @@
AutoConnect KEYWORD1 AutoConnect KEYWORD1
AutoConnectConfig KEYWORD1 AutoConnectConfig KEYWORD1
AutoConnectCredential KEYWORD1 AutoConnectCredential KEYWORD1
AutoConnectAux KEYWORD1
AutoConnectText KEYWORD1
AutoConnectInput KEYWORD1
AutoConnectButon KEYWORD1
AutoConnectSubmit KEYWORD1
####################################### #######################################
# Methods and Functions (KEYWORD2) # Methods and Functions (KEYWORD2)
@ -17,6 +22,7 @@ handleClient KEYWORD2
handleRequest KEYWORD2 handleRequest KEYWORD2
home KEYWORD2 home KEYWORD2
host KEYWORD2 host KEYWORD2
join KEYWORD2
load KEYWORD2 load KEYWORD2
onDetect KEYWORD2 onDetect KEYWORD2
onNotFound KEYWORD2 onNotFound KEYWORD2

@ -21,6 +21,6 @@
"espressif8266", "espressif8266",
"espressif32" "espressif32"
], ],
"version": "0.9.6", "version": "0.9.7",
"license": "MIT" "license": "MIT"
} }

@ -1,5 +1,5 @@
name=AutoConnect name=AutoConnect
version=0.9.6 version=0.9.7
author=Hieromon Ikasamo <hieromon@gmail.com> author=Hieromon Ikasamo <hieromon@gmail.com>
maintainer=Hieromon Ikasamo <hieromon@gmail.com> maintainer=Hieromon Ikasamo <hieromon@gmail.com>
sentence=ESP8266/ESP32 WLAN configuration at runtime with web interface. sentence=ESP8266/ESP32 WLAN configuration at runtime with web interface.

@ -2,8 +2,8 @@
* AutoConnect class implementation. * AutoConnect class implementation.
* @file AutoConnect.cpp * @file AutoConnect.cpp
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 0.9.6 * @version 0.9.7
* @date 2018-09-27 * @date 2018-11-17
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -51,6 +51,7 @@ void AutoConnect::_initialize() {
_menuTitle = String(AUTOCONNECT_MENU_TITLE); _menuTitle = String(AUTOCONNECT_MENU_TITLE);
_portalTimeout = AUTOCONNECT_TIMEOUT; _portalTimeout = AUTOCONNECT_TIMEOUT;
memset(&_credential, 0x00, sizeof(struct station_config)); memset(&_credential, 0x00, sizeof(struct station_config));
_aux.release();
} }
/** /**
@ -257,6 +258,34 @@ WebServerClass& AutoConnect::host() {
return *_webServer; return *_webServer;
} }
/**
* Append auxiliary pages made up with AutoConnectAux.
* @param aux A reference to AutoConnectAux that made up
* the auxiliary page to be added.
*/
void AutoConnect::join(AutoConnectAux& aux) {
if (_aux) {
AutoConnectAux* addon = _aux.get();
addon->_append(aux);
}
else
_aux.reset(&aux);
aux._join(*this);
AC_DBG("%s contained\n", aux._uri);
}
/**
* Append auxiliary pages made up with AutoConnectAux.
* @param aux A vector of reference to AutoConnectAux that made up
* the auxiliary page to be added.
*/
void AutoConnect::join(std::vector<std::reference_wrapper<AutoConnectAux>> aux) {
for (std::size_t n = 0; n < aux.size(); n++) {
AutoConnectAux& addon = aux[n + 1].get();
join(addon);
}
}
/** /**
* Starts Web server for AutoConnect service. * Starts Web server for AutoConnect service.
*/ */
@ -360,9 +389,9 @@ void AutoConnect::handleRequest() {
_stopPortal(); _stopPortal();
_disconnectWiFi(true); _disconnectWiFi(true);
AC_DBG("Disconnected\n"); AC_DBG("Disconnected\n");
// Reset disconnection request, restore the menu title. // Reset disconnection request //, restore the menu title.
_rfDisconnect = false; _rfDisconnect = false;
_menuTitle = String(AUTOCONNECT_MENU_TITLE); // _menuTitle = String(AUTOCONNECT_MENU_TITLE);
if (_apConfig.autoReset) { if (_apConfig.autoReset) {
delay(1000); delay(1000);
@ -485,7 +514,6 @@ String AutoConnect::_induceReset(PageArgument& args) {
*/ */
String AutoConnect::_induceDisconnect(PageArgument& args) { String AutoConnect::_induceDisconnect(PageArgument& args) {
_rfDisconnect = true; _rfDisconnect = true;
_menuTitle = String("Disconnect");
return ""; return "";
} }
@ -552,7 +580,7 @@ String AutoConnect::_invokeResult(PageArgument& args) {
* a part of the handling of http request originated from handleClient. * a part of the handling of http request originated from handleClient.
*/ */
bool AutoConnect::_classifyHandle(HTTPMethod method, String uri) { bool AutoConnect::_classifyHandle(HTTPMethod method, String uri) {
AC_DBG("%s%s\n", _webServer->hostHeader().c_str(), uri.c_str()); AC_DBG("Host:%s, URI:%s\n", _webServer->hostHeader().c_str(), uri.c_str());
if (uri == _uri) { if (uri == _uri) {
return true; // The response page already exists. return true; // The response page already exists.
} }
@ -567,6 +595,12 @@ bool AutoConnect::_classifyHandle(HTTPMethod method, String uri) {
if ((_currentPageElement = _setupPage(uri)) != nullptr) { if ((_currentPageElement = _setupPage(uri)) != nullptr) {
_uri = String(uri); _uri = String(uri);
_responsePage->addElement(*_currentPageElement); _responsePage->addElement(*_currentPageElement);
} else if (_aux) {
// Requested URL is not a normal page, exploring AUX pages
if ((_currentPageElement = _aux->_setupPage(uri)) != nullptr) {
_uri = String(uri);
_responsePage->addElement(*_currentPageElement);
}
} }
_responsePage->setUri(_uri.c_str()); _responsePage->setUri(_uri.c_str());
AC_DBG("Page[%s] allocated\n", _responsePage->uri()); AC_DBG("Page[%s] allocated\n", _responsePage->uri());

@ -2,8 +2,8 @@
* Declaration of AutoConnect class and accompanying AutoConnectConfig class. * Declaration of AutoConnect class and accompanying AutoConnectConfig class.
* @file AutoConnect.h * @file AutoConnect.h
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 0.9.5 * @version 0.9.7
* @date 2018-08-27 * @date 2018-11-17
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -30,6 +30,7 @@ using WebServerClass = WebServer;
#include <PageBuilder.h> #include <PageBuilder.h>
#include "AutoConnectPage.h" #include "AutoConnectPage.h"
#include "AutoConnectCredential.h" #include "AutoConnectCredential.h"
#include "AutoConnectAux.h"
// Uncomment the following AC_DEBUG to enable debug output. // Uncomment the following AC_DEBUG to enable debug output.
#define AC_DEBUG #define AC_DEBUG
@ -207,6 +208,8 @@ class AutoConnectConfig {
IPAddress dns2; /**< Secondary DNS server */ IPAddress dns2; /**< Secondary DNS server */
}; };
class AutoConnectAux;
class AutoConnect { class AutoConnect {
public: public:
AutoConnect(); AutoConnect();
@ -221,6 +224,8 @@ class AutoConnect {
void handleClient(); void handleClient();
void handleRequest(); void handleRequest();
WebServerClass& host(); WebServerClass& host();
void join(AutoConnectAux& aux);
void join(std::vector<std::reference_wrapper<AutoConnectAux>> aux);
typedef std::function<bool(IPAddress)> DetectExit_ft; typedef std::function<bool(IPAddress)> DetectExit_ft;
void onDetect(DetectExit_ft fn); void onDetect(DetectExit_ft fn);
@ -262,14 +267,23 @@ class AutoConnect {
DetectExit_ft _onDetectExit; DetectExit_ft _onDetectExit;
WebServerClass::THandlerFunction _notFoundHandler; WebServerClass::THandlerFunction _notFoundHandler;
/** Servers which works in concert. */
std::unique_ptr<WebServerClass> _webServer; std::unique_ptr<WebServerClass> _webServer;
std::unique_ptr<DNSServer> _dnsServer; std::unique_ptr<DNSServer> _dnsServer;
AC_WEBSERVER_TYPE _webServerAlloc; AC_WEBSERVER_TYPE _webServerAlloc;
/**
* Dynamically hold one page of AutoConnect menu.
* Every time a GET/POST HTTP request occurs, an AutoConnect
* menu page corresponding to the URI is generated.
*/
PageBuilder* _responsePage; PageBuilder* _responsePage;
PageElement* _currentPageElement; PageElement* _currentPageElement;
/** configurations */ /** Extended pages made up with AutoConnectAux */
std::unique_ptr<AutoConnectAux> _aux;
/** Saved configurations */
AutoConnectConfig _apConfig; AutoConnectConfig _apConfig;
struct station_config _credential; struct station_config _credential;
uint8_t _hiddenSSIDCount; uint8_t _hiddenSSIDCount;
@ -280,10 +294,11 @@ class AutoConnect {
bool _rfDisconnect; /**< URI /disc requested */ bool _rfDisconnect; /**< URI /disc requested */
bool _rfReset; /**< URI /reset requested */ bool _rfReset; /**< URI /reset requested */
String _uri; /** HTTP header information of the currently requested page. */
String _redirectURI; String _uri; /**< Requested URI */
IPAddress _currentHostIP; String _redirectURI; /**< Redirect destination */
String _menuTitle; IPAddress _currentHostIP; /**< host IP address */
String _menuTitle; /**< Title string of the page */
/** PegeElements of AutoConnect site. */ /** PegeElements of AutoConnect site. */
static const char _CSS_BASE[] PROGMEM; static const char _CSS_BASE[] PROGMEM;
@ -294,7 +309,9 @@ class AutoConnect {
static const char _CSS_TABLE[] PROGMEM; static const char _CSS_TABLE[] PROGMEM;
static const char _CSS_LUXBAR[] PROGMEM; static const char _CSS_LUXBAR[] PROGMEM;
static const char _ELM_HTML_HEAD[] PROGMEM; static const char _ELM_HTML_HEAD[] PROGMEM;
static const char _ELM_MENU[] PROGMEM; static const char _ELM_MENU_PRE[] PROGMEM;
static const char _ELM_MENU_AUX[] PROGMEM;
static const char _ELM_MENU_POST[] PROGMEM;
static const char _PAGE_STAT[] PROGMEM; static const char _PAGE_STAT[] PROGMEM;
static const char _PAGE_CONFIGNEW[] PROGMEM; static const char _PAGE_CONFIGNEW[] PROGMEM;
static const char _PAGE_OPENCREDT[] PROGMEM; static const char _PAGE_OPENCREDT[] PROGMEM;
@ -313,7 +330,9 @@ class AutoConnect {
String _token_CSS_TABLE(PageArgument& args); String _token_CSS_TABLE(PageArgument& args);
String _token_CSS_LUXBAR(PageArgument& args); String _token_CSS_LUXBAR(PageArgument& args);
String _token_HEAD(PageArgument& args); String _token_HEAD(PageArgument& args);
String _token_MENU(PageArgument& args); String _token_MENU_PRE(PageArgument& args);
String _token_MENU_AUX(PageArgument& args);
String _token_MENU_POST(PageArgument& args);
String _token_ESTAB_SSID(PageArgument& args); String _token_ESTAB_SSID(PageArgument& args);
String _token_WIFI_MODE(PageArgument& args); String _token_WIFI_MODE(PageArgument& args);
String _token_WIFI_STATUS(PageArgument& args); String _token_WIFI_STATUS(PageArgument& args);
@ -340,6 +359,7 @@ class AutoConnect {
#elif defined(ARDUINO_ARCH_ESP32) #elif defined(ARDUINO_ARCH_ESP32)
friend class WebServer; friend class WebServer;
#endif #endif
friend class AutoConnectAux;
}; };
#endif // _AUTOCONNECT_H_ #endif // _AUTOCONNECT_H_

@ -0,0 +1,135 @@
/**
* Implementation of AutoConnectAux class and subordinated AutoConnectElement class.
* @file AutoConnectAux.cpp
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#include "AutoConnect.h"
#include "AutoConnectAux.h"
const char AutoConnectAux::_PAGE_AUX[] PROGMEM = {
"{{HEAD}}"
"<title>{{AUX_TITLE}}</title>"
"<style type=\"text/css\">"
"{{CSS_BASE}}"
"{{CSS_UL}}"
"{{CSS_INPUT_BUTTON}}"
"{{CSS_INPUT_TEXT}}"
"{{CSS_LUXBAR}}"
"</style>"
"</head>"
"<body style=\"padding-top:58px;\">"
"<div class=\"container\">"
"{{MENU_PRE}}"
"{{MENU_AUX}}"
"{{MENU_POST}}"
"<div class=\"base-panel\">"
"<form id='_aux' method=\"post\">"
"<ul class=\"noorder\">"
"{{AUX_ELEMENT}}"
"</ul>"
"</form>"
"</div>"
"</div>"
"<script>"
"function sa(url) {"
"document.getElementById('_aux').action=url;"
"document.getElementIyId('_aux').submit();"
"}"
"</script>"
"</body>"
"</html>"
};
/**
* Destructs container of AutoConnectElement and release a unique
* pointer of AutoConnect instance.
*/
AutoConnectAux::~AutoConnectAux() {
_addonElm.clear();
_addonElm.swap(_addonElm);
if (_ac)
_ac.release();
}
void AutoConnectAux::add(AutoConnectElement& addon) {
_addonElm.push_back(addon);
AC_DBG("ELM:%s placed\n", addon.name().c_str());
}
void AutoConnectAux::add(AutoConnectElementVT addons) {
for (std::size_t n = 0; n < addons.size(); n++)
add(addons[n]);
}
void AutoConnectAux::_append(AutoConnectAux& aux) {
if (_next) {
AutoConnectAux* next = _next.get();
next->_append(aux);
}
else
_next.reset(&aux);
}
void AutoConnectAux::_join(AutoConnect& ac) {
_ac.reset(&ac);
if (_next) {
AutoConnectAux *next = _next.get();
next->_join(ac);
}
}
const String AutoConnectAux::_insertElement(PageArgument& args) {
String body = String();
for (std::size_t n = 0; n < _addonElm.size(); n++) {
AutoConnectElement& addon = _addonElm[n];
body += addon.toHTML();
}
return body;
}
PageElement* AutoConnectAux::_setupPage(String uri) {
PageElement* elm = nullptr;
if (_ac) {
if (uri != String(_uri)) {
if (_next) {
elm = _next->_setupPage(uri);
}
} else {
AutoConnect* mother = _ac.get();
elm = new PageElement();
// Overwrite the default menu title
mother->_menuTitle = _title;
// Construct the auxiliary page
elm->setMold(_PAGE_AUX);
elm->addToken(PSTR("HEAD"), std::bind(&AutoConnect::_token_HEAD, mother, std::placeholders::_1));
elm->addToken(PSTR("AUX_TITLE"), std::bind(&AutoConnectAux::_injectTitle, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, mother, std::placeholders::_1));
elm->addToken(PSTR("CSS_UL"), std::bind(&AutoConnect::_token_CSS_UL, mother, std::placeholders::_1));
elm->addToken(PSTR("CSS_INPUT_BUTTON"), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, mother, std::placeholders::_1));
elm->addToken(PSTR("CSS_INPUT_TEXT"), std::bind(&AutoConnect::_token_CSS_INPUT_TEXT, mother, std::placeholders::_1));
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, mother, std::placeholders::_1));
elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, mother, std::placeholders::_1));
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, mother, std::placeholders::_1));
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, mother, std::placeholders::_1));
elm->addToken(PSTR("AUX_ELEMENT"), std::bind(&AutoConnectAux::_insertElement, this, std::placeholders::_1));
}
}
return elm;
}
const String AutoConnectAux::_injectMenu(PageArgument& args) {
String menuItem = String(FPSTR("<li class=\"luxbar-item\"><a href=\"")) + String(_uri) + String("\">") + _title + String(FPSTR("</a></li>"));
if (_next) {
AutoConnectAux* next = _next.get();
menuItem += next->_injectMenu(args);
}
return menuItem;
}

@ -0,0 +1,156 @@
/**
* Declaration of AutoConnectAux class and subordinated AutoConnectElement class.
* @file AutoConnectAux.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTAUX_H_
#define _AUTOCONNECTAUX_H_
#include <vector>
#include <memory>
#include <functional>
#include <PageBuilder.h>
class AutoConnect; // Reference to avoid circular
// Add-on element base class
class AutoConnectElement {
public:
explicit AutoConnectElement(const char* name = nullptr, const char* value = nullptr) : _name(String(name)), _value(String(value)) {}
virtual ~AutoConnectElement() {}
const String name(void) const { return _name; } /**< Element name */
const String value(void) const { return _value; } /**< Element value */
virtual const String toHTML(void) { return String(); }; /**< HTML code to be generated */
protected:
String _name;
String _value;
};
/**
* Text arrangement class, a part of AutoConnectAux element.
* @param
* @param name Text name string.
* @param value Text value string.
* @param style A string of style-code for decoration, optionally.
* An arrangement text would be placed with <div> contains. A string
* of style-codes are given for '<div style=>'.
*/
class AutoConnectText : public AutoConnectElement {
public:
explicit AutoConnectText(const char* name = nullptr, const char* value = nullptr, const char* style = nullptr) : AutoConnectElement(name, value), _style(String(style)) {}
~AutoConnectText() {}
const String style(void) const { return _style; } /**< A modify of HTML 'style' code */
const String toHTML(void) {
return String(FPSTR("<div style=\"")) + _style + String("\">") + _value + String(FPSTR("</div>"));
}
protected:
String _style;
};
/**
* Input-box arrangement class, a part of AutoConnectAux element.
* Place a optionally labeled input-box that can be added by user sketch.
* @param name Input-box name string.
* @param value Button value string.
* @param label A label string that follows Input-box, optionally.
* The label is placed in front of Input-box.
*/
class AutoConnectInput : public AutoConnectElement {
public:
explicit AutoConnectInput(const char* name = nullptr, const char* value = nullptr, const char* label = nullptr) : AutoConnectElement(name, value), _label(String(label)) {}
~AutoConnectInput() {}
const String label(void) const { return _label; }
const String toHTML(void) {
return _label + String(FPSTR("<input type=\"text\" name=\"")) + _name + String(FPSTR("\" value=\"")) + _value + String("\"><br>");
}
protected:
String _label;
};
/**
* Button arrangement class, a part of AutoConnectAux element.
* Placed a labeled button that can be added by user sketch.
* @param name Button name string.
* @param value Button value string.
* @param action A sting of action code, it contains a simple JavaScript code.
*/
class AutoConnectButton : public AutoConnectElement {
public:
explicit AutoConnectButton(const char* name = nullptr, const char* value = nullptr, const String action = String()) : AutoConnectElement(name, value), _action(action) {}
const String action(void) const { return _action; }
const String toHTML(void) {
return String(FPSTR("<button type=\"button\" name=\"")) + _name + String(FPSTR("\" value=\"")) + _value + String(FPSTR("\" onclick=\"")) + _action + String("\">") + _value + String(FPSTR("</button>"));
}
protected:
String _action;
};
/**
* Submit button arrangement class, a part of AutoConnectAux element.
* Place a submit button with a label that can be added by user sketch.
* With the button behavior, the values of the elements contained in
* the form would be sent using the post method.
* @param name Button name string.
* @param value Sending value string.
* @param uri Sending uri string.
*/
class AutoConnectSubmit : public AutoConnectElement {
public:
explicit AutoConnectSubmit(const char* name = nullptr, const char* value = nullptr, const char* uri = nullptr) : AutoConnectElement(name, value), _uri(String(uri)) {}
const String uri(void) const { return _uri; }
const String toHTML(void) {
return String(FPSTR("<button type=\"submit\" name=\"")) + _name + String(FPSTR("\" value=\"")) + _value + String(FPSTR("\" onclick=\"sa('")) + _uri + String("')\">") + _value + String(FPSTR("</button>"));
}
protected:
String _uri;
};
// Manage placed AutoConnectElement with a vector
typedef std::vector<std::reference_wrapper<AutoConnectElement>> AutoConnectElementVT;
/**
* A class that handles an auxiliary page with AutoConnectElement
* that placed on it by binding it to the AutoConnect menu.
* @param uri An uri string of this page.
* @param title A title string of this page.
* @param addons A set of AutoConnectElement vector.
*/
class AutoConnectAux : public PageBuilder {
public:
explicit AutoConnectAux(const char* uri = nullptr, const char* title = nullptr, const AutoConnectElementVT addons = AutoConnectElementVT()) :
_title(String(title)), _addonElm(addons) { setUri(uri); _next.release(); _ac.release(); }
~AutoConnectAux();
void add(AutoConnectElement& addon); /**< Add an element to the auxiliary page. */
void add(AutoConnectElementVT addons); /**< Add the element set to the auxiliary page. */
void setTitle(const char* title) { _title = String(title); } /**< Set a title of the auxiliary page. */
protected:
void _append(AutoConnectAux& aux);
void _join(AutoConnect& ac);
PageElement* _setupPage(String uri);
const String _insertElement(PageArgument& args);
const String _injectTitle(PageArgument& args) { return _title; }
const String _injectMenu(PageArgument& args);
String _title; /**< A title of the page */
AutoConnectElementVT _addonElm; /**< A vector set of AutoConnectElements placed on this auxiliary page */
std::unique_ptr<AutoConnectAux> _next; /**< Auxiliary pages chain list */
std::unique_ptr<AutoConnect> _ac; /**< Hosted AutoConnect instance */
static const char _PAGE_AUX[] PROGMEM; /**< Auxiliary page template */
// Protected members can be used from AutoConnect which handles AutoConnectAux pages.
friend class AutoConnect;
};
#endif // _AUTOCONNECTAUX_H_

@ -2,8 +2,8 @@
* AutoConnect portal site web page implementation. * AutoConnect portal site web page implementation.
* @file AutoConnectPage.h * @file AutoConnectPage.h
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 0.9.6 * @version 0.9.7
* @date 2018-09-27 * @date 2018-11-17
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -104,6 +104,10 @@ const char AutoConnect::_CSS_UL[] PROGMEM = {
"margin-right:10px;" "margin-right:10px;"
"text-align:right;" "text-align:right;"
"}" "}"
"ul.noorder>input[type=\"checkbox\"]{"
"-moz-appearance: checkbox;"
"-webkit-appearance: checkbox;"
"}"
}; };
/**< Image icon for inline expansion, the lock mark. */ /**< Image icon for inline expansion, the lock mark. */
@ -448,7 +452,7 @@ const char AutoConnect::_ELM_HTML_HEAD[] PROGMEM = {
}; };
/**< LuxBar menu element. */ /**< LuxBar menu element. */
const char AutoConnect::_ELM_MENU[] PROGMEM = { const char AutoConnect::_ELM_MENU_PRE[] PROGMEM = {
"<header id=\"luxbar\" class=\"luxbar-fixed\">" "<header id=\"luxbar\" class=\"luxbar-fixed\">"
"<input type=\"checkbox\" class=\"luxbar-checkbox\" id=\"luxbar-checkbox\"/>" "<input type=\"checkbox\" class=\"luxbar-checkbox\" id=\"luxbar-checkbox\"/>"
"<div class=\"luxbar-menu luxbar-menu-right luxbar-menu-material-bluegrey\">" "<div class=\"luxbar-menu luxbar-menu-right luxbar-menu-material-bluegrey\">"
@ -459,6 +463,13 @@ const char AutoConnect::_ELM_MENU[] PROGMEM = {
"</li>" "</li>"
"<li class=\"luxbar-item\"><a href=\"" AUTOCONNECT_URI_CONFIG "\">Configure new AP</a></li>" "<li class=\"luxbar-item\"><a href=\"" AUTOCONNECT_URI_CONFIG "\">Configure new AP</a></li>"
"<li class=\"luxbar-item\"><a href=\"" AUTOCONNECT_URI_OPEN "\">Open SSIDs</a></li>" "<li class=\"luxbar-item\"><a href=\"" AUTOCONNECT_URI_OPEN "\">Open SSIDs</a></li>"
};
const char AutoConnect::_ELM_MENU_AUX[] PROGMEM = {
"{{AUX_MENU}}"
};
const char AutoConnect::_ELM_MENU_POST[] PROGMEM = {
"<li class=\"luxbar-item\"><a href=\"" AUTOCONNECT_URI_DISCON "\">Disconnect</a></li>" "<li class=\"luxbar-item\"><a href=\"" AUTOCONNECT_URI_DISCON "\">Disconnect</a></li>"
"<li class=\"luxbar-item\" id=\"reset\"><a href=\"#rdlg\">Reset...</a></li>" "<li class=\"luxbar-item\" id=\"reset\"><a href=\"#rdlg\">Reset...</a></li>"
"<li class=\"luxbar-item\"><a href=\"HOME_URI\">HOME</a></li>" "<li class=\"luxbar-item\"><a href=\"HOME_URI\">HOME</a></li>"
@ -505,7 +516,9 @@ const char AutoConnect::_PAGE_STAT[] PROGMEM = {
"</head>" "</head>"
"<body style=\"padding-top:58px;\">" "<body style=\"padding-top:58px;\">"
"<div class=\"container\">" "<div class=\"container\">"
"{{MENU}}" "{{MENU_PRE}}"
"{{MENU_AUX}}"
"{{MENU_POST}}"
"<div>" "<div>"
"<table class=\"info\" style=\"border:none;\">" "<table class=\"info\" style=\"border:none;\">"
"<tbody>" "<tbody>"
@ -588,7 +601,9 @@ const char AutoConnect::_PAGE_CONFIGNEW[] PROGMEM = {
"</head>" "</head>"
"<body style=\"padding-top:58px;\">" "<body style=\"padding-top:58px;\">"
"<div class=\"container\">" "<div class=\"container\">"
"{{MENU}}" "{{MENU_PRE}}"
"{{MENU_AUX}}"
"{{MENU_POST}}"
"<div class=\"base-panel\">" "<div class=\"base-panel\">"
"<form action=\"" AUTOCONNECT_URI_CONNECT "\" method=\"post\">" "<form action=\"" AUTOCONNECT_URI_CONNECT "\" method=\"post\">"
"{{LIST_SSID}}" "{{LIST_SSID}}"
@ -624,7 +639,9 @@ const char AutoConnect::_PAGE_OPENCREDT[] PROGMEM = {
"</head>" "</head>"
"<body style=\"padding-top:58px;\">" "<body style=\"padding-top:58px;\">"
"<div class=\"container\">" "<div class=\"container\">"
"{{MENU}}" "{{MENU_PRE}}"
"{{MENU_AUX}}"
"{{MENU_POST}}"
"<div class=\"base-panel\">" "<div class=\"base-panel\">"
"<form action=\"" AUTOCONNECT_URI_CONNECT "\" method=\"post\">" "<form action=\"" AUTOCONNECT_URI_CONNECT "\" method=\"post\">"
"{{OPEN_SSID}}" "{{OPEN_SSID}}"
@ -647,7 +664,9 @@ const char AutoConnect::_PAGE_SUCCESS[] PROGMEM = {
"</head>" "</head>"
"<body style=\"padding-top:58px;\">" "<body style=\"padding-top:58px;\">"
"<div class=\"container\">" "<div class=\"container\">"
"{{MENU}}" "{{MENU_PRE}}"
"{{MENU_AUX}}"
"{{MENU_POST}}"
"<div>" "<div>"
"<table class=\"info\" style=\"border:none;\">" "<table class=\"info\" style=\"border:none;\">"
"<tbody>" "<tbody>"
@ -697,7 +716,9 @@ const char AutoConnect::_PAGE_FAIL[] PROGMEM = {
"</head>" "</head>"
"<body style=\"padding-top:58px;\">" "<body style=\"padding-top:58px;\">"
"<div class=\"container\">" "<div class=\"container\">"
"{{MENU}}" "{{MENU_PRE}}"
"{{MENU_AUX}}"
"{{MENU_POST}}"
"<div>" "<div>"
"<table class=\"info\" style=\"border:none;\">" "<table class=\"info\" style=\"border:none;\">"
"<tbody>" "<tbody>"
@ -775,13 +796,26 @@ String AutoConnect::_token_HEAD(PageArgument& args) {
return String(_ELM_HTML_HEAD); return String(_ELM_HTML_HEAD);
} }
String AutoConnect::_token_MENU(PageArgument& args) { String AutoConnect::_token_MENU_PRE(PageArgument& args) {
String currentMenu = String(_ELM_MENU); String currentMenu = String(_ELM_MENU_PRE);
currentMenu.replace(String("MENU_TITLE"), _menuTitle); currentMenu.replace(String("MENU_TITLE"), _menuTitle);
currentMenu.replace(String("HOME_URI"), _apConfig.homeUri); currentMenu.replace(String("HOME_URI"), _apConfig.homeUri);
return currentMenu; return currentMenu;
} }
String AutoConnect::_token_MENU_AUX(PageArgument& args) {
String menuItem;
if (_aux) {
AutoConnectAux* aux = _aux.get();
menuItem = aux->_injectMenu(args);
}
return menuItem;
}
String AutoConnect::_token_MENU_POST(PageArgument& args) {
return String(FPSTR(_ELM_MENU_POST));
}
String AutoConnect::_token_CSS_LUXBAR(PageArgument& args) { String AutoConnect::_token_CSS_LUXBAR(PageArgument& args) {
return String(_CSS_LUXBAR); return String(_CSS_LUXBAR);
} }
@ -819,11 +853,9 @@ String AutoConnect::_token_WIFI_STATUS(PageArgument& args) {
} }
String AutoConnect::_token_STATION_STATUS(PageArgument& args) { String AutoConnect::_token_STATION_STATUS(PageArgument& args) {
uint8_t st;
const char* wlStatusSymbol; const char* wlStatusSymbol;
#if defined(ARDUINO_ARCH_ESP8266)
static const char *wlStatusSymbols[] = { static const char *wlStatusSymbols[] = {
#if defined(ARDUINO_ARCH_ESP8266)
"IDLE", "IDLE",
"CONNECTING", "CONNECTING",
"WRONG_PASSWORD", "WRONG_PASSWORD",
@ -831,7 +863,7 @@ String AutoConnect::_token_STATION_STATUS(PageArgument& args) {
"CONNECT_FAIL", "CONNECT_FAIL",
"GOT_IP" "GOT_IP"
}; };
st = wifi_station_get_connect_status(); uint8_t st = wifi_station_get_connect_status();
switch (st) { switch (st) {
case STATION_IDLE: case STATION_IDLE:
wlStatusSymbol = wlStatusSymbols[0]; wlStatusSymbol = wlStatusSymbols[0];
@ -851,19 +883,17 @@ String AutoConnect::_token_STATION_STATUS(PageArgument& args) {
case STATION_GOT_IP: case STATION_GOT_IP:
wlStatusSymbol = wlStatusSymbols[5]; wlStatusSymbol = wlStatusSymbols[5];
break; break;
}
#elif defined(ARDUINO_ARCH_ESP32) #elif defined(ARDUINO_ARCH_ESP32)
static const char *wlStatusSymbols[] = {
"IDLE", "IDLE",
"NO_SSID_AVAIL", "NO_SSID_AVAIL",
"SCAN_COMPLETED", "SCAN_COMPLETED",
"CONNECTED", "CONNECTED",
"CONNECT_FAILED", "CONNECT_FAILED",
"CONNECTION_LOST", "CONNECTION_LOST",
"DISCONNECTED" "DISCONNECTED",
"NO_SHIELD"
}; };
st = WiFi.status(); wl_status_t st = WiFi.status();
switch (st) { switch (st) {
case WL_IDLE_STATUS: case WL_IDLE_STATUS:
wlStatusSymbol = wlStatusSymbols[0]; wlStatusSymbol = wlStatusSymbols[0];
@ -886,9 +916,10 @@ String AutoConnect::_token_STATION_STATUS(PageArgument& args) {
case WL_DISCONNECTED: case WL_DISCONNECTED:
wlStatusSymbol = wlStatusSymbols[6]; wlStatusSymbol = wlStatusSymbols[6];
break; break;
} default:
wlStatusSymbol = wlStatusSymbols[7];
#endif #endif
}
return "(" + String(st) + ") " + String(wlStatusSymbol); return "(" + String(st) + ") " + String(wlStatusSymbol);
} }
@ -1016,6 +1047,9 @@ String AutoConnect::_token_UPTIME(PageArgument& args) {
PageElement* AutoConnect::_setupPage(String uri) { PageElement* AutoConnect::_setupPage(String uri) {
PageElement *elm = new PageElement(); PageElement *elm = new PageElement();
// Restore menu title
_menuTitle = String(AUTOCONNECT_MENU_TITLE);
// Build the elements of current requested page. // Build the elements of current requested page.
if (uri == String(AUTOCONNECT_URI)) { if (uri == String(AUTOCONNECT_URI)) {
@ -1025,7 +1059,9 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_TABLE"), std::bind(&AutoConnect::_token_CSS_TABLE, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_TABLE"), std::bind(&AutoConnect::_token_CSS_TABLE, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1));
elm->addToken(PSTR("MENU"), std::bind(&AutoConnect::_token_MENU, this, std::placeholders::_1)); elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
elm->addToken(PSTR("ESTAB_SSID"), std::bind(&AutoConnect::_token_ESTAB_SSID, this, std::placeholders::_1)); elm->addToken(PSTR("ESTAB_SSID"), std::bind(&AutoConnect::_token_ESTAB_SSID, this, std::placeholders::_1));
elm->addToken(PSTR("WIFI_MODE"), std::bind(&AutoConnect::_token_WIFI_MODE, this, std::placeholders::_1)); elm->addToken(PSTR("WIFI_MODE"), std::bind(&AutoConnect::_token_WIFI_MODE, this, std::placeholders::_1));
elm->addToken(PSTR("WIFI_STATUS"), std::bind(&AutoConnect::_token_WIFI_STATUS, this, std::placeholders::_1)); elm->addToken(PSTR("WIFI_STATUS"), std::bind(&AutoConnect::_token_WIFI_STATUS, this, std::placeholders::_1));
@ -1053,7 +1089,9 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(PSTR("CSS_INPUT_BUTTON"), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_INPUT_BUTTON"), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_INPUT_TEXT"), std::bind(&AutoConnect::_token_CSS_INPUT_TEXT, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_INPUT_TEXT"), std::bind(&AutoConnect::_token_CSS_INPUT_TEXT, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1));
elm->addToken(PSTR("MENU"), std::bind(&AutoConnect::_token_MENU, this, std::placeholders::_1)); elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
elm->addToken(PSTR("LIST_SSID"), std::bind(&AutoConnect::_token_LIST_SSID, this, std::placeholders::_1)); elm->addToken(PSTR("LIST_SSID"), std::bind(&AutoConnect::_token_LIST_SSID, this, std::placeholders::_1));
elm->addToken(PSTR("HIDDEN_COUNT"), std::bind(&AutoConnect::_token_HIDDEN_COUNT, this, std::placeholders::_1)); elm->addToken(PSTR("HIDDEN_COUNT"), std::bind(&AutoConnect::_token_HIDDEN_COUNT, this, std::placeholders::_1));
} }
@ -1072,18 +1110,23 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(PSTR("CSS_ICON_LOCK"), std::bind(&AutoConnect::_token_CSS_ICON_LOCK, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_ICON_LOCK"), std::bind(&AutoConnect::_token_CSS_ICON_LOCK, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_INPUT_BUTTON"), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_INPUT_BUTTON"), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1));
elm->addToken(PSTR("MENU"), std::bind(&AutoConnect::_token_MENU, this, std::placeholders::_1)); elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
elm->addToken(PSTR("OPEN_SSID"), std::bind(&AutoConnect::_token_OPEN_SSID, this, std::placeholders::_1)); elm->addToken(PSTR("OPEN_SSID"), std::bind(&AutoConnect::_token_OPEN_SSID, this, std::placeholders::_1));
} }
else if (uri == String(AUTOCONNECT_URI_DISCON)) { else if (uri == String(AUTOCONNECT_URI_DISCON)) {
// Setup /auto/disc // Setup /auto/disc
_menuTitle = String("Disconnect");
elm->setMold(_PAGE_DISCONN); elm->setMold(_PAGE_DISCONN);
elm->addToken(PSTR("DISCONNECT"), std::bind(&AutoConnect::_induceDisconnect, this, std::placeholders::_1)); elm->addToken(PSTR("DISCONNECT"), std::bind(&AutoConnect::_induceDisconnect, this, std::placeholders::_1));
elm->addToken(PSTR("HEAD"), std::bind(&AutoConnect::_token_HEAD, this, std::placeholders::_1)); elm->addToken(PSTR("HEAD"), std::bind(&AutoConnect::_token_HEAD, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1));
elm->addToken(PSTR("MENU"), std::bind(&AutoConnect::_token_MENU, this, std::placeholders::_1)); elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
} }
else if (uri == String(AUTOCONNECT_URI_RESET)) { else if (uri == String(AUTOCONNECT_URI_RESET)) {
@ -1108,7 +1151,9 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_TABLE"), std::bind(&AutoConnect::_token_CSS_TABLE, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_TABLE"), std::bind(&AutoConnect::_token_CSS_TABLE, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1));
elm->addToken(PSTR("MENU"), std::bind(&AutoConnect::_token_MENU, this, std::placeholders::_1)); elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
elm->addToken(PSTR("ESTAB_SSID"), std::bind(&AutoConnect::_token_ESTAB_SSID, this, std::placeholders::_1)); elm->addToken(PSTR("ESTAB_SSID"), std::bind(&AutoConnect::_token_ESTAB_SSID, this, std::placeholders::_1));
elm->addToken(PSTR("WIFI_MODE"), std::bind(&AutoConnect::_token_WIFI_MODE, this, std::placeholders::_1)); elm->addToken(PSTR("WIFI_MODE"), std::bind(&AutoConnect::_token_WIFI_MODE, this, std::placeholders::_1));
elm->addToken(PSTR("WIFI_STATUS"), std::bind(&AutoConnect::_token_WIFI_STATUS, this, std::placeholders::_1)); elm->addToken(PSTR("WIFI_STATUS"), std::bind(&AutoConnect::_token_WIFI_STATUS, this, std::placeholders::_1));
@ -1126,7 +1171,9 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_TABLE"), std::bind(&AutoConnect::_token_CSS_TABLE, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_TABLE"), std::bind(&AutoConnect::_token_CSS_TABLE, this, std::placeholders::_1));
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1));
elm->addToken(PSTR("MENU"), std::bind(&AutoConnect::_token_MENU, this, std::placeholders::_1)); elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, this, std::placeholders::_1));
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
elm->addToken(PSTR("STATION_STATUS"), std::bind(&AutoConnect::_token_STATION_STATUS, this, std::placeholders::_1)); elm->addToken(PSTR("STATION_STATUS"), std::bind(&AutoConnect::_token_STATION_STATUS, this, std::placeholders::_1));
} }
else { else {

Loading…
Cancel
Save