From b2de8735c8813d2ce6d29788ce11bfa0922b8fd9 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 16 Dec 2015 19:45:21 +0100 Subject: [PATCH 1/3] check current flash before starting update, to avoid update problems. see: #1111 --- cores/esp8266/Updater.cpp | 10 ++++++++++ cores/esp8266/Updater.h | 16 +++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index 7ad21300a..ee7fe0b0f 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -57,6 +57,14 @@ bool UpdaterClass::begin(size_t size, int command) { return false; } + if(ESP.getFlashChipRealSize() != ESP.getFlashChipSize()) { + _error = UPDATE_ERROR_FLASH_CONFIG; +#ifdef DEBUG_UPDATER + printError(DEBUG_UPDATER); +#endif + return false; + } + _reset(); _error = 0; @@ -278,6 +286,8 @@ void UpdaterClass::printError(Stream &out){ out.println("Stream Read Timeout"); } else if(_error == UPDATE_ERROR_MD5){ out.println("MD5 Check Failed"); + } else if(_error == UPDATE_ERROR_FLASH_CONFIG){ + out.printf("Flash config wrong real: %d IDE: %d\n", ESP.getFlashChipRealSize(), ESP.getFlashChipSize()); } else { out.println("UNKNOWN"); } diff --git a/cores/esp8266/Updater.h b/cores/esp8266/Updater.h index a25cb081b..07b2708ec 100644 --- a/cores/esp8266/Updater.h +++ b/cores/esp8266/Updater.h @@ -5,13 +5,15 @@ #include "flash_utils.h" #include "MD5Builder.h" -#define UPDATE_ERROR_OK 0 -#define UPDATE_ERROR_WRITE 1 -#define UPDATE_ERROR_ERASE 2 -#define UPDATE_ERROR_SPACE 3 -#define UPDATE_ERROR_SIZE 4 -#define UPDATE_ERROR_STREAM 5 -#define UPDATE_ERROR_MD5 6 +#define UPDATE_ERROR_OK (0) +#define UPDATE_ERROR_WRITE (1) +#define UPDATE_ERROR_ERASE (2) +#define UPDATE_ERROR_SPACE (3) +#define UPDATE_ERROR_SIZE (4) +#define UPDATE_ERROR_STREAM (5) +#define UPDATE_ERROR_MD5 (6) +#define UPDATE_ERROR_FLASH_CONFIG (7) + #define U_FLASH 0 #define U_SPIFFS 100 From 28dd31a80f95df8a45e92e277ea5ab62310ff7f7 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 16 Dec 2015 23:05:23 +0100 Subject: [PATCH 2/3] add advanced error handling for HTTP update see: #1111 --- .../ESP8266HTTPClient/src/ESP8266HTTPClient.h | 2 +- .../examples/httpUpdate/httpUpdate.ino | 2 +- .../httpUpdateSPIFFS/httpUpdateSPIFFS.ino | 2 +- .../src/ESP8266httpUpdate.cpp | 66 ++++++++++++++++++- .../ESP8266httpUpdate/src/ESP8266httpUpdate.h | 12 ++++ 5 files changed, 79 insertions(+), 5 deletions(-) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h index 5f7490f86..74a27af5d 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h @@ -153,7 +153,7 @@ class HTTPClient { int writeToStream(Stream * stream); String getString(void); - String errorToString(int error); + static String errorToString(int error); protected: diff --git a/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino b/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino index bc9160a6e..c7da7139b 100644 --- a/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino +++ b/libraries/ESP8266httpUpdate/examples/httpUpdate/httpUpdate.ino @@ -45,7 +45,7 @@ void loop() { switch(ret) { case HTTP_UPDATE_FAILED: - USE_SERIAL.println("HTTP_UPDATE_FAILD"); + USE_SERIAL.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break; case HTTP_UPDATE_NO_UPDATES: diff --git a/libraries/ESP8266httpUpdate/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino b/libraries/ESP8266httpUpdate/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino index 3d746af6c..a993386cf 100644 --- a/libraries/ESP8266httpUpdate/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino +++ b/libraries/ESP8266httpUpdate/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino @@ -48,7 +48,7 @@ void loop() { switch(ret) { case HTTP_UPDATE_FAILED: - USE_SERIAL.println("HTTP_UPDATE_FAILD"); + USE_SERIAL.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); break; case HTTP_UPDATE_NO_UPDATES: diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp index 2eacf09db..4ee378f47 100644 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp @@ -82,6 +82,54 @@ t_httpUpdate_return ESP8266HTTPUpdate::update(String host, uint16_t port, String return handleUpdate(&http, current_version.c_str(), reboot, false); } +/** + * return error code as int + * @return int error code + */ +int ESP8266HTTPUpdate::getLastError(void){ + return lastError; +} + +/** + * return error code as String + * @return String error + */ +String ESP8266HTTPUpdate::getLastErrorString(void) { + + if(lastError == 0) { + return String(); // no error + } + + // error from Update class + if(lastError > 0) { + StreamString error; + Update.printError(error); + error.trim(); // remove line ending + return "Update error: " + error; + } + + // error from http client + if(lastError > -100) { + return "HTTP error: " + HTTPClient::errorToString(lastError); + } + + switch(lastError) { + case HTTP_UE_TOO_LESS_SPACE: + return String("To less space"); + case HTTP_UE_SERVER_NOT_REPORT_SIZE: + return String("Server not Report Size"); + case HTTP_UE_SERVER_FILE_NOT_FOUND: + return String("File not Found (404)"); + case HTTP_UE_SERVER_FORBIDDEN: + return String("Forbidden (403)"); + case HTTP_UE_SERVER_WRONG_HTTP_CODE: + return String("Wrong HTTP code"); + } + + return String(); +} + + /** * * @param http HTTPClient * @@ -122,10 +170,12 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha if(code <= 0) { DEBUG_HTTP_UPDATE("[httpUpdate] HTTP error: %s\n", http->errorToString(code).c_str()); + lastError = code; http->end(); return HTTP_UPDATE_FAILED; } + DEBUG_HTTP_UPDATE("[httpUpdate] Header read fin.\n"); DEBUG_HTTP_UPDATE("[httpUpdate] Server header:\n"); DEBUG_HTTP_UPDATE("[httpUpdate] - code: %d\n", code); @@ -161,6 +211,7 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha } if(!startUpdate) { + lastError = HTTP_UE_TOO_LESS_SPACE; ret = HTTP_UPDATE_FAILED; } else { @@ -196,6 +247,7 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha } } } else { + lastError = HTTP_UE_SERVER_NOT_REPORT_SIZE; ret = HTTP_UPDATE_FAILED; DEBUG_HTTP_UPDATE("[httpUpdate] Content-Length is 0 or not set by Server?!\n"); } @@ -204,16 +256,23 @@ t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate(HTTPClient * http, const cha ///< Not Modified (No updates) ret = HTTP_UPDATE_NO_UPDATES; break; + case HTTP_CODE_NOT_FOUND: + lastError = HTTP_UE_SERVER_FILE_NOT_FOUND; + ret = HTTP_UPDATE_FAILED; + break; + case HTTP_CODE_FORBIDDEN: + lastError = HTTP_UE_SERVER_FORBIDDEN; + ret = HTTP_UPDATE_FAILED; + break; default: + lastError = HTTP_UE_SERVER_WRONG_HTTP_CODE; ret = HTTP_UPDATE_FAILED; DEBUG_HTTP_UPDATE("[httpUpdate] HTTP Code is (%d)\n", code); //http->writeToStream(&Serial1); break; } - http->end(); - return ret; } @@ -229,6 +288,7 @@ bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int com StreamString error; if(!Update.begin(size, command)) { + lastError = Update.getError(); Update.printError(error); error.trim(); // remove line ending DEBUG_HTTP_UPDATE("[httpUpdate] Update.begin failed! (%s)\n", error.c_str()); @@ -240,6 +300,7 @@ bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int com } if(Update.writeStream(in) != size) { + lastError = Update.getError(); Update.printError(error); error.trim(); // remove line ending DEBUG_HTTP_UPDATE("[httpUpdate] Update.writeStream failed! (%s)\n", error.c_str()); @@ -247,6 +308,7 @@ bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int com } if(!Update.end()) { + lastError = Update.getError(); Update.printError(error); error.trim(); // remove line ending DEBUG_HTTP_UPDATE("[httpUpdate] Update.end failed! (%s)\n", error.c_str()); diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h index 6a13f9ce3..c8061c715 100644 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h @@ -38,6 +38,13 @@ #define DEBUG_HTTP_UPDATE(...) #endif +/// note we use HTTP client errors too so we start at 100 +#define HTTP_UE_TOO_LESS_SPACE (-100) +#define HTTP_UE_SERVER_NOT_REPORT_SIZE (-101) +#define HTTP_UE_SERVER_FILE_NOT_FOUND (-102) +#define HTTP_UE_SERVER_FORBIDDEN (-103) +#define HTTP_UE_SERVER_WRONG_HTTP_CODE (-104) + typedef enum { HTTP_UPDATE_FAILED, HTTP_UPDATE_NO_UPDATES, @@ -55,9 +62,14 @@ class ESP8266HTTPUpdate { t_httpUpdate_return updateSpiffs(const char * url, const char * current_version = "", const char * httpsFingerprint = "", bool reboot = false); + int getLastError(void); + String getLastErrorString(void); + protected: t_httpUpdate_return handleUpdate(HTTPClient * http, const char * current_version, bool reboot = true, bool spiffs = false); bool runUpdate(Stream& in, uint32_t size, String md5, int command = U_FLASH); + + int lastError; }; extern ESP8266HTTPUpdate ESPhttpUpdate; From f57ab609ecc5a63ac23d2363db1916405bf56ab1 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 17 Dec 2015 13:02:14 +0100 Subject: [PATCH 3/3] move flash size check to a function in ESP class, allow real size bigger the IDE for Update --- cores/esp8266/Esp.cpp | 18 ++++++++++++++++++ cores/esp8266/Esp.h | 2 ++ cores/esp8266/Updater.cpp | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index 5d39874fb..2c35597d4 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -298,6 +298,24 @@ uint32_t EspClass::getFlashChipSizeByChipId(void) { } } +/** + * check the Flash settings from IDE against the Real flash size + * @param needsEquals (return only true it equals) + * @return ok or not + */ +bool EspClass::checkFlashConfig(bool needsEquals) { + if(needsEquals) { + if(getFlashChipRealSize() == getFlashChipSize()) { + return true; + } + } else { + if(getFlashChipRealSize() >= getFlashChipSize()) { + return true; + } + } + return false; +} + String EspClass::getResetInfo(void) { if(resetInfo.reason != 0) { char buff[200]; diff --git a/cores/esp8266/Esp.h b/cores/esp8266/Esp.h index 07e1c093b..4201ec47d 100644 --- a/cores/esp8266/Esp.h +++ b/cores/esp8266/Esp.h @@ -117,6 +117,8 @@ class EspClass { FlashMode_t getFlashChipMode(); uint32_t getFlashChipSizeByChipId(); + bool checkFlashConfig(bool needsEquals = false); + bool flashEraseSector(uint32_t sector); bool flashWrite(uint32_t offset, uint32_t *data, size_t size); bool flashRead(uint32_t offset, uint32_t *data, size_t size); diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index ee7fe0b0f..ec2411064 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -57,7 +57,7 @@ bool UpdaterClass::begin(size_t size, int command) { return false; } - if(ESP.getFlashChipRealSize() != ESP.getFlashChipSize()) { + if(ESP.checkFlashConfig(false)) { _error = UPDATE_ERROR_FLASH_CONFIG; #ifdef DEBUG_UPDATER printError(DEBUG_UPDATER);