From bf36ac88cca98d84a1b7491b57d27956b7b2bb83 Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 23 Oct 2023 15:16:33 +0200 Subject: [PATCH 1/2] Reorder Arduino Nano RP2040 OTA error codes --- src/utility/ota/OTA-nano-rp2040.cpp | 47 ++++++++++++++++++++++------- src/utility/ota/OTA.h | 16 ---------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/utility/ota/OTA-nano-rp2040.cpp b/src/utility/ota/OTA-nano-rp2040.cpp index 4e3c1d047..89b079b69 100644 --- a/src/utility/ota/OTA-nano-rp2040.cpp +++ b/src/utility/ota/OTA-nano-rp2040.cpp @@ -34,6 +34,31 @@ #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, + 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 +117,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 +130,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 +140,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 +158,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 +167,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 +204,7 @@ 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); } /* Extract concent length from HTTP header. A typical entry looks like @@ -190,7 +215,7 @@ 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); @@ -219,7 +244,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 +254,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 +264,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 +272,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, }; /****************************************************************************** From a4019d451a24e19a2ed739daad1e6a3135f2cbc7 Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 23 Oct 2023 16:41:29 +0200 Subject: [PATCH 2/2] Nano RP2040 connect: Add http response check --- src/utility/ota/OTA-nano-rp2040.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/utility/ota/OTA-nano-rp2040.cpp b/src/utility/ota/OTA-nano-rp2040.cpp index 89b079b69..7e259f07a 100644 --- a/src/utility/ota/OTA-nano-rp2040.cpp +++ b/src/utility/ota/OTA-nano-rp2040.cpp @@ -53,6 +53,7 @@ enum class rp2040OTAError : int 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, @@ -207,6 +208,26 @@ int rp2040_connect_onOTARequest(char const * ota_url) 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 * "Content-Length: 123456" */ @@ -218,7 +239,7 @@ int rp2040_connect_onOTARequest(char const * ota_url) 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;