You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
AutoConnect/src/AutoConnect.h

303 lines
9.3 KiB

/**
* Declaration of AutoConnect class and accompanying AutoConnectConfig class.
* @file AutoConnect.h
* @author hieromon@gmail.com
* @version 0.9.1
* @date 2018-02-13
* @copyright MIT license.
*/
#ifndef _AUTOCONNECT_H_
#define _AUTOCONNECT_H_
#include <vector>
#include <memory>
#include <functional>
#include <DNSServer.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
#include <PageBuilder.h>
extern "C" {
#include <user_interface.h>
}
#include "AutoConnectPage.h"
#include "AutoConnectCredential.h"
// Uncomment the following AC_DEBUG to enable debug output.
//#define AC_DEBUG
// Debug output destination can be defined externally with AC_DEBUG_PORT
#ifndef AC_DEBUG_PORT
#define AC_DEBUG_PORT Serial
#endif
#ifdef AC_DEBUG
#define AC_DBG(...) do {AC_DEBUG_PORT.print("[AC] "); AC_DEBUG_PORT.printf( __VA_ARGS__ );} while (0)
#else
#define AC_DBG(...)
#endif
#ifndef AUTOCONNECT_APID
#define AUTOCONNECT_APID "esp8266ap"
#endif
#ifndef AUTOCONNECT_PSK
#define AUTOCONNECT_PSK "12345678"
#endif
#ifndef AUTOCONNECT_AP_IP
#define AUTOCONNECT_AP_IP 0x01F4A8C0 //*< 192.168.244.1 */
#endif // !AUTOCONNECT_AP_IP
#ifndef AUTOCONNECT_AP_GW
#define AUTOCONNECT_AP_GW 0x01F4A8C0 //*< 192.168.244.1 */
#endif // !AUTOCONNECT_AP_GW
#ifndef AUTOCONNECT_AP_NM
#define AUTOCONNECT_AP_NM 0x00FFFFFF //*< 255.255.255.0 */
#endif // !AUTOCONNECT_AP_NM
#ifndef AUTOCONNECT_URI
#define AUTOCONNECT_URI "/_ac"
#endif
#ifndef AUTOCONNECT_HOMEURI
#define AUTOCONNECT_HOMEURI "/"
#endif
#ifndef AUTOCONNECT_MENU_TITLE
#define AUTOCONNECT_MENU_TITLE "AutoConnect"
#endif
#define AUTOCONNECT_MENU_TITLE_CONNETED "Connected"
#define AUTOCONNECT_URI_CONFIG AUTOCONNECT_URI "/config"
#define AUTOCONNECT_URI_CONNECT AUTOCONNECT_URI "/connect"
#define AUTOCONNECT_URI_RESULT AUTOCONNECT_URI "/result"
#define AUTOCONNECT_URI_OPEN AUTOCONNECT_URI "/open"
#define AUTOCONNECT_URI_DISCON AUTOCONNECT_URI "/disc"
#define AUTOCONNECT_URI_RESET AUTOCONNECT_URI "/reset"
#define AUTOCONNECT_URI_SUCCESS AUTOCONNECT_URI "/success"
#define AUTOCONNECT_URI_FAIL AUTOCONNECT_URI "/fail"
#ifndef AUTOCONNECT_TIMEOUT
#define AUTOCONNECT_TIMEOUT 30000
#endif
#ifndef AUTOCONNECT_STARTUPTIME
#define AUTOCONNECT_STARTUPTIME 10
#endif
#ifndef AUTOCONNECT_HTTPPORT
#define AUTOCONNECT_HTTPPORT 80
#endif
#ifndef AUTOCONNECT_DNSPORT
#define AUTOCONNECT_DNSPORT 53
#endif
/**< A type to save established credential at WiFi.begin automatically. */
typedef enum AC_SAVECREDENTIAL {
AC_SAVECREDENTIAL_NEVER,
AC_SAVECREDENTIAL_AUTO
} AC_SAVECREDENTIAL_t;
class AutoConnectConfig {
public:
/**
* AutoConnectConfig default constructor.
* SSID for the captive portal access point assumes AUTOCONNECT_APID which
* assigned from macro. Password is same as above too.
*/
AutoConnectConfig() :
apip(AUTOCONNECT_AP_IP),
gateway(AUTOCONNECT_AP_GW),
netmask(AUTOCONNECT_AP_NM),
apid(String(AUTOCONNECT_APID)),
psk(String(AUTOCONNECT_PSK)),
channel(1),
hidden(0),
autoSave(AC_SAVECREDENTIAL_AUTO),
boundaryOffset(AC_IDENTIFIER_OFFSET),
uptime(AUTOCONNECT_STARTUPTIME),
autoRise(true),
autoReset(true),
homeUri(AUTOCONNECT_HOMEURI) {}
/**
* Configure by SSID for the captive portal access point and password.
*/
AutoConnectConfig(const char* ap, const char* password) :
apip(AUTOCONNECT_AP_IP),
gateway(AUTOCONNECT_AP_GW),
netmask(AUTOCONNECT_AP_NM),
apid(String(ap)),
psk(String(password)),
channel(1),
hidden(0),
autoSave(AC_SAVECREDENTIAL_AUTO),
boundaryOffset(AC_IDENTIFIER_OFFSET),
uptime(AUTOCONNECT_STARTUPTIME),
autoRise(true),
autoReset(true),
homeUri(AUTOCONNECT_HOMEURI) {}
~AutoConnectConfig() {}
AutoConnectConfig& operator=(const AutoConnectConfig& o) {
apip = o.apip;
gateway = o.gateway;
netmask = o.netmask;
apid = o.apid;
psk = o.psk;
channel = o.channel;
hidden = o.hidden;
autoSave = o.autoSave;
boundaryOffset = o.boundaryOffset;
uptime = o.uptime;
autoRise = o.autoRise;
autoReset = o.autoReset;
homeUri = o.homeUri;
return *this;
}
IPAddress apip; /**< SoftAP IP address */
IPAddress gateway; /**< SoftAP gateway address */
IPAddress netmask; /**< SoftAP subnet mask */
String apid; /**< SoftAP SSID */
String psk; /**< SoftAP password */
uint8_t channel; /**< SoftAP used wifi channel */
uint8_t hidden; /**< SoftAP SSID hidden */
AC_SAVECREDENTIAL_t autoSave; /**< Auto save credential */
uint16_t boundaryOffset; /**< The save storage offset of EEPROM */
int uptime; /**< Length of start up time */
bool autoRise; /**< Automatic starting the captive portal */
bool autoReset; /**< Reset ESP8266 module automatically when WLAN disconnected. */
String homeUri; /**< A URI of user site */
};
class AutoConnect {
public:
AutoConnect();
AutoConnect(ESP8266WebServer& webServer);
~AutoConnect();
bool config(AutoConnectConfig& Config);
bool config(const char* ap, const char* password = nullptr);
void home(String uri);
bool begin();
bool begin(const char* ssid, const char* passphrase);
bool begin(const char* ssid, const char* passphrase, unsigned long timeout);
void end();
void handleClient();
void handleRequest();
ESP8266WebServer& host();
typedef std::function<bool(IPAddress)> DetectExit_ft;
void onDetect(DetectExit_ft fn);
void onNotFound(ESP8266WebServer::THandlerFunction fn);
protected:
enum _webServerAllocateType {
AC_WEBSERVER_PARASITIC,
AC_WEBSERVER_HOSTED
};
typedef enum _webServerAllocateType AC_WEBSERVER_TYPE;
void _initialize();
bool _config();
void _startWebServer();
void _startDNSServer();
void _handleNotFound();
void _stopPortal();
bool _classifyHandle(HTTPMethod mothod, String uri);
PageElement* _setupPage(String uri);
/** Request handlers implemented by Page Builder */
String _induceConnect(PageArgument& args);
String _induceDisconnect(PageArgument& args);
String _induceReset(PageArgument& args);
String _invokeResult(PageArgument& args);
/** For portal control */
bool _captivePortal();
bool _isIP(String ipStr);
wl_status_t _waitForConnect(unsigned long timeout);
/** Utilities */
static String _toMACAddressString(const uint8_t mac[]);
static unsigned int _toWiFiQuality(int32_t rssi);
DetectExit_ft _onDetectExit;
ESP8266WebServer::THandlerFunction _notFoundHandler;
std::unique_ptr<ESP8266WebServer> _webServer;
std::unique_ptr<DNSServer> _dnsServer;
AC_WEBSERVER_TYPE _webServerAlloc;
PageBuilder* _responsePage;
PageElement* _currentPageElement;
/** configurations */
AutoConnectConfig _apConfig;
struct station_config _credential;
uint8_t _hiddenSSIDCount;
unsigned long _portalTimeout;
/** The control indicators */
bool _rfConnect; /**< URI /connect requested */
bool _rfDisconnect; /**< URI /disc requested */
bool _rfReset; /**< URI /reset requested */
String _uri;
String _redirectURI;
IPAddress _currentHostIP;
String _menuTitle;
/** PegeElements of AutoConnect site. */
static const char _CSS_BASE[] PROGMEM;
static const char _CSS_UL[] PROGMEM;
static const char _CSS_ICON_LOCK[] PROGMEM;
static const char _CSS_INPUT_BUTTON[] PROGMEM;
static const char _CSS_INPUT_TEXT[] PROGMEM;
static const char _CSS_TABLE[] PROGMEM;
static const char _CSS_LUXBAR[] PROGMEM;
static const char _ELM_HTML_HEAD[] PROGMEM;
static const char _ELM_MENU[] PROGMEM;
static const char _PAGE_STAT[] PROGMEM;
static const char _PAGE_CONFIGNEW[] PROGMEM;
static const char _PAGE_OPENCREDT[] PROGMEM;
static const char _PAGE_SUCCESS[] PROGMEM;
static const char _PAGE_RESETTING[] PROGMEM;
static const char _PAGE_DISCONN[] PROGMEM;
static const char _PAGE_FAIL[] PROGMEM;
static const char _PAGE_404[] PROGMEM;
/** Token handlers for PageBuilder */
String _token_CSS_BASE(PageArgument& args);
String _token_CSS_UL(PageArgument& args);
String _token_CSS_ICON_LOCK(PageArgument& args);
String _token_CSS_INPUT_BUTTON(PageArgument& args);
String _token_CSS_INPUT_TEXT(PageArgument& args);
String _token_CSS_TABLE(PageArgument& args);
String _token_CSS_LUXBAR(PageArgument& args);
String _token_HEAD(PageArgument& args);
String _token_MENU(PageArgument& args);
String _token_ESTAB_SSID(PageArgument& args);
String _token_WIFI_MODE(PageArgument& args);
String _token_WIFI_STATUS(PageArgument& args);
String _token_STATION_STATUS(PageArgument& args);
String _token_LOCAL_IP(PageArgument& args);
String _token_SOFTAP_IP(PageArgument& args);
String _token_GATEWAY(PageArgument& args);
String _token_NETMASK(PageArgument& args);
String _token_AP_MAC(PageArgument& args);
String _token_STA_MAC(PageArgument& args);
String _token_CHANNEL(PageArgument& args);
String _token_DBM(PageArgument& args);
String _token_CPU_FREQ(PageArgument& args);
String _token_FLASH_SIZE(PageArgument& args);
String _token_CHIP_ID(PageArgument& args);
String _token_FREE_HEAP(PageArgument& args);
String _token_LIST_SSID(PageArgument& args);
String _token_HIDDEN_COUNT(PageArgument& args);
String _token_OPEN_SSID(PageArgument& args);
String _token_UPTIME(PageArgument& args);
friend class ESP8266WebServer;
};
#endif // _AUTOCONNECT_H_