From d36d8282bc7f5759c234c7fa45458db2e0d8013c Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Mon, 3 Jun 2019 20:02:48 +0900 Subject: [PATCH] Separated the AutoConnectUpdate class more drastically --- src/AutoConnect.h | 7 ---- src/AutoConnectUpdate.cpp | 68 ++++++++++++++++++++----------------- src/AutoConnectUpdate.h | 66 +++++++++++++++++++++++++---------- src/AutoConnectUpdatePage.h | 18 +++++----- 4 files changed, 95 insertions(+), 64 deletions(-) diff --git a/src/AutoConnect.h b/src/AutoConnect.h index 883734b..608cddc 100644 --- a/src/AutoConnect.h +++ b/src/AutoConnect.h @@ -35,10 +35,8 @@ using WebServerClass = WebServer; // The realization of AutoConnectUpdate is effective only by the explicit // definition of AUTOCONNECT_USE_UPDATE -#ifdef AUTOCONNECT_USE_UPDATE #include "AutoConnectUpdate.h" class AutoConnectUpdate; // Reference to avoid circular -#endif /**< A type to save established credential at WiFi.begin automatically. */ typedef enum AC_SAVECREDENTIAL { @@ -274,11 +272,8 @@ class AutoConnect { std::unique_ptr _aux; String _auxUri; /**< Last accessed AutoConnectAux */ String _prevUri; /**< Previous generated page uri */ - -#ifdef AUTOCONNECT_USE_UPDATE /** Available updater, only reset by AutoConnectUpdate::attach is valid */ std::unique_ptr _update; -#endif /** Saved configurations */ AutoConnectConfig _apConfig; @@ -380,9 +375,7 @@ class AutoConnect { #endif friend class AutoConnectAux; -#ifdef AUTOCONNECT_USE_UPDATE friend class AutoConnectUpdate; -#endif }; #endif // _AUTOCONNECT_H_ diff --git a/src/AutoConnectUpdate.cpp b/src/AutoConnectUpdate.cpp index 4a8114f..2ba8213 100644 --- a/src/AutoConnectUpdate.cpp +++ b/src/AutoConnectUpdate.cpp @@ -7,6 +7,10 @@ * @copyright MIT license. */ +#include "AutoConnectDefs.h" + +#ifdef AUTOCONNECT_USE_UPDATE + #include #include #include "AutoConnectUpdate.h" @@ -14,16 +18,16 @@ #include "AutoConnectJsonDefs.h" /** - * The AutoConnectUpdate class inherits from the HTTPupdate class. The + * The AutoConnectUpdateAct class inherits from the HTTPupdate class. The * update server corresponding to this class needs a simple script * based on an HTTP server. It is somewhat different from the advanced * updater script offered by Arduino core of ESP8266. * The equipment required for the update server for the - * AutoConnectUpdate class is as follows: + * AutoConnectUpdateAct class is as follows: * * The catalog script: * The update server URI /catalog is a script process that responds to - * queries from the AutoConnectUpdate class. The catalog script accepts + * queries from the AutoConnectUpdateAct class. The catalog script accepts * the queries such as '/catalog?op=list&path='. * - op: * An op parameter speicies the query operation. In the current @@ -54,7 +58,7 @@ * - type: * The type of the file. It defines either directory, file or bin. * The bin means that the file is a sketch binary, and the - * AutoConnectUpdate class recognizes only files type bin as + * AutoConnectUpdateAct class recognizes only files type bin as * available update files. * - path: * A path parameter specifies the path on the server storing @@ -85,17 +89,17 @@ namespace AutoConnectUtil { AC_HAS_FUNC(onProgress); template -typename std::enable_if::value, AutoConnectUpdate::AC_UPDATEDIALOG_t>::type onProgress(T& updater, std::function fn) { +typename std::enable_if::value, AutoConnectUpdateAct::AC_UPDATEDIALOG_t>::type onProgress(T& updater, std::function fn) { updater.onProgress(fn); AC_DBG("Updater keeps callback\n"); - return AutoConnectUpdate::UPDATEDIALOG_METER; + return AutoConnectUpdateAct::UPDATEDIALOG_METER; } template -typename std::enable_if::value, AutoConnectUpdate::AC_UPDATEDIALOG_t>::type onProgress(T& updater, std::function fn) { +typename std::enable_if::value, AutoConnectUpdateAct::AC_UPDATEDIALOG_t>::type onProgress(T& updater, std::function fn) { (void)(updater); (void)(fn); - return AutoConnectUpdate::UPDATEDIALOG_LOADER; + return AutoConnectUpdateAct::UPDATEDIALOG_LOADER; } } @@ -103,7 +107,7 @@ typename std::enable_if::value, AutoCon * A destructor. Release the update processing dialogue page generated * as AutoConnectAux. */ -AutoConnectUpdate::~AutoConnectUpdate() { +AutoConnectUpdateAct::~AutoConnectUpdateAct() { _catalog.reset(nullptr); _progress.reset(nullptr); _result.reset(nullptr); @@ -112,13 +116,13 @@ AutoConnectUpdate::~AutoConnectUpdate() { } /** - * Attach the AutoConnectUpdate to the AutoConnect which constitutes + * Attach the AutoConnectUpdateAct to the AutoConnect which constitutes * the bedrock of the update process. This function creates dialog pages * for update operation as an instance of AutoConnectAux and joins to * the AutoConnect which is the bedrock of the process. * @param portal A reference of AutoConnect */ -void AutoConnectUpdate::attach(AutoConnect& portal) { +void AutoConnectUpdateAct::attach(AutoConnect& portal) { AutoConnectAux* updatePage; updatePage = new AutoConnectAux(String(FPSTR(_auxCatalog.uri)), String(FPSTR(_auxCatalog.title)), _auxCatalog.menu); @@ -133,9 +137,9 @@ void AutoConnectUpdate::attach(AutoConnect& portal) { _buildAux(updatePage, &_auxResult, lengthOf(_elmResult)); _result.reset(updatePage); _result->chunk = PB_ByteStream; - _catalog->on(std::bind(&AutoConnectUpdate::_onCatalog, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); - _progress->on(std::bind(&AutoConnectUpdate::_onUpdate, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); - _result->on(std::bind(&AutoConnectUpdate::_onResult, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); + _catalog->on(std::bind(&AutoConnectUpdateAct::_onCatalog, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); + _progress->on(std::bind(&AutoConnectUpdateAct::_onUpdate, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); + _result->on(std::bind(&AutoConnectUpdateAct::_onResult, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); portal.join(*_catalog.get()); portal.join(*_progress.get()); @@ -143,14 +147,14 @@ void AutoConnectUpdate::attach(AutoConnect& portal) { _status = UPDATE_IDLE; - // Attach this to the AutoConnectUpdate + // Attach this to the AutoConnectUpdateAct portal._update.reset(this); AC_DBG("AutoConnectUpdate attached\n"); if (WiFi.status() == WL_CONNECTED) enable(); // Register the callback to inform the update progress - _dialog = AutoConnectUtil::onProgress(Update, std::bind(&AutoConnectUpdate::_inProgress, this, std::placeholders::_1, std::placeholders::_2)); + _dialog = AutoConnectUtil::onProgress(Update, std::bind(&AutoConnectUpdateAct::_inProgress, this, std::placeholders::_1, std::placeholders::_2)); // Adjust the client dialog pattern according to the callback validity // of the UpdateClass. AutoConnectElement* loader = _progress->getElement(String(F("loader"))); @@ -177,9 +181,9 @@ void AutoConnectUpdate::attach(AutoConnect& portal) { /** * Detach the update item from the current AutoConnect menu. - * AutoConnectUpdate still active. + * AutoConnectUpdateAct still active. */ -void AutoConnectUpdate::disable(void) { +void AutoConnectUpdateAct::disable(void) { if (_catalog) { _catalog->menu(false); if (_WiFiClient) @@ -189,10 +193,10 @@ void AutoConnectUpdate::disable(void) { } /** - * Make AutoConnectUpdate class available by incorporating the update + * Make AutoConnectUpdateAct class available by incorporating the update * function into the menu. */ -void AutoConnectUpdate::enable(void) { +void AutoConnectUpdateAct::enable(void) { if (_catalog) { _catalog->menu(true); _status = UPDATE_IDLE; @@ -201,7 +205,7 @@ void AutoConnectUpdate::enable(void) { } } -void AutoConnectUpdate::handleUpdate(void) { +void AutoConnectUpdateAct::handleUpdate(void) { // Purge WiFiClient instances that have exceeded their retention // period to avoid running out of memory. if (_WiFiClient) { @@ -214,7 +218,7 @@ void AutoConnectUpdate::handleUpdate(void) { if (isEnable()) { if (WiFi.status() == WL_CONNECTED) { - // Evaluate the processing status of AutoConnectUpdate and + // Evaluate the processing status of AutoConnectUpdateAct and // execute it accordingly. It is only this process point that // requests update processing. if (_status == UPDATE_START) { @@ -238,7 +242,7 @@ void AutoConnectUpdate::handleUpdate(void) { } } // If WiFi is not connected, disables the update menu. - // However, the AutoConnectUpdate class stills active. + // However, the AutoConnectUpdateAct class stills active. else disable(); } @@ -249,7 +253,7 @@ void AutoConnectUpdate::handleUpdate(void) { * fetch the result. * @return AC_UPDATESTATUS_t */ -AC_UPDATESTATUS_t AutoConnectUpdate::update(void) { +AC_UPDATESTATUS_t AutoConnectUpdateAct::update(void) { // Start update String uriBin = uri + '/' + _binName; if (_binName.length()) { @@ -296,7 +300,7 @@ AC_UPDATESTATUS_t AutoConnectUpdate::update(void) { * @param page Pre-defined ACPage_t * @param elementNum Number of AutoConnectElements to configure. */ -void AutoConnectUpdate::_buildAux(AutoConnectAux* aux, const AutoConnectUpdate::ACPage_t* page, const size_t elementNum) { +void AutoConnectUpdateAct::_buildAux(AutoConnectAux* aux, const AutoConnectUpdateAct::ACPage_t* page, const size_t elementNum) { for (size_t n = 0; n < elementNum; n++) { if (page->element[n].type == AC_Element) { AutoConnectElement* element = new AutoConnectElement; @@ -341,7 +345,7 @@ void AutoConnectUpdate::_buildAux(AutoConnectAux* aux, const AutoConnectUpdate:: * @param args A reference of the PageArgument of the PageBuilder * @return Additional string to the page but it always null. */ -String AutoConnectUpdate::_onCatalog(AutoConnectAux& catalog, PageArgument& args) { +String AutoConnectUpdateAct::_onCatalog(AutoConnectAux& catalog, PageArgument& args) { AC_UNUSED(args); HTTPClient httpClient; @@ -448,13 +452,13 @@ String AutoConnectUpdate::_onCatalog(AutoConnectAux& catalog, PageArgument& args * @param args A reference of the PageArgument of the PageBuilder * @return Additional string to the page but it always null. */ -String AutoConnectUpdate::_onUpdate(AutoConnectAux& progress, PageArgument& args) { +String AutoConnectUpdateAct::_onUpdate(AutoConnectAux& progress, PageArgument& args) { AC_UNUSED(args); // launch the WebSocket server _ws.reset(new WebSocketsServer(AUTOCONNECT_WEBSOCKETPORT)); if (_ws) { _ws->begin(); - _ws->onEvent(std::bind(&AutoConnectUpdate::_wsEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + _ws->onEvent(std::bind(&AutoConnectUpdateAct::_wsEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } else AC_DBG("WebSocketsServer allocation failed\n"); @@ -480,7 +484,7 @@ String AutoConnectUpdate::_onUpdate(AutoConnectAux& progress, PageArgument& args * @param args A reference of the PageArgument of the PageBuilder * @return Additional string to the page but it always null. */ -String AutoConnectUpdate::_onResult(AutoConnectAux& result, PageArgument& args) { +String AutoConnectUpdateAct::_onResult(AutoConnectAux& result, PageArgument& args) { AC_UNUSED(args); String resForm; String resColor; @@ -518,7 +522,7 @@ String AutoConnectUpdate::_onResult(AutoConnectAux& result, PageArgument& args) return String(""); } -void AutoConnectUpdate::_inProgress(size_t amount, size_t size) { +void AutoConnectUpdateAct::_inProgress(size_t amount, size_t size) { if (_ws) { _amount = amount; _binSize = size; @@ -527,7 +531,7 @@ void AutoConnectUpdate::_inProgress(size_t amount, size_t size) { } } -void AutoConnectUpdate::_wsEvent(uint8_t client, WStype_t event, uint8_t* payload, size_t length) { +void AutoConnectUpdateAct::_wsEvent(uint8_t client, WStype_t event, uint8_t* payload, size_t length) { AC_DBG("WS client:%d event(%d)\n", client, event); if (event == WStype_CONNECTED) { _wsConnected = true; @@ -537,3 +541,5 @@ void AutoConnectUpdate::_wsEvent(uint8_t client, WStype_t event, uint8_t* payloa else if (event == WStype_DISCONNECTED) _wsConnected = false; } + +#endif // !AUTOCONNECT_USE_UPDATE diff --git a/src/AutoConnectUpdate.h b/src/AutoConnectUpdate.h index b53a2c1..852b85f 100644 --- a/src/AutoConnectUpdate.h +++ b/src/AutoConnectUpdate.h @@ -29,6 +29,11 @@ #ifndef _AUTOCONNECTUPDATE_H_ #define _AUTOCONNECTUPDATE_H_ +#include "AutoConnectDefs.h" +#ifdef AUTOCONNECT_USE_UPDATE +#ifndef AUTOCONNECT_USE_JSON +#define AUTOCONNECT_USE_JSON +#endif #include #define NO_GLOBAL_HTTPUPDATE #if defined(ARDUINO_ARCH_ESP8266) @@ -41,11 +46,10 @@ using HTTPUpdateClass = ESP8266HTTPUpdate; using HTTPUpdateClass = HTTPUpdate; #endif #include -#include "AutoConnectDefs.h" -#if defined(AUTOCONNECT_USE_UPDATE) -#ifndef AUTOCONNECT_USE_JSON -#define AUTOCONNECT_USE_JSON -#endif +// Quote the true AutoConnectUpdate class according to AUTOCONNECT_USE_UPDATE. +#define AutoConnectUpdate AutoConnectUpdateAct +#else // !AUTOCONNECT_USE_UPDATE! +#define AutoConnectUpdate AutoConnectUpdateVoid #endif #include "AutoConnect.h" @@ -66,27 +70,54 @@ typedef enum AC_UPDATESTATUS { UPDATE_FAIL /**< Update fails */ } AC_UPDATESTATUS_t; -class AutoConnectUpdate : public HTTPUpdateClass { +class AutoConnectUpdateVoid { + public: + explicit AutoConnectUpdateVoid(const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT) { + AC_UNUSED(host); + AC_UNUSED(port); + AC_UNUSED(uri); + AC_UNUSED(timeout); + } + AutoConnectUpdateVoid(AutoConnect& portal, const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT) { + AC_UNUSED(portal); + AC_UNUSED(host); + AC_UNUSED(port); + AC_UNUSED(uri); + AC_UNUSED(timeout); + } + virtual ~AutoConnectUpdateVoid() {} + virtual void attach(AutoConnect& portal) { AC_UNUSED(portal); } + virtual void enable(void) {} + virtual void disable(void) {} + virtual void handleUpdate(void) {} + virtual bool isEnable(void) { return false; } + virtual AC_UPDATESTATUS_t status(void) { return UPDATE_IDLE; } + virtual AC_UPDATESTATUS_t update(void) { return UPDATE_IDLE; } +}; + +#ifdef AUTOCONNECT_USE_UPDATE + +class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClass { public: - explicit AutoConnectUpdate(const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT) + explicit AutoConnectUpdateAct(const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT) : HTTPUpdateClass(timeout), host(host), port(port), uri(uri), _status(UPDATE_IDLE), _binName(String()), _period(0) { UPDATE_SETLED(LOW); /**< LED blinking during the update that is the default. */ rebootOnUpdate(false); /**< Default reboot mode */ } - AutoConnectUpdate(AutoConnect& portal, const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT) + AutoConnectUpdateAct(AutoConnect& portal, const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT) : HTTPUpdateClass(timeout), host(host), port(port), uri(uri), _status(UPDATE_IDLE), _binName(String()), _period(0) { UPDATE_SETLED(LOW); rebootOnUpdate(false); attach(portal); } - ~AutoConnectUpdate(); - void attach(AutoConnect& portal); /**< Attach the update class to AutoConnect */ - void enable(void); /**< Enable the AutoConnectUpdate */ - void disable(void); /**< Disable the AutoConnectUpdate */ - void handleUpdate(void); /**< Behaves the update process */ - bool isEnable(void) { return _catalog ? _catalog->isMenu() : false; } /**< Returns current updater effectiveness */ - AC_UPDATESTATUS_t status(void) { return _status; } /**< reports the current update behavior status */ - AC_UPDATESTATUS_t update(void); /**< behaves update */ + ~AutoConnectUpdateAct(); + void attach(AutoConnect& portal) override; /**< Attach the update class to AutoConnect */ + void enable(void) override; /**< Enable the AutoConnectUpdateAct */ + void disable(void) override; /**< Disable the AutoConnectUpdateAct */ + void handleUpdate(void) override; /**< Behaves the update process */ + bool isEnable(void) override { return _catalog ? _catalog->isMenu() : false; } /**< Returns current updater effectiveness */ + AC_UPDATESTATUS_t status(void) override { return _status; } /**< reports the current update behavior status */ + AC_UPDATESTATUS_t update(void) override; /**< behaves update */ String host; /**< Available URL of Update Server */ uint16_t port; /**< Port number of the update server */ @@ -117,7 +148,7 @@ class AutoConnectUpdate : public HTTPUpdateClass { template constexpr size_t lengthOf(T(&)[N]) noexcept { return N; } - void _buildAux(AutoConnectAux* aux, const AutoConnectUpdate::ACPage_t* page, const size_t elementNum); + void _buildAux(AutoConnectAux* aux, const AutoConnectUpdateAct::ACPage_t* page, const size_t elementNum); String _onCatalog(AutoConnectAux& catalog, PageArgument& args); String _onUpdate(AutoConnectAux& update, PageArgument& args); String _onResult(AutoConnectAux& result, PageArgument& args); @@ -151,4 +182,5 @@ class AutoConnectUpdate : public HTTPUpdateClass { static const ACElementProp_t _elmResult[] PROGMEM; }; +#endif // !AUTOCONNECT_USE_UPDATE #endif // _AUTOCONNECTUPDATE_H_ diff --git a/src/AutoConnectUpdatePage.h b/src/AutoConnectUpdatePage.h index 10cda4c..8054919 100644 --- a/src/AutoConnectUpdatePage.h +++ b/src/AutoConnectUpdatePage.h @@ -13,7 +13,7 @@ // Define the AUTOCONNECT_URI_UPDATE page to select the sketch binary // for update and order update execution. -const AutoConnectUpdate::ACElementProp_t AutoConnectUpdate::_elmCatalog[] PROGMEM = { +const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmCatalog[] PROGMEM = { { AC_Element, "binSty", "", nullptr }, { AC_Text, "caption", nullptr, nullptr }, { AC_Element, "c1", "
", nullptr }, @@ -21,13 +21,13 @@ const AutoConnectUpdate::ACElementProp_t AutoConnectUpdate::_elmCatalog[] PROGME { AC_Element, "c1", "
", nullptr }, { AC_Submit, "update", "UPDATE", AUTOCONNECT_URI_UPDATE_ACT } }; -const AutoConnectUpdate::ACPage_t AutoConnectUpdate::_auxCatalog PROGMEM = { - AUTOCONNECT_URI_UPDATE, "Update", false, AutoConnectUpdate::_elmCatalog +const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_auxCatalog PROGMEM = { + AUTOCONNECT_URI_UPDATE, "Update", false, AutoConnectUpdateAct::_elmCatalog }; // Define the AUTOCONNECT_URI_UPDATE_ACT page to display during the // update process. -const AutoConnectUpdate::ACElementProp_t AutoConnectUpdate::_elmProgress[] PROGMEM = { +const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmProgress[] PROGMEM = { { AC_Element, "loader", "", nullptr }, { AC_Element, "c1", "
", nullptr }, { AC_Element, "binname", nullptr, nullptr }, @@ -49,17 +49,17 @@ const AutoConnectUpdate::ACElementProp_t AutoConnectUpdate::_elmProgress[] PROGM { AC_Element, "inprogress_loader", "function incr(pv){}", nullptr }, { AC_Element, "c9", "", nullptr } }; -const AutoConnectUpdate::ACPage_t AutoConnectUpdate::_auxProgress PROGMEM = { - AUTOCONNECT_URI_UPDATE_ACT, "Update", false, AutoConnectUpdate::_elmProgress +const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_auxProgress PROGMEM = { + AUTOCONNECT_URI_UPDATE_ACT, "Update", false, AutoConnectUpdateAct::_elmProgress }; // Definition of the AUTOCONNECT_URI_UPDATE_RESULT page to notify update results -const AutoConnectUpdate::ACElementProp_t AutoConnectUpdate::_elmResult[] PROGMEM = { +const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmResult[] PROGMEM = { { AC_Text, "status", nullptr, nullptr }, { AC_Element, "restart", "", nullptr } }; -const AutoConnectUpdate::ACPage_t AutoConnectUpdate::_auxResult PROGMEM = { - AUTOCONNECT_URI_UPDATE_RESULT, "Update", false, AutoConnectUpdate::_elmResult +const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_auxResult PROGMEM = { + AUTOCONNECT_URI_UPDATE_RESULT, "Update", false, AutoConnectUpdateAct::_elmResult }; #endif // _AUTOCONNECTUPDATEPAGE_H