From b805d1b18399895c7142acc6f0c87ceac1878001 Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Thu, 28 Nov 2019 06:48:16 +0100 Subject: [PATCH] Updater: Better flow for performing updates; added MD5 validation. --- include/updater.h | 8 ++-- src/main.cpp | 4 +- src/updater.cpp | 113 ++++++++++++++++++++-------------------------- update.manifest | 2 + 4 files changed, 58 insertions(+), 69 deletions(-) diff --git a/include/updater.h b/include/updater.h index b781fc2..3aa76b7 100644 --- a/include/updater.h +++ b/include/updater.h @@ -1,8 +1,10 @@ #pragma once +#include "http_client_wrapper.h" + class Updater { public: - static void run(); - static bool do_update(int cmd, String url); - static void update_spiffs(); + static void run(uint16_t spiffs_version = 0); + static bool do_update(int cmd, String url, String expected_md5); + static bool read_line(String* dst, HTTPClientWrapper* http, String expected_key); }; diff --git a/src/main.cpp b/src/main.cpp index e32d8d7..7b5804d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -136,9 +136,7 @@ void setup() { } #ifdef OTA_UPDATE_URL - if (spiffs_version < OTA_VERSION) { - Updater::run(); - } + Updater::run(spiffs_version); #endif INFO("Initialization completed.\n"); diff --git a/src/updater.cpp b/src/updater.cpp index 9d956c3..e0a9351 100644 --- a/src/updater.cpp +++ b/src/updater.cpp @@ -4,7 +4,8 @@ #include "updater.h" #include "http_client_wrapper.h" -void Updater::run() { +void Updater::run(uint16_t spiffs_version) { + bool update_image = true; DEBUG("Updater is running...\n"); HTTPClientWrapper* http = new HTTPClientWrapper(); DEBUG("Requesting update info...\n"); @@ -13,47 +14,74 @@ void Updater::run() { ERROR("Updater failed requesting %s.\n", OTA_UPDATE_URL); return; } - String line = http->readUntil("\n"); - if (!line.startsWith("VERSION=")) { - ERROR("Expected first line to be VERSION.\n"); + + String line_str = ""; + if (!read_line(&line_str, http, "VERSION")) { return; } - uint16_t version = line.substring(8).toInt(); + uint16_t version = line_str.toInt(); if (version==0) { ERROR("Could not parse version number.\n"); return; } DEBUG("Found version %d. My version is %d.\n", version, OTA_VERSION); if (version <= OTA_VERSION) { + if (spiffs_version>0 && spiffs_version < version) { + update_image = false; + DEBUG("SPIFFS needs an update. Continuing.\n"); + } else { + return; + } + } + + String image_path = ""; + if (!read_line(&image_path, http, "IMAGE_PATH")) { return; } - line = http->readUntil("\n"); - if (!line.startsWith("IMAGE_PATH=")) { - ERROR("Expected second line to be IMAGE_PATH.\n"); + + String image_md5 = ""; + if (!read_line(&image_md5, http, "IMAGE_MD5")) { return; } - String image_path = line.substring(11); - image_path.trim(); - line = http->readUntil("\n"); - if (!line.startsWith("SPIFFS_PATH=")) { - ERROR("Expected third line to be SPIFFS_PATH.\n"); + + String spiffs_path = ""; + if (!read_line(&spiffs_path, http, "SPIFFS_PATH")) { + return; + } + + String spiffs_md5 = ""; + if (!read_line(&spiffs_md5, http, "SPIFFS_MD5")) { return; } - String spiffs_path = line.substring(12); - spiffs_path.trim(); http->close(); delete http; - result = do_update(U_FLASH, image_path); + result = true; + if (update_image) { + result = do_update(U_FLASH, image_path, image_md5); + } if (result) { - do_update(U_SPIFFS, spiffs_path); + do_update(U_SPIFFS, spiffs_path, spiffs_md5); } DEBUG("Done. Rebooting...\n"); ESP.restart(); } -bool Updater::do_update(int command, String url) { +bool Updater::read_line(String* dst, HTTPClientWrapper* http, String expected_key) { + expected_key += "="; + String line = http->readUntil("\n"); + if (!line.startsWith(expected_key)) { + ERROR("Expected line start with '%s', but it started with '%s'.\n", expected_key.c_str(), line.c_str()); + return false; + } + line = line.substring(expected_key.length()); + line.trim(); + dst->concat(line); + return true; +} + +bool Updater::do_update(int command, String url, String expected_md5) { HTTPClientWrapper* http = new HTTPClientWrapper(); bool result = http->get(url); if (!result) { @@ -66,10 +94,11 @@ bool Updater::do_update(int command, String url) { ERROR("Update could not be started.\n"); return false; } + Update.setMD5(expected_md5.c_str()); uint8_t buf[512]; uint16_t len; while((len = http->read(buf, 512))) { - Update.write(buf, 512); + Update.write(buf, len); } http->close(); @@ -77,51 +106,9 @@ bool Updater::do_update(int command, String url) { result = Update.end(); if (!result) { - ERROR("Writing the update failed somewhere. Aborted.\n"); + const char* error = Update.errorString(); + ERROR("Writing the update failed. The error was: %s\n", error); return false; } return true; } - -void Updater::update_spiffs() { - HTTPClientWrapper* http = new HTTPClientWrapper(); - DEBUG("Requesting update info...\n"); - bool result = http->get(OTA_UPDATE_URL); - if (!result) { - ERROR("Updater failed requesting %s.\n", OTA_UPDATE_URL); - return; - } - String line = http->readUntil("\n"); - if (!line.startsWith("VERSION=")) { - ERROR("Expected first line to be VERSION.\n"); - return; - } - uint16_t version = line.substring(8).toInt(); - if (version==0) { - ERROR("Could not parse version number.\n"); - return; - } else if (version > OTA_VERSION) { - DEBUG("Found newer version %d. My version is %d. Starting full update!\n", version, OTA_VERSION); - run(); - } else { - DEBUG("Loading SPIFFS image.\n"); - line = http->readUntil("\n"); - if (!line.startsWith("IMAGE_PATH=")) { - ERROR("Expected second line to be IMAGE_PATH.\n"); - return; - } - line = http->readUntil("\n"); - if (!line.startsWith("SPIFFS_PATH=")) { - ERROR("Expected third line to be SPIFFS_PATH.\n"); - return; - } - String spiffs_path = line.substring(12); - spiffs_path.trim(); - do_update(U_SPIFFS, spiffs_path); - DEBUG("Done. Rebooting...\n"); - delay(500); - ESP.restart(); - } - http->close(); - delete http; -} diff --git a/update.manifest b/update.manifest index 69f7d45..7f0bdd5 100644 --- a/update.manifest +++ b/update.manifest @@ -1,3 +1,5 @@ VERSION=1 IMAGE_PATH=https://files.schle.nz/esmp3/firmware.bin +IMAGE_MD5=ead8d94ae8a3c9f46e7ee65e2270fd69 SPIFFS_PATH=https://files.schle.nz/esmp3/spiffs.bin +SPIFFS_MD5=9f3902e3312863da8326e7fbe9485c9e