From acb0eb30284a6617e67858e89cbe226b9b996f50 Mon Sep 17 00:00:00 2001 From: IPdotSetAF Date: Tue, 29 Apr 2025 09:19:16 +0330 Subject: [PATCH 1/5] added events and enums in header file --- src/ESPAsyncHTTPUpdateServer.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/ESPAsyncHTTPUpdateServer.h b/src/ESPAsyncHTTPUpdateServer.h index 0aa8f29..edf6423 100644 --- a/src/ESPAsyncHTTPUpdateServer.h +++ b/src/ESPAsyncHTTPUpdateServer.h @@ -3,9 +3,27 @@ #include +enum UpdateType +{ + FIRMWARE, + FILE_SYSTEM +}; + +enum UpdateCode +{ + UPDATE_OK, + UPDATE_ABORT, + UPDATE_ERROR, +}; + +typedef void (*ESPAsyncHTTPUpdateServer_event)(const UpdateType updateType, int &resultCode); + class ESPAsyncHTTPUpdateServer { public: + ESPAsyncHTTPUpdateServer_event onUpdateBegin; + ESPAsyncHTTPUpdateServer_event onUpdateEnd; + ESPAsyncHTTPUpdateServer(); void setup(AsyncWebServer *server) From 18099d2b385a1f80e2096ebd07c71008c6ea4c75 Mon Sep 17 00:00:00 2001 From: IPdotSetAF Date: Tue, 29 Apr 2025 12:09:30 +0330 Subject: [PATCH 2/5] implemented events --- src/ESPAsyncHTTPUpdateServer.cpp | 28 ++++++++++++++++++++++++++-- src/ESPAsyncHTTPUpdateServer.h | 10 ++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/ESPAsyncHTTPUpdateServer.cpp b/src/ESPAsyncHTTPUpdateServer.cpp index 542c8d7..f6d0251 100644 --- a/src/ESPAsyncHTTPUpdateServer.cpp +++ b/src/ESPAsyncHTTPUpdateServer.cpp @@ -123,11 +123,14 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, // handler for the file upload, gets the sketch bytes, and writes // them through the Update object - String inputName = request->getParam("name")->value(); + _updateType = request->getParam("name")->value() == "filesystem"? + UpdateType::FILE_SYSTEM : + UpdateType::FIRMWARE; if (!index) { _updaterError.clear(); + #ifdef ESPASYNCHTTPUPDATESERVER_DEBUG ESPASYNCHTTPUPDATESERVER_SerialOutput.setDebugOutput(true); #endif @@ -137,11 +140,25 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, Log("Unauthenticated Update\n"); return; } + + if (onUpdateBegin) + { + _updateResult = UpdateResult::UPDATE_OK; + onUpdateBegin(_updateType, _updateResult); + if (_updateResult != UpdateResult::UPDATE_OK) + { + Log("Update aborted by server: %d\n", _updateResult); + if(onUpdateEnd) + onUpdateEnd(_updateType, _updateResult); + return; + } + } + Log("Update: %s\n", filename.c_str()); #ifdef ESP8266 Update.runAsync(true); #endif - if (inputName == "filesystem") + if (_updateType == UpdateType::FILE_SYSTEM) { Log("updating filesystem"); #ifdef ESP8266 @@ -183,6 +200,9 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, { if (Update.end(true)) { // true to set the size to the current progress + _updateResult = UpdateResult::UPDATE_OK; + if(onUpdateEnd) + onUpdateEnd(_updateType, _updateResult); Log("Update Success: \nRebooting...\n"); } else @@ -204,4 +224,8 @@ void ESPAsyncHTTPUpdateServer::_setUpdaterError() StreamString str; Update.printError(str); _updaterError = str.c_str(); + + _updateResult = UpdateResult::UPDATE_ERROR; + if(onUpdateEnd) + onUpdateEnd(_updateType, _updateResult); } \ No newline at end of file diff --git a/src/ESPAsyncHTTPUpdateServer.h b/src/ESPAsyncHTTPUpdateServer.h index edf6423..d587504 100644 --- a/src/ESPAsyncHTTPUpdateServer.h +++ b/src/ESPAsyncHTTPUpdateServer.h @@ -9,20 +9,20 @@ enum UpdateType FILE_SYSTEM }; -enum UpdateCode +enum UpdateResult { UPDATE_OK, UPDATE_ABORT, UPDATE_ERROR, }; -typedef void (*ESPAsyncHTTPUpdateServer_event)(const UpdateType updateType, int &resultCode); +typedef void (*ESPAsyncHTTPUpdateServer_event)(const UpdateType type, int &result); class ESPAsyncHTTPUpdateServer { public: - ESPAsyncHTTPUpdateServer_event onUpdateBegin; - ESPAsyncHTTPUpdateServer_event onUpdateEnd; + ESPAsyncHTTPUpdateServer_event onUpdateBegin = NULL; + ESPAsyncHTTPUpdateServer_event onUpdateEnd = NULL; ESPAsyncHTTPUpdateServer(); @@ -58,6 +58,8 @@ class ESPAsyncHTTPUpdateServer String _password; bool _authenticated; String _updaterError; + UpdateType _updateType; + int _updateResult; }; #endif From 5c9439e193e76e573318fa48dae151cde7dddd53 Mon Sep 17 00:00:00 2001 From: IPdotSetAF Date: Fri, 2 May 2025 00:41:25 +0330 Subject: [PATCH 3/5] cleanedup logs updated conditions and behaviors --- src/ESPAsyncHTTPUpdateServer.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ESPAsyncHTTPUpdateServer.cpp b/src/ESPAsyncHTTPUpdateServer.cpp index f6d0251..ee7568f 100644 --- a/src/ESPAsyncHTTPUpdateServer.cpp +++ b/src/ESPAsyncHTTPUpdateServer.cpp @@ -105,9 +105,9 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, if (!_authenticated) return request->requestAuthentication(); - if (Update.hasError()) + if (_updateResult != UpdateResult::UPDATE_OK) { - AsyncWebServerResponse *response = request->beginResponse(200, F("text/html"), String(F("Update error: ")) + _updaterError); + AsyncWebServerResponse *response = request->beginResponse(200, F("text/html"), Update.hasError() ? String(F("Update error: ")) + _updaterError : "Update aborted by server."); response->addHeader("Access-Control-Allow-Headers", "*"); response->addHeader("Access-Control-Allow-Origin", "*"); response->addHeader("Connection", "close"); @@ -116,6 +116,7 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, else { request->send_P(200, PSTR("text/html"), successResponse); + Log("Rebooting...\n"); restartTimer.once_ms(1000, ESP.restart); } }, [&](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) @@ -160,7 +161,7 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, #endif if (_updateType == UpdateType::FILE_SYSTEM) { - Log("updating filesystem"); + Log("updating filesystem\n"); #ifdef ESP8266 int command = U_FS; size_t fsSize = ((size_t)FS_end - (size_t)FS_start); @@ -182,28 +183,28 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, } else { - Log("updating flash"); + Log("updating flash\n"); uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; if (!Update.begin(maxSketchSpace, U_FLASH)) // start with max available size _setUpdaterError(); } } - if (_authenticated && len && !_updaterError.length()) + if (_authenticated && len && _updateResult == UpdateResult::UPDATE_OK) { Log("."); if (Update.write(data, len) != len) _setUpdaterError(); } - if (_authenticated && final && !_updaterError.length()) + if (_authenticated && final && _updateResult == UpdateResult::UPDATE_OK) { if (Update.end(true)) { // true to set the size to the current progress + Log("Update Success.\n"); _updateResult = UpdateResult::UPDATE_OK; if(onUpdateEnd) onUpdateEnd(_updateType, _updateResult); - Log("Update Success: \nRebooting...\n"); } else _setUpdaterError(); From e03c1dc14ebd946282ddf436668917e7765821ee Mon Sep 17 00:00:00 2001 From: IPdotSetAF Date: Fri, 2 May 2025 02:50:37 +0330 Subject: [PATCH 4/5] fixed esp32 build updated depricated functions for esp32 --- src/ESPAsyncHTTPUpdateServer.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ESPAsyncHTTPUpdateServer.cpp b/src/ESPAsyncHTTPUpdateServer.cpp index ee7568f..259d53e 100644 --- a/src/ESPAsyncHTTPUpdateServer.cpp +++ b/src/ESPAsyncHTTPUpdateServer.cpp @@ -78,7 +78,11 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, if(_username != emptyString && _password != emptyString) if( !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); +#ifdef ESP32 + AsyncWebServerResponse* response = request->beginResponse(200, "text/html", serverIndex, sizeof(serverIndex)); +#else AsyncWebServerResponse* response = request->beginResponse_P(200, "text/html", serverIndex, sizeof(serverIndex)); +#endif response->addHeader("Content-Encoding", "gzip"); request->send(response); }); @@ -115,9 +119,13 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path, } else { +#ifdef ESP32 + request->send(200, PSTR("text/html"), successResponse); +#else request->send_P(200, PSTR("text/html"), successResponse); +#endif Log("Rebooting...\n"); - restartTimer.once_ms(1000, ESP.restart); + restartTimer.once_ms(1000,[]{ ESP.restart(); }); } }, [&](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { From 898b9feed0e8fb53512737975375a267fd3d8c03 Mon Sep 17 00:00:00 2001 From: IPdotSetAF Date: Fri, 2 May 2025 03:03:51 +0330 Subject: [PATCH 5/5] added event usage docs in readme updated example --- README.md | 37 +++++++++++++++++++----- examples/simple_server/simple_server.ino | 12 ++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1bb3fed..17b5e42 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ It will provide a webpage for updating the firmware/filesystem of `ESP8266` or ` - Update credentials customization (default: `No credentials`) - Username - Password +- Update Events: + - onUpdateBegin + - onUpdateEnd +- Force Aborting Update using events - FileSystem Options: - SPIFFS - LittleFS @@ -60,25 +64,44 @@ This Library is available in `Arduino Library Repository` and `PIO` and you can ``` 2. Create an object from `ESPAsyncHTTPUpdateServer` ``` C++ -ESPAsyncHTTPUpdateServer _updateServer; -AsyncWebServer _server(80); +ESPAsyncHTTPUpdateServer updateServer; +AsyncWebServer server(80); ``` 3. Setup the update server before starting the webServer ``` C++ -_updateServer.setup(&_server); -_server.begin(); +updateServer.setup(&server); +server.begin(); ``` #### Custom Route ``` C++ -_updateServer.setup(&_server, "/customroute"); +updateServer.setup(&server, "/customroute"); ``` #### Credentials ``` C++ -_updateServer.setup(&_server, "username", "password"); +updateServer.setup(&server, "username", "password"); ``` or ``` C++ -_updateServer.setup(&_server, "/customroute", "username", "password"); +updateServer.setup(&server, "/customroute", "username", "password"); +``` +#### Events +```c++ +updateServer.onUpdateBegin = [](const UpdateType type, int &result) + { + //... + }; + +updateServer.onUpdateEnd = [](const UpdateType type, int &result) + { + //... + }; +``` +#### Aborting the update +```c++ +updateServer.onUpdateBegin = [](const UpdateType type, int &result) + { + result = UpdateResult::UPDATE_ABORT; + }; ``` ### Styling and Customizing OTA Page diff --git a/examples/simple_server/simple_server.ino b/examples/simple_server/simple_server.ino index 3d3856c..59140fa 100644 --- a/examples/simple_server/simple_server.ino +++ b/examples/simple_server/simple_server.ino @@ -48,6 +48,18 @@ void setup() { //setup the updateServer with credentials updateServer.setup(&server, "admin", "admin"); + //hook to update events if you need to + updateServer.onUpdateBegin = [](const UpdateType type, int &result) + { + //you can force abort the update like this if you need to: + //result = UpdateResult::UPDATE_ABORT; + Serial.println("Update started : " + String(type)); + }; + updateServer.onUpdateEnd = [](const UpdateType type, int &result) + { + Serial.println("Update finished : " + String(type) + " result: " + String(result)); + }; + server.begin(); }