diff --git a/html/script.js b/html/script.js index ad8d636cb..aa4d05ba3 100644 --- a/html/script.js +++ b/html/script.js @@ -230,19 +230,37 @@ $(function () { } function completeHandler(event) { + console.info("Transfer Complete"); + // console.info("event: '" + event + "'"); + // console.info("event.target.response: '" + event.target.response + "'"); + // console.info("event.target.responseText: '" + event.target.responseText + "'"); + // console.info("event.target.status : '" + event.target.status + "'"); + // console.info("event.target.statusText : '" + event.target.statusText + "'"); + // _("status").innerHTML = event.target.responseText; _("EfuProgressBar").value = 0; //will clear progress bar after successful upload - showReboot(); + $("#EfuProgressBar").addClass("hidden"); + + if(event.target.status === '200') + { + showReboot(); + } + else + { + alert("Firmware Upload FAILED!\n" + event.target.response); + } } function errorHandler(event) { console.error("Transfer Error"); - // _("status").innerHTML = "Upload Failed"; + $("#EfuProgressBar").addClass("hidden"); + alert("Firmware Upload FAILED!"); } function abortHandler(event) { console.error("Transfer Abort"); - // _("status").innerHTML = "Upload Aborted"; + $("#EfuProgressBar").addClass("hidden"); + alert("Firmware Upload FAILED!"); } }); })); diff --git a/include/EFUpdate.h b/include/EFUpdate.h index d59b3b71e..5285ef834 100644 --- a/include/EFUpdate.h +++ b/include/EFUpdate.h @@ -2,7 +2,7 @@ * EFUpdate.h * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2016, 2022 Shelby Merrick +* Copyright (c) 2016, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -34,7 +34,7 @@ class EFUpdate { void begin(); bool process(uint8_t *data, uint32_t len); bool hasError(); - uint8_t getError(); + uint8_t getError(String & msg); bool end(); void GetDriverName(String & name) {name = String(F("EFUPD"));} bool UpdateIsInProgress() {return _state != State::IDLE;} @@ -81,8 +81,12 @@ class EFUpdate { uint32_t _loc = 0; efuheader_t _header; efurecord_t _record; - uint32_t _maxSketchSpace; - uint8_t _error; + uint32_t _maxSketchSpace = 0; + uint8_t _error = EFUPDATE_ERROR_OK; + String _errorMsg; + + void ConvertErrorToString(); + }; #endif /* EFUPDATE_H_ */ diff --git a/src/EFUpdate.cpp b/src/EFUpdate.cpp index 8cdd27ea3..c1088e259 100644 --- a/src/EFUpdate.cpp +++ b/src/EFUpdate.cpp @@ -47,6 +47,7 @@ void EFUpdate::begin() { _state = State::HEADER; _loc = 0; _error = EFUPDATE_ERROR_OK; + _errorMsg = ""; Update.onProgress( [this] (size_t progress, size_t total) { @@ -61,12 +62,15 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { uint32_t index = 0; bool ConfigChanged = true; - while (index < len) { + while (!hasError() && (index < len)) + { // DEBUG_V (String (" len: 0x") + String (len, HEX)); // DEBUG_V (String ("index: 0X") + String (index, HEX)); - switch (_state) { + switch (_state) + { case State::HEADER: + { // DEBUG_V (String (" len: 0x") + String (len, HEX)); // DEBUG_V (String ("index: ") + String (index)); // DEBUG_V ("Process HEADER record"); @@ -82,14 +86,17 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { _loc = 0; _state = State::RECORD; } else { - logcon ("FAIL: EFUPDATE_ERROR_SIG"); + logcon (F("FAIL: EFUPDATE_ERROR_SIG")); _state = State::FAIL; _error = EFUPDATE_ERROR_SIG; + _errorMsg = F("Invalid EFU Signature"); } } // DEBUG_V (); break; + } case State::RECORD: + { // DEBUG_V ("Process Data RECORD Type"); // DEBUG_V (String (" len: 0x") + String (len, HEX)); // DEBUG_V (String (" index: ") + String (index)); @@ -110,9 +117,10 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { logcon ("Starting Sketch Image Update\n"); // Begin sketch update if (!Update.begin(_record.size, U_FLASH)) { - logcon ("Update.begin FAIL"); + logcon (F("Update.begin FAIL")); _state = State::FAIL; _error = Update.getError(); + ConvertErrorToString(); } else { /// DEBUG_V ("PASS"); _state = State::DATA; @@ -143,9 +151,10 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { #endif // DEBUG_V (); if (!Update.begin(_record.size, U_SPIFFS)) { - logcon ("begin U_SPIFFS failed"); + logcon (F("begin U_SPIFFS failed")); _state = State::FAIL; _error = Update.getError(); + ConvertErrorToString(); // DEBUG_V (); } else { // DEBUG_V ("begin U_SPIFFS"); @@ -155,14 +164,17 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { Update.runAsync (true); #endif } else { - logcon ("Unknown Record Type"); + logcon (F("Unknown Record Type")); _state = State::FAIL; _error = EFUPDATE_ERROR_REC; + _errorMsg = F("Unknown Record Type"); } } // DEBUG_V (); break; + } case State::DATA: + { // DEBUG_V ("DATA"); uint32_t toWrite; @@ -187,12 +199,14 @@ bool EFUpdate::process(uint8_t *data, uint32_t len) { } // DEBUG_V (); break; - + } case State::FAIL: + { // DEBUG_V ("Enter FAIL state"); index = len; ConfigChanged = false; break; + } case State::IDLE: { // dont do anything @@ -210,11 +224,90 @@ bool EFUpdate::hasError() { return _error != EFUPDATE_ERROR_OK; } -uint8_t EFUpdate::getError() { +uint8_t EFUpdate::getError(String & msg) +{ // DEBUG_V (); + msg = _errorMsg; return _error; } +void EFUpdate::ConvertErrorToString() +{ + switch (_error) + { + case UPDATE_ERROR_OK: + { + _errorMsg = F("OK"); + break; + } + case UPDATE_ERROR_WRITE: + { + _errorMsg = F("Error writting to Flash"); + break; + } + case UPDATE_ERROR_ERASE: + { + _errorMsg = F("Error Erasing Flash"); + break; + } + case UPDATE_ERROR_READ: + { + _errorMsg = F("Could not read from FLASH"); + break; + } + case UPDATE_ERROR_SPACE: + { + _errorMsg = F("Not enough space in partition"); + break; + } + case UPDATE_ERROR_SIZE: + { + _errorMsg = F("File Size mismatch"); + break; + } + case UPDATE_ERROR_STREAM: + { + _errorMsg = F("Stream writer failed"); + break; + } + case UPDATE_ERROR_MD5: + { + _errorMsg = F("MD5 checksum failed"); + break; + } + case UPDATE_ERROR_MAGIC_BYTE: + { + _errorMsg = F("Magic Byte Mismatch"); + break; + } + case UPDATE_ERROR_ACTIVATE: + { + _errorMsg = F("Could Not activate the alternate partition"); + break; + } + case UPDATE_ERROR_NO_PARTITION: + { + _errorMsg = F("No partition defined for target"); + break; + } + case UPDATE_ERROR_BAD_ARGUMENT: + { + _errorMsg = F("Invalid argument"); + break; + } + case UPDATE_ERROR_ABORT: + { + _errorMsg = F("Operation Aborted"); + break; + } + default: + { + _errorMsg = F("Unknown Error Code"); + break; + } + } +} // ConvertErrorToString + bool EFUpdate::end() { // DEBUG_V (); if (_state == State::FAIL) diff --git a/src/WebMgr.cpp b/src/WebMgr.cpp index 149b20297..1c2dd644c 100644 --- a/src/WebMgr.cpp +++ b/src/WebMgr.cpp @@ -365,7 +365,20 @@ void c_WebMgr::init () webServer.on ("/updatefw", HTTP_POST, [](AsyncWebServerRequest* request) { - RequestReboot(100000);; + // DEBUG_V("Client requested reboot"); + if (WebMgr.efupdate.hasError ()) + { + // DEBUG_V ("efupdate.hasError, ignoring reboot request"); + String ErrorMsg; + WebMgr.efupdate.getError (ErrorMsg); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + ErrorMsg.c_str())); + } + else + { + // DEBUG_V ("efupdate.hasError == false"); + request->send (200, CN_textSLASHplain, (String (F ("Update Success")))); + RequestReboot(100000); + } }, [](AsyncWebServerRequest* request, String filename, uint32_t index, uint8_t* data, uint32_t len, bool final) {WebMgr.FirmwareUpload (request, filename, index, data, len, final); }); //.setFilter (ON_STA_FILTER); @@ -830,6 +843,15 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, // DEBUG_V (String (" data: 0x") + String (uint32_t(data), HEX)); // DEBUG_V (String (" len: ") + String (len)); // DEBUG_V (String ("final: ") + String (final)); + if (efupdate.hasError ()) + { + // logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); + // DEBUG_V ("efupdate.hasError"); + String ErrorMsg; + WebMgr.efupdate.getError (ErrorMsg); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + ErrorMsg.c_str())); + break; + } // is the first message in the upload? if (0 == index) @@ -841,6 +863,7 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, request->send (429, CN_textSLASHplain, F ("Update Error: Too many requests.")); break; } + #ifdef ARDUINO_ARCH_ESP8266 WiFiUDP::stopAll (); #else @@ -853,6 +876,15 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, // start the update efupdate.begin (); + if (efupdate.hasError ()) + { + // logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); + // DEBUG_V ("efupdate.hasError"); + String ErrorMsg; + WebMgr.efupdate.getError (ErrorMsg); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + ErrorMsg.c_str())); + break; + } } // DEBUG_V ("Sending data to efupdate"); @@ -862,16 +894,18 @@ void c_WebMgr::FirmwareUpload (AsyncWebServerRequest* request, if (efupdate.hasError ()) { - logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); + // logcon (String(CN_stars) + F (" UPDATE ERROR: ") + String (efupdate.getError ())); // DEBUG_V ("efupdate.hasError"); - request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + String (efupdate.getError ()).c_str())); + String ErrorMsg; + WebMgr.efupdate.getError (ErrorMsg); + request->send (500, CN_textSLASHplain, (String (F ("Update Error: ")) + ErrorMsg.c_str())); break; } // DEBUG_V ("No EFUpdate Error"); if (final) { - request->send (200, CN_textSLASHplain, (String ( F ("Update Finished: ")) + String (efupdate.getError ())).c_str()); + request->send (200, CN_textSLASHplain, (String ( F ("Update Finished")))); logcon (F ("Upload Finished. Rebooting")); efupdate.end (); RequestReboot(100000);