diff --git a/src/AutoConnect.cpp b/src/AutoConnect.cpp index 0c5a046..c5c946c 100644 --- a/src/AutoConnect.cpp +++ b/src/AutoConnect.cpp @@ -22,15 +22,17 @@ #define SET_HOSTNAME(x) do { WiFi.setHostname(x); } while(0) #endif + /** * AutoConnect default constructor. This entry activates WebServer * internally and the web server is allocated internal. */ -AutoConnect::AutoConnect() { - _initialize(); - _webServer.reset(nullptr); - _dnsServer.reset(nullptr); - _webServerAlloc = AC_WEBSERVER_HOSTED; +AutoConnect::AutoConnect() +: _scanCount( 0 ) +, _connectTimeout( AUTOCONNECT_TIMEOUT ) +, _menuTitle( _apConfig.title ) +{ + memset(&_credential, 0x00, sizeof(station_config_t)); } /** @@ -38,28 +40,10 @@ AutoConnect::AutoConnect() { * User's added URI handler response can be included in handleClient method. * @param webServer A reference of ESP8266WebServer instance. */ -AutoConnect::AutoConnect(WebServerClass& webServer) { - _initialize(); - _webServer.reset(&webServer); - _dnsServer.reset(nullptr); - _webServerAlloc = AC_WEBSERVER_PARASITIC; -} - -void AutoConnect::_initialize(void) { - _rfConnect = false; - _rfReset = false; - _rfDisconnect = false; - _responsePage = nullptr; - _currentPageElement = nullptr; - _menuTitle = _apConfig.title; - _connectTimeout = AUTOCONNECT_TIMEOUT; - _scanCount = 0; - memset(&_credential, 0x00, sizeof(station_config_t)); -#ifdef ARDUINO_ARCH_ESP32 - _disconnectEventId = -1; // The member available for ESP32 only -#endif - _aux = nullptr; - _auxUri = String(""); +AutoConnect::AutoConnect(WebServerClass& webServer) +: AutoConnect() +{ + _webServer = WebserverUP(&webServer, [](WebServerClass*){}); } /** @@ -296,8 +280,9 @@ bool AutoConnect::config(AutoConnectConfig& Config) { * by Config method. */ bool AutoConnect::_config(void) { - if (static_cast(_apConfig.apip) == 0U || static_cast(_apConfig.gateway) == 0U || static_cast(_apConfig.netmask) == 0U) + if (static_cast(_apConfig.apip) == 0U || static_cast(_apConfig.gateway) == 0U || static_cast(_apConfig.netmask) == 0U) { AC_DBG("Warning: Contains invalid SoftAPIP address(es).\n"); + } bool rc = WiFi.softAPConfig(_apConfig.apip, _apConfig.gateway, _apConfig.netmask); AC_DBG("SoftAP configure %s, %s, %s %s\n", _apConfig.apip.toString().c_str(), _apConfig.gateway.toString().c_str(), _apConfig.netmask.toString().c_str(), rc ? "" : "failed"); return rc; @@ -317,8 +302,9 @@ bool AutoConnect::_configSTA(const IPAddress& ip, const IPAddress& gateway, cons bool rc; AC_DBG("WiFi.config(IP=%s, Gateway=%s, Subnetmask=%s, DNS1=%s, DNS2=%s)\n", ip.toString().c_str(), gateway.toString().c_str(), netmask.toString().c_str(), dns1.toString().c_str(), dns2.toString().c_str()); - if (!(rc = WiFi.config(ip, gateway, netmask, dns1, dns2))) + if (!(rc = WiFi.config(ip, gateway, netmask, dns1, dns2))) { AC_DBG("failed\n"); + } #ifdef ARDUINO_ARCH_ESP8266 AC_DBG("DHCP client(%s)\n", wifi_station_dhcpc_status() == DHCP_STOPPED ? "STOPPED" : "STARTED"); #endif @@ -374,32 +360,12 @@ void AutoConnect::home(const String& uri) { * Stops AutoConnect captive portal service. */ void AutoConnect::end(void) { - if (_responsePage != nullptr) { - _responsePage->~PageBuilder(); - delete _responsePage; - _responsePage = nullptr; - } - if (_currentPageElement != nullptr) { - _currentPageElement->~PageElement(); - _currentPageElement = nullptr; - } + _responsePage.reset(); + _currentPageElement.reset(); _stopPortal(); - if (_webServer) { - switch (_webServerAlloc) { - case AC_WEBSERVER_HOSTED: - if (_dnsServer) { - _dnsServer->stop(); - _dnsServer.reset(); - } - _webServer.reset(); - break; - case AC_WEBSERVER_PARASITIC: - _webServer.release(); - break; - } - } - + _dnsServer.reset(); + _webServer.reset(); } /** @@ -455,8 +421,7 @@ void AutoConnect::_startWebServer(void) { // Boot Web server if (!_webServer) { // Only when hosting WebServer internally - _webServer.reset(new WebServerClass(AUTOCONNECT_HTTPPORT)); - _webServerAlloc = AC_WEBSERVER_HOSTED; + _webServer = WebserverUP(new WebServerClass(AUTOCONNECT_HTTPPORT), std::default_delete() ); AC_DBG("WebServer allocated\n"); } // Discard the original the not found handler to redirect captive portal detection. @@ -464,7 +429,7 @@ void AutoConnect::_startWebServer(void) { _webServer->onNotFound(std::bind(&AutoConnect::_handleNotFound, this)); // here, Prepare PageBuilders for captive portal if (!_responsePage) { - _responsePage = new PageBuilder(); + _responsePage.reset( new PageBuilder() ); _responsePage->exitCanHandle(std::bind(&AutoConnect::_classifyHandle, this, std::placeholders::_1, std::placeholders::_2)); _responsePage->onUpload(std::bind(&AutoConnect::_handleUpload, this, std::placeholders::_1, std::placeholders::_2)); _responsePage->insert(*_webServer); @@ -539,17 +504,20 @@ void AutoConnect::handleRequest(void) { // Save current credential if (_apConfig.autoSave == AC_SAVECREDENTIAL_AUTO) { AutoConnectCredential credit(_apConfig.boundaryOffset); - if (credit.save(&_credential)) + if (credit.save(&_credential)) { AC_DBG("%.*s credential saved\n", sizeof(_credential.ssid), reinterpret_cast(_credential.ssid)); - else + } + else { AC_DBG("credential %.*s save failed\n", sizeof(_credential.ssid), reinterpret_cast(_credential.ssid)); + } } // Ensures that keeps a connection with the current AP while the portal behaves. _setReconnect(AC_RECONNECT_SET); } - else + else { AC_DBG("%.*s has no BSSID, saving is unavailable\n", sizeof(_credential.ssid), reinterpret_cast(_credential.ssid)); + } // Activate AutoConnectUpdate if it is attached and incorporate // it into the AutoConnect menu. @@ -686,7 +654,7 @@ bool AutoConnect::_loadAvailCredential(const char* ssid) { * Stops DNS server and flush tcp sending. */ void AutoConnect::_stopPortal(void) { - if (_dnsServer && _webServerAlloc == AC_WEBSERVER_HOSTED) + if (_dnsServer) _dnsServer->stop(); if (_webServer) { @@ -940,12 +908,13 @@ bool AutoConnect::_classifyHandle(HTTPMethod method, String uri) { _purgePages(); // Create the page dynamically - if ((_currentPageElement = _setupPage(uri)) == nullptr) - if (_aux) { - // Requested URL is not a normal page, exploring AUX pages - _currentPageElement = _aux->_setupPage(uri); - } - if (_currentPageElement != nullptr) { + _currentPageElement.reset( _setupPage(uri) ); + if (!_currentPageElement && _aux) { + // Requested URL is not a normal page, exploring AUX pages + _currentPageElement.reset(_aux->_setupPage(uri)); + } + + if (_currentPageElement) { AC_DBG_DUMB(",generated:%s", uri.c_str()); _uri = uri; _responsePage->addElement(*_currentPageElement); @@ -975,9 +944,8 @@ void AutoConnect::_handleUpload(const String& requestUri, const HTTPUpload& uplo */ void AutoConnect::_purgePages(void) { _responsePage->clearElement(); - if (_currentPageElement != nullptr) { - delete _currentPageElement; - _currentPageElement = nullptr; + if (_currentPageElement) { + _currentPageElement.reset(); _uri = String(""); } } @@ -1064,8 +1032,7 @@ void AutoConnect::_setReconnect(const AC_STARECONNECT_t order) { if (order == AC_RECONNECT_SET) { _disconnectEventId = WiFi.onEvent([](WiFiEvent_t e, WiFiEventInfo_t info) { AC_DBG("STA lost connection:%d\n", info.disconnected.reason); - bool rst = WiFi.reconnect(); - AC_DBG("STA connection %s\n", rst ? "restored" : "failed"); + AC_DBG("STA connection %s\n", WiFi.reconnect() ? "restored" : "failed"); }, WiFiEvent_t::SYSTEM_EVENT_AP_STADISCONNECTED); AC_DBG("Event<%d> handler registered\n", static_cast(WiFiEvent_t::SYSTEM_EVENT_AP_STADISCONNECTED)); } diff --git a/src/AutoConnect.h b/src/AutoConnect.h index d6c605f..f0f8a98 100644 --- a/src/AutoConnect.h +++ b/src/AutoConnect.h @@ -218,16 +218,10 @@ class AutoConnect { void onNotFound(WebServerClass::THandlerFunction fn); protected: - enum _webServerAllocateType { - AC_WEBSERVER_PARASITIC, - AC_WEBSERVER_HOSTED - }; - typedef enum _webServerAllocateType AC_WEBSERVER_TYPE; typedef enum { AC_RECONNECT_SET, AC_RECONNECT_RESET } AC_STARECONNECT_t; - void _initialize(void); bool _config(void); bool _configSTA(const IPAddress& ip, const IPAddress& gateway, const IPAddress& netmask, const IPAddress& dns1, const IPAddress& dns2); bool _getConfigSTA(station_config_t* config); @@ -271,17 +265,17 @@ class AutoConnect { size_t _freeHeapSize; /** Servers which works in concert. */ - std::unique_ptr _webServer; + typedef std::unique_ptr > WebserverUP; + WebserverUP _webServer = WebserverUP(nullptr, std::default_delete()); std::unique_ptr _dnsServer; - 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; - PageElement* _currentPageElement; + std::unique_ptr _responsePage; + std::unique_ptr _currentPageElement; /** Extended pages made up with AutoConnectAux */ AutoConnectAux* _aux = nullptr; /**< A top of registered AutoConnectAux */ @@ -300,12 +294,12 @@ class AutoConnect { unsigned long _portalAccessPeriod; /** The control indicators */ - bool _rfConnect; /**< URI /connect requested */ - bool _rfDisconnect; /**< URI /disc requested */ - bool _rfReset; /**< URI /reset requested */ + bool _rfConnect = false; /**< URI /connect requested */ + bool _rfDisconnect = false; /**< URI /disc requested */ + bool _rfReset = false; /**< URI /reset requested */ wl_status_t _rsConnect; /**< connection result */ #ifdef ARDUINO_ARCH_ESP32 - WiFiEventId_t _disconnectEventId; /**< STA disconnection event handler registered id */ + WiFiEventId_t _disconnectEventId = -1; /**< STA disconnection event handler registered id */ #endif std::unique_ptr _ticker; /**< */ diff --git a/src/AutoConnectAux.cpp b/src/AutoConnectAux.cpp index b52a067..0b84f01 100644 --- a/src/AutoConnectAux.cpp +++ b/src/AutoConnectAux.cpp @@ -303,8 +303,9 @@ void AutoConnectAux::upload(const String& requestUri, const HTTPUpload& upload) _upload = _uploadHandler; AC_DBG_DUMB("enabled\n"); } - else + else { AC_DBG_DUMB("missing\n"); + } } } diff --git a/src/AutoConnectAuxImpl.h b/src/AutoConnectAuxImpl.h index 649d302..84f3cb0 100644 --- a/src/AutoConnectAuxImpl.h +++ b/src/AutoConnectAuxImpl.h @@ -272,8 +272,9 @@ AutoConnectButtonJson& AutoConnectAux::getElement(const String& name) { if (elm) { if (elm->typeOf() == AC_Button) return *(reinterpret_cast(elm)); - else + else { AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); + } } return reinterpret_cast(_nullElement()); } @@ -289,8 +290,9 @@ AutoConnectCheckboxJson& AutoConnectAux::getElement(const String& name) { if (elm) { if (elm->typeOf() == AC_Checkbox) return *(reinterpret_cast(elm)); - else + else { AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); + } } return reinterpret_cast(_nullElement()); } @@ -306,8 +308,9 @@ AutoConnectFileJson& AutoConnectAux::getElement(const String& name) { if (elm) { if (elm->typeOf() == AC_File) return *(reinterpret_cast(elm)); - else + else { AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); + } } return reinterpret_cast(_nullElement()); } @@ -323,8 +326,9 @@ AutoConnectInputJson& AutoConnectAux::getElement(const String& name) { if (elm) { if (elm->typeOf() == AC_Input) return *(reinterpret_cast(elm)); - else + else { AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); + } } return reinterpret_cast(_nullElement()); } @@ -340,8 +344,9 @@ AutoConnectRadioJson& AutoConnectAux::getElement(const String& name) { if (elm) { if (elm->typeOf() == AC_Radio) return *(reinterpret_cast(elm)); - else + else { AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); + } } return reinterpret_cast(_nullElement()); } @@ -357,8 +362,9 @@ AutoConnectSelectJson& AutoConnectAux::getElement(const String& name) { if (elm) { if (elm->typeOf() == AC_Select) return *(reinterpret_cast(elm)); - else + else { AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); + } } return reinterpret_cast(_nullElement()); } @@ -374,8 +380,9 @@ AutoConnectSubmitJson& AutoConnectAux::getElement(const String& name) { if (elm) { if (elm->typeOf() == AC_Submit) return *(reinterpret_cast(elm)); - else + else { AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); + } } return reinterpret_cast(_nullElement()); } @@ -391,8 +398,9 @@ AutoConnectTextJson& AutoConnectAux::getElement(const String& name) { if (elm) { if (elm->typeOf() == AC_Text) return *(reinterpret_cast(elm)); - else + else { AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf()); + } } return reinterpret_cast(_nullElement()); } diff --git a/src/AutoConnectElementJson.h b/src/AutoConnectElementJson.h index 2cb9486..ad4d06a 100644 --- a/src/AutoConnectElementJson.h +++ b/src/AutoConnectElementJson.h @@ -309,64 +309,73 @@ class AutoConnectTextJson : public AutoConnectElementJson, public AutoConnectTex */ template<> inline AutoConnectButtonJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_Button) + if (typeOf() != AC_Button) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); } template<> inline AutoConnectCheckboxJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_Checkbox) + if (typeOf() != AC_Checkbox) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); } template<> inline AutoConnectFileJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_File) + if (typeOf() != AC_File) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); } template<> inline AutoConnectInputJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_Input) + if (typeOf() != AC_Input) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); } template<> inline AutoConnectRadioJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_Radio) + if (typeOf() != AC_Radio) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); } template<> inline AutoConnectSelectJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_Select) + if (typeOf() != AC_Select) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); } template<> inline AutoConnectStyleJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_Style) + if (typeOf() != AC_Style) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); } template<> inline AutoConnectSubmitJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_Submit) + if (typeOf() != AC_Submit) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); } template<> inline AutoConnectTextJson& AutoConnectElementJson::as(void) { - if (typeOf() != AC_Text) + if (typeOf() != AC_Text) { AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } return *(reinterpret_cast(this)); }