| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 | /** * WiFiManager.h *  * WiFiManager, a library for the ESP8266/Arduino platform * for configuration of WiFi credentials using a Captive Portal *  * @author Creator tzapu * @author tablatronix * @version 0.0.0 * @license MIT */#ifndef WiFiManager_h#define WiFiManager_h#if defined(ESP8266) || defined(ESP32)#ifdef ESP8266#include <core_version.h>#endif#include <vector>// #define WM_MDNS            // also set MDNS with sethostname// #define WM_FIXERASECONFIG  // use erase flash fix// #define WM_ERASE_NVS       // esp32 erase(true) will erase NVS // #define WM_RTC             // esp32 info page will include reset reasons#ifdef ARDUINO_ESP8266_RELEASE_2_3_0#warning "ARDUINO_ESP8266_RELEASE_2_3_0, some WM features disabled" #define WM_NOASYNC         // esp8266 no async scan wifi#endif// #include "soc/efuse_reg.h" // include to add efuse chip rev to info, getChipRevision() is almost always the same though, so not sure why it matters.// #define esp32autoreconnect    // implement esp32 autoreconnect event listener kludge, @DEPRECATED// autoreconnect is WORKING https://github.com/espressif/arduino-esp32/issues/653#issuecomment-405604766#define WM_WEBSERVERSHIM      // use webserver shim lib#ifdef ESP8266    extern "C" {      #include "user_interface.h"    }    #include <ESP8266WiFi.h>    #include <ESP8266WebServer.h>    #ifdef WM_MDNS        #include <ESP8266mDNS.h>    #endif    #define WIFI_getChipId() ESP.getChipId()    #define WM_WIFIOPEN   ENC_TYPE_NONE#elif defined(ESP32)    #include <WiFi.h>    #include <esp_wifi.h>          #define WIFI_getChipId() (uint32_t)ESP.getEfuseMac()    #define WM_WIFIOPEN   WIFI_AUTH_OPEN    #ifndef WEBSERVER_H        #ifdef WM_WEBSERVERSHIM            #include <WebServer.h>        #else            #include <ESP8266WebServer.h>            // Forthcoming official ?            // https://github.com/esp8266/ESPWebServer        #endif    #endif    #ifdef WM_ERASE_NVS       #include <nvs.h>       #include <nvs_flash.h>    #endif    #ifdef WM_MDNS        #include <ESPmDNS.h>    #endif    #ifdef WM_RTC        #include <rom/rtc.h>    #endif#else#endif#include <DNSServer.h>#include <memory>#include "strings_en.h"#ifndef WIFI_MANAGER_MAX_PARAMS    #define WIFI_MANAGER_MAX_PARAMS 5 // params will autoincrement and realloc by this amount when max is reached#endif#define WFM_LABEL_BEFORE 1#define WFM_LABEL_AFTER 2#define WFM_NO_LABEL 0class WiFiManagerParameter {  public:    /**         Create custom parameters that can be added to the WiFiManager setup web page        @id is used for HTTP queries and must not contain spaces nor other special characters    */    WiFiManagerParameter();    WiFiManagerParameter(const char *custom);    WiFiManagerParameter(const char *id, const char *label);    WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length);    WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom);    WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement);    ~WiFiManagerParameter();    const char *getID();    const char *getValue();    const char *getLabel();    const char *getPlaceholder(); // @deprecated, use getLabel    int         getValueLength();    int         getLabelPlacement();    const char *getCustomHTML();    void        setValue(const char *defaultValue, int length);  protected:    void init(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement);  private:    const char *_id;    const char *_label;    char       *_value;    int         _length;    int         _labelPlacement;    const char *_customHTML;    friend class WiFiManager;};class WiFiManager{  public:    WiFiManager(Stream& consolePort);    WiFiManager();    ~WiFiManager();    void WiFiManagerInit();    // auto connect to saved wifi, or custom, and start config portal on failures    boolean       autoConnect();    boolean       autoConnect(char const *apName, char const *apPassword = NULL);    //manually start the config portal, autoconnect does this automatically on connect failure    boolean       startConfigPortal(); // auto generates apname    boolean       startConfigPortal(char const *apName, char const *apPassword = NULL);    //manually stop the config portal if started manually, stop immediatly if non blocking, flag abort if blocking    bool          stopConfigPortal();        //manually start the web portal, autoconnect does this automatically on connect failure        void          startWebPortal();    //manually stop the web portal if started manually    void          stopWebPortal();    // Run webserver processing, if setConfigPortalBlocking(false)    boolean       process();    // get the AP name of the config portal, so it can be used in the callback    String        getConfigPortalSSID();    int           getRSSIasQuality(int RSSI);    // erase wifi credentials    void          resetSettings();    // reboot esp    void          reboot();    // disconnect wifi, without persistent saving or erasing    bool          disconnect();    // erase esp    bool          erase();    bool          erase(bool opt);    //adds a custom parameter, returns false on failure    bool          addParameter(WiFiManagerParameter *p);    //returns the list of Parameters    WiFiManagerParameter** getParameters();    // returns the Parameters Count    int           getParametersCount();    // SET CALLBACKS    //called after AP mode and config portal has started    void          setAPCallback( std::function<void(WiFiManager*)> func );    //called after webserver has started    void          setWebServerCallback( std::function<void()> func );    //called when settings reset have been triggered    void          setConfigResetCallback( std::function<void()> func );    //called when wifi settings have been changed and connection was successful ( or setBreakAfterConfig(true) )    void          setSaveConfigCallback( std::function<void()> func );    //called when settings have been changed and connection was successful    void          setSaveParamsCallback( std::function<void()> func );    //called when settings before have been changed and connection was successful    void          setPreSaveConfigCallback( std::function<void()> func );    //sets timeout before AP,webserver loop ends and exits even if there has been no setup.    //useful for devices that failed to connect at some point and got stuck in a webserver loop    //in seconds setConfigPortalTimeout is a new name for setTimeout, ! not used if setConfigPortalBlocking    void          setConfigPortalTimeout(unsigned long seconds);    void          setTimeout(unsigned long seconds); // @deprecated, alias    //sets timeout for which to attempt connecting, useful if you get a lot of failed connects    void          setConnectTimeout(unsigned long seconds);    //sets timeout for which to attempt connecting on saves, useful if there are bugs in esp waitforconnectloop    void          setSaveConnectTimeout(unsigned long seconds);    // toggle debug output    void          setDebugOutput(boolean debug);    //set min quality percentage to include in scan, defaults to 8% if not specified    void          setMinimumSignalQuality(int quality = 8);    //sets a custom ip /gateway /subnet configuration    void          setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn);    //sets config for a static IP    void          setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn);    //sets config for a static IP with DNS    void          setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns);    //if this is set, it will exit after config, even if connection is unsuccessful.    void          setBreakAfterConfig(boolean shouldBreak);    // if this is set, portal will be blocking and wait until save or exit,     // is false user must manually `process()` to handle config portal,    // setConfigPortalTimeout is ignored in this mode, user is responsible for closing configportal    void          setConfigPortalBlocking(boolean shouldBlock);    //if this is set, customise style    void          setCustomHeadElement(const char* element);    //if this is true, remove duplicated Access Points - defaut true    void          setRemoveDuplicateAPs(boolean removeDuplicates);    //setter for ESP wifi.persistent so we can remember it and restore user preference, as WIFi._persistent is protected    void          setRestorePersistent(boolean persistent);    //if true, always show static net inputs, IP, subnet, gateway, else only show if set via setSTAStaticIPConfig    void          setShowStaticFields(boolean alwaysShow);    //if true, always show static dns, esle only show if set via setSTAStaticIPConfig    void          setShowDnsFields(boolean alwaysShow);    // toggle showing the saved wifi password in wifi form, could be a security issue.    void          setShowPassword(boolean show);    //if false, disable captive portal redirection    void          setCaptivePortalEnable(boolean enabled);    //if false, timeout captive portal even if a STA client connected to softAP (false), suggest disabling if captiveportal is open    void          setAPClientCheck(boolean enabled);    //if true, reset timeout when webclient connects (true), suggest disabling if captiveportal is open        void          setWebPortalClientCheck(boolean enabled);    // if true, enable autoreconnecting    void          setWiFiAutoReconnect(boolean enabled);    // if true, wifiscan will show percentage instead of quality icons, until we have better templating    void          setScanDispPerc(boolean enabled);    // if true (default) then start the config portal from autoConnect if connection failed    void          setEnableConfigPortal(boolean enable);    // set a custom hostname, sets sta and ap dhcp client id for esp32, and sta for esp8266    bool          setHostname(const char * hostname);    // show erase wifi onfig button on info page, true    void          setShowInfoErase(boolean enabled);    // set ap channel    void          setWiFiAPChannel(int32_t channel);    // set ap hidden    void          setWiFiAPHidden(bool hidden); // default false    // clean connect, always disconnect before connecting    void          setCleanConnect(bool enable); // default false    // set custom menu    // set custom menu items and order    void          setMenu(std::vector<const char*>& menu);    void          setMenu(const char* menu[], uint8_t size);        // add params to its own menu page and remove from wifi, NOT TO BE COMBINED WITH setMenu!    void          setParamsPage(bool enable);    // get last connection result, includes autoconnect and wifisave    uint8_t       getLastConxResult();    // get a status as string    String        getWLStatusString(uint8_t status);        String        getModeString(uint8_t mode);    // check if the module has a saved ap to connect to    bool          getWiFiIsSaved();    // helper to get saved ssid, if persistent get stored, else get current if connected    String        getWiFiPass(bool persistent = false);    // helper to get saved password, if persistent get stored, else get current if connected    String        getWiFiSSID(bool persistent = false);    // debug output the softap config    void          debugSoftAPConfig();    // debug output platform info and versioning    void          debugPlatformInfo();    String        htmlEntities(String str);        // set the country code for wifi settings    void          setCountry(String cc);    // set body class (invert)    void          setClass(String str);    String        getDefaultAPName();        std::unique_ptr<DNSServer>        dnsServer;    #if defined(ESP32) && defined(WM_WEBSERVERSHIM)        using WM_WebServer = WebServer;    #else        using WM_WebServer = ESP8266WebServer;    #endif        std::unique_ptr<WM_WebServer> server;  private:    std::vector<uint8_t> _menuIds;    std::vector<const char *> _menuIdsParams  = {"wifi","param","info","exit"};    std::vector<const char *> _menuIdsDefault = {"wifi","info","exit"};    // ip configs @todo struct ?    IPAddress     _ap_static_ip;    IPAddress     _ap_static_gw;    IPAddress     _ap_static_sn;    IPAddress     _sta_static_ip;    IPAddress     _sta_static_gw;    IPAddress     _sta_static_sn;    IPAddress     _sta_static_dns;    // defaults    const byte    DNS_PORT                = 53;    const byte    HTTP_PORT               = 80;    String        _apName                 = "no-net";    String        _apPassword             = "";    String        _ssid                   = "";    String        _pass                   = "";        // options flags    unsigned long _configPortalTimeout    = 0; // ms close config portal loop if set (depending on  _cp/webClientCheck options)    unsigned long _connectTimeout         = 0; // ms stop trying to connect to ap if set    unsigned long _saveTimeout            = 0; // ms stop trying to connect to ap on saves, in case bugs in esp waitforconnectresult    unsigned long _configPortalStart      = 0; // ms config portal start time (updated for timeouts)    unsigned long _webPortalAccessed      = 0; // ms last web access time    WiFiMode_t    _usermode               = WIFI_OFF;    String        _wifissidprefix         = FPSTR(S_ssidpre); // auto apname prefix prefix+chipid    uint8_t       _lastconxresult         = WL_IDLE_STATUS;    int           _numNetworks            = 0;    unsigned long _lastscan               = 0; // ms for timing wifi scans    unsigned long _startscan              = 0; // ms for timing wifi scans    int           _cpclosedelay           = 2000; // delay before wifisave, prevents captive portal from closing to fast.    bool          _cleanConnect           = false; // disconnect before connect in connectwifi, increases stability on connects       bool          _disableSTA             = false; // disable sta when starting ap, always    bool          _disableSTAConn         = true;  // disable sta when starting ap, if sta is not connected ( stability )    bool          _channelSync            = false; // use same wifi sta channel when starting ap    int32_t       _apChannel              = 0; // channel to use for ap    bool          _apHidden               = false; // store softap hidden value    #ifdef ESP32    static uint8_t _lastconxresulttmp; // tmp var for esp32 callback    #endif    #ifndef WL_STATION_WRONG_PASSWORD    uint8_t WL_STATION_WRONG_PASSWORD     = 7; // @kludge define a WL status for wrong password    #endif    // parameter options    int           _minimumQuality         = -1;    // filter wifiscan ap by this rssi    int            _staShowStaticFields   = 0;     // ternary 1=always show static ip fields, 0=only if set, -1=never(cannot change ips via web!)    int            _staShowDns            = 0;     // ternary 1=always show dns, 0=only if set, -1=never(cannot change dns via web!)    boolean       _removeDuplicateAPs     = true;  // remove dup aps from wifiscan    boolean       _showPassword           = false; // show or hide saved password on wifi form, might be a security issue!    boolean       _shouldBreakAfterConfig = false; // stop configportal on save failure    boolean       _configPortalIsBlocking = true;  // configportal enters blocking loop     boolean       _enableCaptivePortal    = true;  // enable captive portal redirection    boolean       _userpersistent         = true;  // users preffered persistence to restore    boolean       _wifiAutoReconnect      = true;  // there is no platform getter for this, we must assume its true and make it so    boolean       _apClientCheck          = false; // keep cp alive if ap have station    boolean       _webClientCheck         = true;  // keep cp alive if web have client    boolean       _scanDispOptions        = false; // show percentage in scans not icons    boolean       _paramsInWifi           = true;  // show custom parameters on wifi page    boolean       _showInfoErase          = true;  // info page erase button    boolean       _enableConfigPortal     = true;  // use config portal if autoconnect failed    const char *  _hostname               = "";    const char*   _customHeadElement      = ""; // store custom head element html from user    String        _bodyClass              = ""; // class to add to body    // internal options    boolean       _preloadwifiscan        = true;  // preload wifiscan if true    boolean       _asyncScan              = false;    unsigned int  _scancachetime          = 30000; // ms cache time for background scans    boolean       _disableIpFields        = false; // modify function of setShow_X_Fields(false), forces ip fields off instead of default show if set, eg. _staShowStaticFields=-1    String        _wificountry            = "";  // country code, @todo define in strings lang    // wrapper functions for handling setting and unsetting persistent for now.    bool          esp32persistent         = false;    bool          _hasBegun               = false;    void          _begin();    void          _end();    void          setupConfigPortal();    bool          shutdownConfigPortal();#ifdef NO_EXTRA_4K_HEAP    boolean       _tryWPS                 = false; // try WPS on save failure, unsupported    void          startWPS();#endif    bool          startAP();    uint8_t       connectWifi(String ssid, String pass);    bool          setSTAConfig();    bool          wifiConnectDefault();    bool          wifiConnectNew(String ssid, String pass);    uint8_t       waitForConnectResult();    uint8_t       waitForConnectResult(uint16_t timeout);    void          updateConxResult(uint8_t status);    // webserver handlers    void          handleRoot();    void          handleWifi(boolean scan);    void          handleWifiSave();    void          handleInfo();    void          handleReset();    void          handleNotFound();    void          handleExit();    void          handleClose();    // void          handleErase();    void          handleErase(boolean opt);    void          handleParam();    void          handleWiFiStatus();    void          handleRequest();    void          handleParamSave();    void          doParamSave();    boolean       captivePortal();    boolean       configPortalHasTimeout();    uint8_t       processConfigPortal();    void          stopCaptivePortal();    // wifi platform abstractions    bool          WiFi_Mode(WiFiMode_t m);    bool          WiFi_Mode(WiFiMode_t m,bool persistent);    bool          WiFi_Disconnect();    bool          WiFi_enableSTA(bool enable);    bool          WiFi_enableSTA(bool enable,bool persistent);    bool          WiFi_eraseConfig();    uint8_t       WiFi_softap_num_stations();    bool          WiFi_hasAutoConnect();    void          WiFi_autoReconnect();    String        WiFi_SSID(bool persistent = false) const;    String        WiFi_psk(bool persistent = false) const;    bool          WiFi_scanNetworks();    bool          WiFi_scanNetworks(bool force,bool async);    bool          WiFi_scanNetworks(unsigned int cachetime,bool async);    bool          WiFi_scanNetworks(unsigned int cachetime);    void          WiFi_scanComplete(int networksFound);    bool          WiFiSetCountry();    #ifdef ESP32    void   WiFiEvent(WiFiEvent_t event, system_event_info_t info);    #endif    // output helpers    String        getParamOut();    String        getIpForm(String id, String title, String value);    String        getScanItemOut();    String        getStaticOut();    String        getHTTPHead(String title);    String        getMenuOut();    //helpers    boolean       isIp(String str);    String        toStringIp(IPAddress ip);    boolean       validApPassword();    String        encryptionTypeStr(uint8_t authmode);    void          reportStatus(String &page);    String        getInfoData(String id);    // flags    boolean       connect;    boolean       abort;    boolean       reset               = false;    boolean       configPortalActive  = false;    boolean       webPortalActive     = false;    boolean       portalTimeoutResult = false;    boolean       portalAbortResult   = false;    boolean       storeSTAmode        = true; // option store persistent STA mode in connectwifi     int           timer               = 0;        // WiFiManagerParameter    int         _paramsCount          = 0;    int         _max_params;    WiFiManagerParameter** _params    = NULL;    // debugging    typedef enum {        DEBUG_ERROR     = 0,        DEBUG_NOTIFY    = 1, // default stable        DEBUG_VERBOSE   = 2,        DEBUG_DEV       = 3, // default dev        DEBUG_MAX       = 4    } wm_debuglevel_t;    boolean _debug  = true;        // build debuglevel support    // @todo use DEBUG_ESP_x?    #ifdef WM_DEBUG_LEVEL    uint8_t _debugLevel = (uint8_t)WM_DEBUG_LEVEL;    #else     uint8_t _debugLevel = DEBUG_DEV; // default debug level    #endif    // @todo use DEBUG_ESP_PORT ?    #ifdef WM_DEBUG_PORT    Stream& _debugPort = WM_DEBUG_PORT;    #else    Stream& _debugPort = Serial; // debug output stream ref    #endif    template <typename Generic>    void        DEBUG_WM(Generic text);    template <typename Generic>    void        DEBUG_WM(wm_debuglevel_t level,Generic text);    template <typename Generic, typename Genericb>    void        DEBUG_WM(Generic text,Genericb textb);    template <typename Generic, typename Genericb>    void        DEBUG_WM(wm_debuglevel_t level, Generic text,Genericb textb);    // callbacks    // @todo use cb list (vector) maybe event ids, allow no return value    std::function<void(WiFiManager*)> _apcallback;    std::function<void()> _webservercallback;    std::function<void()> _savewificallback;    std::function<void()> _presavecallback;    std::function<void()> _saveparamscallback;    std::function<void()> _resetcallback;    template <class T>    auto optionalIPFromString(T *obj, const char *s) -> decltype(  obj->fromString(s)  ) {      return  obj->fromString(s);    }    auto optionalIPFromString(...) -> bool {      // DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work.");      return false;    }};#endif#endif
 |