diff --git a/src/utility/ota/OTA-nano-rp2040.cpp b/src/utility/ota/OTA-nano-rp2040.cpp index 4e3c1d047..7e259f07a 100644 --- a/src/utility/ota/OTA-nano-rp2040.cpp +++ b/src/utility/ota/OTA-nano-rp2040.cpp @@ -34,6 +34,32 @@ #include "FlashIAPBlockDevice.h" #include "utility/ota/FlashSHA256.h" +/****************************************************************************** + * DEFINES + ******************************************************************************/ + +#define RP2040_OTA_ERROR_BASE (-100) + +/****************************************************************************** + * TYPEDEF + ******************************************************************************/ + +enum class rp2040OTAError : int +{ + None = 0, + ErrorFlashInit = RP2040_OTA_ERROR_BASE - 3, + ErrorParseHttpHeader = RP2040_OTA_ERROR_BASE - 8, + UrlParseError = RP2040_OTA_ERROR_BASE - 9, + ServerConnectError = RP2040_OTA_ERROR_BASE - 10, + HttpHeaderError = RP2040_OTA_ERROR_BASE - 11, + HttpDataError = RP2040_OTA_ERROR_BASE - 12, + HttpResponse = RP2040_OTA_ERROR_BASE - 14, + ErrorOpenUpdateFile = RP2040_OTA_ERROR_BASE - 19, + ErrorWriteUpdateFile = RP2040_OTA_ERROR_BASE - 20, + ErrorReformat = RP2040_OTA_ERROR_BASE - 21, + ErrorUnmount = RP2040_OTA_ERROR_BASE - 22, +}; + /****************************************************************************** * FUNCTION DEFINITION ******************************************************************************/ @@ -92,7 +118,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) if ((err = flash.init()) < 0) { DEBUG_ERROR("%s: flash.init() failed with %d", __FUNCTION__, err); - return static_cast(OTAError::RP2040_ErrorFlashInit); + return static_cast(rp2040OTAError::ErrorFlashInit); } watchdog_reset(); @@ -105,7 +131,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) if ((err = fs.reformat(&flash)) != 0) { DEBUG_ERROR("%s: fs.reformat() failed with %d", __FUNCTION__, err); - return static_cast(OTAError::RP2040_ErrorReformat); + return static_cast(rp2040OTAError::ErrorReformat); } watchdog_reset(); @@ -115,7 +141,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) { DEBUG_ERROR("%s: fopen() failed", __FUNCTION__); fclose(file); - return static_cast(OTAError::RP2040_ErrorOpenUpdateFile); + return static_cast(rp2040OTAError::ErrorOpenUpdateFile); } watchdog_reset(); @@ -133,7 +159,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) } else { DEBUG_ERROR("%s: Failed to parse OTA URL %s", __FUNCTION__, ota_url); fclose(file); - return static_cast(OTAError::RP2040_UrlParseError); + return static_cast(rp2040OTAError::UrlParseError); } watchdog_reset(); @@ -142,7 +168,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) { DEBUG_ERROR("%s: Connection failure with OTA storage server %s", __FUNCTION__, url.host_.c_str()); fclose(file); - return static_cast(OTAError::RP2040_ServerConnectError); + return static_cast(rp2040OTAError::ServerConnectError); } watchdog_reset(); @@ -179,7 +205,27 @@ int rp2040_connect_onOTARequest(char const * ota_url) { DEBUG_ERROR("%s: Error receiving HTTP header %s", __FUNCTION__, is_http_header_timeout ? "(timeout)":""); fclose(file); - return static_cast(OTAError::RP2040_HttpHeaderError); + return static_cast(rp2040OTAError::HttpHeaderError); + } + + /* Check HTTP response status code */ + char const * http_response_ptr = strstr(http_header.c_str(), "HTTP/1.1"); + if (!http_response_ptr) + { + DEBUG_ERROR("%s: Failure to extract http response from header", __FUNCTION__); + return static_cast(rp2040OTAError::ErrorParseHttpHeader); + } + /* Find start of numerical value. */ + char * ptr = const_cast(http_response_ptr); + for (ptr += strlen("HTTP/1.1"); (*ptr != '\0') && !isDigit(*ptr); ptr++) { } + /* Extract numerical value. */ + String http_response_str; + for (; isDigit(*ptr); ptr++) http_response_str += *ptr; + int const http_response = atoi(http_response_str.c_str()); + + if (http_response != 200) { + DEBUG_ERROR("%s: HTTP response status code = %d", __FUNCTION__, http_response); + return static_cast(rp2040OTAError::HttpResponse); } /* Extract concent length from HTTP header. A typical entry looks like @@ -190,10 +236,10 @@ int rp2040_connect_onOTARequest(char const * ota_url) { DEBUG_ERROR("%s: Failure to extract content length from http header", __FUNCTION__); fclose(file); - return static_cast(OTAError::RP2040_ErrorParseHttpHeader); + return static_cast(rp2040OTAError::ErrorParseHttpHeader); } /* Find start of numerical value. */ - char * ptr = const_cast(content_length_ptr); + ptr = const_cast(content_length_ptr); for (; (*ptr != '\0') && !isDigit(*ptr); ptr++) { } /* Extract numerical value. */ String content_length_str; @@ -219,7 +265,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) { DEBUG_ERROR("%s: Writing of firmware image to flash failed", __FUNCTION__); fclose(file); - return static_cast(OTAError::RP2040_ErrorWriteUpdateFile); + return static_cast(rp2040OTAError::ErrorWriteUpdateFile); } bytes_received++; @@ -229,7 +275,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) if (bytes_received != content_length_val) { DEBUG_ERROR("%s: Error receiving HTTP data %s (%d bytes received, %d expected)", __FUNCTION__, is_http_data_timeout ? "(timeout)":"", bytes_received, content_length_val); fclose(file); - return static_cast(OTAError::RP2040_HttpDataError); + return static_cast(rp2040OTAError::HttpDataError); } DEBUG_INFO("%s: %d bytes received", __FUNCTION__, ftell(file)); @@ -239,7 +285,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) if ((err = fs.unmount()) != 0) { DEBUG_ERROR("%s: fs.unmount() failed with %d", __FUNCTION__, err); - return static_cast(OTAError::RP2040_ErrorUnmount); + return static_cast(rp2040OTAError::ErrorUnmount); } /* Perform the reset to reboot to SFU. */ @@ -247,7 +293,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) /* If watchdog is enabled we should not reach this point */ NVIC_SystemReset(); - return static_cast(OTAError::None); + return static_cast(rp2040OTAError::None); } String rp2040_connect_getOTAImageSHA256() diff --git a/src/utility/ota/OTA.h b/src/utility/ota/OTA.h index 88c7229b9..0d09341dd 100644 --- a/src/utility/ota/OTA.h +++ b/src/utility/ota/OTA.h @@ -28,12 +28,6 @@ #include #include -/****************************************************************************** - * DEFINES - ******************************************************************************/ - -#define RP2040_OTA_ERROR_BASE (-100) - /****************************************************************************** * TYPEDEF ******************************************************************************/ @@ -42,16 +36,6 @@ enum class OTAError : int { None = 0, DownloadFailed = 1, - RP2040_UrlParseError = RP2040_OTA_ERROR_BASE - 0, - RP2040_ServerConnectError = RP2040_OTA_ERROR_BASE - 1, - RP2040_HttpHeaderError = RP2040_OTA_ERROR_BASE - 2, - RP2040_HttpDataError = RP2040_OTA_ERROR_BASE - 3, - RP2040_ErrorOpenUpdateFile = RP2040_OTA_ERROR_BASE - 4, - RP2040_ErrorWriteUpdateFile = RP2040_OTA_ERROR_BASE - 5, - RP2040_ErrorParseHttpHeader = RP2040_OTA_ERROR_BASE - 6, - RP2040_ErrorFlashInit = RP2040_OTA_ERROR_BASE - 7, - RP2040_ErrorReformat = RP2040_OTA_ERROR_BASE - 8, - RP2040_ErrorUnmount = RP2040_OTA_ERROR_BASE - 9, }; /******************************************************************************