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);