Skip to content

Commit

Permalink
Added extended FW update error reporting to the user.
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinMueller2003 committed Dec 27, 2024
1 parent eeb76f5 commit 8438847
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 19 deletions.
24 changes: 21 additions & 3 deletions html/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -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!");
}
});
}));
Expand Down
12 changes: 8 additions & 4 deletions include/EFUpdate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;}
Expand Down Expand Up @@ -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_ */
109 changes: 101 additions & 8 deletions src/EFUpdate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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");
Expand All @@ -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));
Expand All @@ -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;
Expand Down Expand Up @@ -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");
Expand All @@ -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;

Expand All @@ -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
Expand All @@ -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)
Expand Down
42 changes: 38 additions & 4 deletions src/WebMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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");
Expand All @@ -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);
Expand Down

0 comments on commit 8438847

Please sign in to comment.