From f16d8686b84a93468abff0cc21f694a5d4f62006 Mon Sep 17 00:00:00 2001 From: platenspeler Date: Tue, 12 Jun 2018 16:42:31 +0200 Subject: [PATCH] Version 5.2.1; Update esp32 name, and add libraries specific for ESP32 --- ESP-sc-gway/ESP-sc-gway.ino | 28 +- ESP-sc-gway/oLED.h | 22 +- README.md | 2 +- libraries/esp32-http-update/README.md | 17 + .../examples/httpUpdate/httpUpdate.ino | 57 +++ .../httpUpdateSPIFFS/httpUpdateSPIFFS.ino | 61 +++ .../esp32-http-update/library.properties | 9 + .../esp32-http-update/src/ESP32httpUpdate.cpp | 389 ++++++++++++++++++ .../esp32-http-update/src/ESP32httpUpdate.h | 116 ++++++ 9 files changed, 687 insertions(+), 14 deletions(-) create mode 100644 libraries/esp32-http-update/README.md create mode 100644 libraries/esp32-http-update/examples/httpUpdate/httpUpdate.ino create mode 100644 libraries/esp32-http-update/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino create mode 100644 libraries/esp32-http-update/library.properties create mode 100644 libraries/esp32-http-update/src/ESP32httpUpdate.cpp create mode 100644 libraries/esp32-http-update/src/ESP32httpUpdate.h diff --git a/ESP-sc-gway/ESP-sc-gway.ino b/ESP-sc-gway/ESP-sc-gway.ino index 2d4db88..cfd9eea 100644 --- a/ESP-sc-gway/ESP-sc-gway.ino +++ b/ESP-sc-gway/ESP-sc-gway.ino @@ -958,7 +958,9 @@ void setup() { char MAC_char[19]; // XXX Unbelievable MAC_char[18] = 0; - + + Serial.begin(_BAUDRATE); // As fast as possible for bus + delay(100); #ifdef ESP32 Serial.println(F("ESP32 defined")); @@ -967,9 +969,6 @@ void setup() { Serial.println(F("ARDUINO_ARCH_ESP32 defined")); #endif - - Serial.begin(_BAUDRATE); // As fast as possible for bus - delay(100); #if DUSB>=1 Serial.flush(); @@ -1015,7 +1014,10 @@ void setup() { yield(); } #endif + WiFi.mode(WIFI_STA); + WiFi.begin(); + WlanReadWpa(); // Read the last Wifi settings from SPIFFS into memory WiFi.macAddress(MAC_array); @@ -1029,18 +1031,22 @@ void setup() { // We start by connecting to a WiFi network, set hostname char hostname[12]; - sprintf(hostname, "%s%02x%02x%02x", "esp8266-", MAC_array[3], MAC_array[4], MAC_array[5]); -#if ESP32_ARCH==1 - WiFi.setHostname( hostname ); -#else - wifi_station_set_hostname( hostname ); -#endif + // Setup WiFi UDP connection. Give it some time and retry 50 times.. while (WlanConnect(50) < 0) { Serial.print(F("Error Wifi network connect ")); Serial.println(); yield(); - } + } + +#if ESP32_ARCH==1 + sprintf(hostname, "%s%02x%02x%02x", "esp32-", MAC_array[3], MAC_array[4], MAC_array[5]); + WiFi.setHostname( hostname ); +#else + sprintf(hostname, "%s%02x%02x%02x", "esp8266-", MAC_array[3], MAC_array[4], MAC_array[5]); + wifi_station_set_hostname( hostname ); +#endif + Serial.print(F("Host ")); #if ESP32_ARCH==1 diff --git a/ESP-sc-gway/oLED.h b/ESP-sc-gway/oLED.h index c183b64..c2f15ee 100644 --- a/ESP-sc-gway/oLED.h +++ b/ESP-sc-gway/oLED.h @@ -26,18 +26,36 @@ // 1. 0.9" OLED (cheap) // 2. 1.3" OLED with much better display -#if OLED>=1 +#if OLED>=1 // If OLED is used +// -------------------------------------------------------- +// Define the diffretn PIN's used for SCL/SDA for each arch. +// +#if _PIN_OUT==1 // HALLARD #define OLED_SCL 5 // GPIO5 / D1 #define OLED_SDA 4 // GPIO4 / D2 +#elif _PIN_OUT==2 // COMRESULT +#define OLED_SCL 0 // GPIO0 / D3 +#define OLED_SDA 2 // GPIO2 / D4 + +#elif _PIN_OUT==4 // TTGO (onboard version used, also for DIY) +#define OLED_SCL 5 // GPIO5 / D1 +#define OLED_SDA 4 // GPIO4 / D2 + +#endif + + +// -------------------------------------------------------- +// Define the different OLED versions +// #if OLED==1 #include "SSD1306.h" #define OLED_ADDR 0x3C // Default 0x3C for 0.9", for 1.3" it is 0x78 SSD1306 display(OLED_ADDR, OLED_SDA, OLED_SCL);// i2c ADDR & SDA, SCL on wemos #endif -// This is an 1.3" OLED display which is runnint on I2C +// This is an 1.3" OLED display which is running on I2C #if OLED==2 #include "SH1106.h" #define OLED_ADDR 0x3C // Default 0x3C for 1.3" SH1106 diff --git a/README.md b/README.md index 8fe613e..2e3cd42 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Single Channel LoRaWAN Gateway -Version 5.2.0, May 30, 2018 +Version 5.2.1, June 06, 2018 Author: M. Westenberg (mw12554@hotmail.com) Copyright: M. Westenberg (mw12554@hotmail.com) diff --git a/libraries/esp32-http-update/README.md b/libraries/esp32-http-update/README.md new file mode 100644 index 0000000..1839d11 --- /dev/null +++ b/libraries/esp32-http-update/README.md @@ -0,0 +1,17 @@ +# ESP32 HTTP Firmware Update (OTA) + +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/03b36fac07824cd08884e1f19bb34fcb)](https://www.codacy.com/app/suculent/esp32-http-update?utm_source=github.com&utm_medium=referral&utm_content=suculent/esp32-http-update&utm_campaign=Badge_Grade) + +ESP Clone of https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266httpUpdate (most work done by Markus Sattler). + +# TL;DR + +This is just a quick port of ESP8266httpUpdate for ESP32. + +Buildable with Arduino framework for ESP32. + +There are things remaining to be solved: + +* Some headers are deprecated (will change for ESP32 anyway) +* Download to SPIFFS with AES-256 decryption +* Does not support ESP-IDF. diff --git a/libraries/esp32-http-update/examples/httpUpdate/httpUpdate.ino b/libraries/esp32-http-update/examples/httpUpdate/httpUpdate.ino new file mode 100644 index 0000000..d79594f --- /dev/null +++ b/libraries/esp32-http-update/examples/httpUpdate/httpUpdate.ino @@ -0,0 +1,57 @@ +/** + * httpUpdate.ino + * + * Created on: 27.11.2015 + * + */ + +#include + +#include + +#include +#include + +#define USE_SERIAL Serial + +void setup() { + + USE_SERIAL.begin(115200); + // USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFi.begin("SSID", "PASSWORD"); + +} + +void loop() { + // wait for WiFi connection + if((WiFi.status() == WL_CONNECTED)) { + + t_httpUpdate_return ret = ESPhttpUpdate.update("http://server/file.bin"); + + switch(ret) { + case HTTP_UPDATE_FAILED: + USE_SERIAL.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); + break; + + case HTTP_UPDATE_NO_UPDATES: + USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES"); + break; + + case HTTP_UPDATE_OK: + USE_SERIAL.println("HTTP_UPDATE_OK"); + break; + } + } +} + diff --git a/libraries/esp32-http-update/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino b/libraries/esp32-http-update/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino new file mode 100644 index 0000000..365461b --- /dev/null +++ b/libraries/esp32-http-update/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino @@ -0,0 +1,61 @@ +/** + * httpUpdateSPIFFS.ino + * + * Created on: 27.11.2017 + * + */ + +#include + +#include + +#include +#include + +#define USE_SERIAL Serial + +void setup() { + + USE_SERIAL.begin(115200); + // USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFi.begin("SSID", "PASSWORD"); + +} + +void loop() { + // wait for WiFi connection + if((WiFi.status() == WL_CONNECTED)) { + + USE_SERIAL.println("Update SPIFFS..."); + t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs("http://server/spiffs.bin"); + if(ret == HTTP_UPDATE_OK) { + USE_SERIAL.println("Update sketch..."); + ret = ESPhttpUpdate.update("http://server/file.bin"); + + switch(ret) { + case HTTP_UPDATE_FAILED: + USE_SERIAL.printf("HTTP_UPDATE_FAILED Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); + break; + + case HTTP_UPDATE_NO_UPDATES: + USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES"); + break; + + case HTTP_UPDATE_OK: + USE_SERIAL.println("HTTP_UPDATE_OK"); + break; + } + } + } +} diff --git a/libraries/esp32-http-update/library.properties b/libraries/esp32-http-update/library.properties new file mode 100644 index 0000000..1d2474d --- /dev/null +++ b/libraries/esp32-http-update/library.properties @@ -0,0 +1,9 @@ +name=ESP32httpUpdate +version=2.1.145 +author=Matej Sychra +maintainer=Matej Sychra +sentence=Http Update for ESP32 +paragraph=Quick clone of Arduino ESP8266httpUpdate for ESP32 (without HTTPS requirement) +category=Data Processing +url=https://github.com/suculent/esp32-http-update +architectures=esp32 diff --git a/libraries/esp32-http-update/src/ESP32httpUpdate.cpp b/libraries/esp32-http-update/src/ESP32httpUpdate.cpp new file mode 100644 index 0000000..5aca24d --- /dev/null +++ b/libraries/esp32-http-update/src/ESP32httpUpdate.cpp @@ -0,0 +1,389 @@ +/** + * + * @file ESP32HTTPUpdate.cpp + * @date 27.11.2017 + * @author Matej Sychra + * + * Copyright (c) 2017 Matej Sychra. All rights reserved. + * This file is part of the ESP32 Http Updater. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "ESP32httpUpdate.h" +#include + +ESP32HTTPUpdate::ESP32HTTPUpdate(void) +{ +} + +ESP32HTTPUpdate::~ESP32HTTPUpdate(void) +{ +} + +HTTPUpdateResult ESP32HTTPUpdate::update(const String& url, const String& currentVersion, + const String& httpsCertificate, bool reboot) +{ + rebootOnUpdate(reboot); + return update(url, currentVersion, httpsCertificate); +} + +HTTPUpdateResult ESP32HTTPUpdate::update(const String& url, const String& currentVersion) +{ + HTTPClient http; + http.begin(url); + return handleUpdate(http, currentVersion, false); +} + +HTTPUpdateResult ESP32HTTPUpdate::update(const String& url, const String& currentVersion, + const String& httpsCertificate) +{ + HTTPClient http; + const char * cacert = strdup(httpsCertificate.c_str()); + http.begin(url, cacert); + return handleUpdate(http, currentVersion, false); +} + +HTTPUpdateResult ESP32HTTPUpdate::updateSpiffs(const String& url, const String& currentVersion, const String& httpsCertificate) +{ + HTTPClient http; + const char * cacert = strdup(httpsCertificate.c_str()); + http.begin(url, cacert); + return handleUpdate(http, currentVersion, true); +} + +HTTPUpdateResult ESP32HTTPUpdate::updateSpiffs(const String& url, const String& currentVersion) +{ + HTTPClient http; + http.begin(url); + return handleUpdate(http, currentVersion, true); +} + +HTTPUpdateResult ESP32HTTPUpdate::update(const String& host, uint16_t port, const String& uri, const String& currentVersion, + bool https, const String& httpsCertificate, bool reboot) +{ + rebootOnUpdate(reboot); + if (httpsCertificate.length() == 0) { + return update(host, port, uri, currentVersion); + } else { + return update(host, port, uri, currentVersion, httpsCertificate); + } +} + +HTTPUpdateResult ESP32HTTPUpdate::update(const String& host, uint16_t port, const String& uri, + const String& currentVersion) +{ + HTTPClient http; + http.begin(host, port, uri); + return handleUpdate(http, currentVersion, false); +} +HTTPUpdateResult ESP32HTTPUpdate::update(const String& host, uint16_t port, const String& url, + const String& currentVersion, const String& httpsCertificate) +{ + HTTPClient http; + const char * cacert = strdup(httpsCertificate.c_str()); + http.begin(host, port, url, cacert); + return handleUpdate(http, currentVersion, false); + +} + +/** + * return error code as int + * @return int error code + */ +int ESP32HTTPUpdate::getLastError(void) +{ + return _lastError; +} + +/** + * return error code as String + * @return String error + */ +String ESP32HTTPUpdate::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 String(F("Update error: ")) + error; + } + + // error from http client + if(_lastError > -100) { + return String(F("HTTP error: ")) + HTTPClient::errorToString(_lastError); + } + + switch(_lastError) { + case HTTP_UE_TOO_LESS_SPACE: + return F("To less space"); + case HTTP_UE_SERVER_NOT_REPORT_SIZE: + return F("Server not Report Size"); + case HTTP_UE_SERVER_FILE_NOT_FOUND: + return F("File not Found (404)"); + case HTTP_UE_SERVER_FORBIDDEN: + return F("Forbidden (403)"); + case HTTP_UE_SERVER_WRONG_HTTP_CODE: + return F("Wrong HTTP code"); + case HTTP_UE_SERVER_FAULTY_MD5: + return F("Faulty MD5"); + case HTTP_UE_BIN_VERIFY_HEADER_FAILED: + return F("Verify bin header failed"); + case HTTP_UE_BIN_FOR_WRONG_FLASH: + return F("bin for wrong flash size"); + } + + return String(); +} + + +/** + * + * @param http HTTPClient * + * @param currentVersion const char * + * @return HTTPUpdateResult + */ +HTTPUpdateResult ESP32HTTPUpdate::handleUpdate(HTTPClient& http, const String& currentVersion, bool spiffs) +{ + + HTTPUpdateResult ret = HTTP_UPDATE_FAILED; + + // use HTTP/1.0 for update since the update handler not support any transfer Encoding + http.useHTTP10(true); + http.setTimeout(30000); // allow time to download on slower networks + http.setUserAgent(F("ESP32-http-Update")); + http.addHeader(F("x-ESP32-STA-MAC"), WiFi.macAddress()); + http.addHeader(F("x-ESP32-AP-MAC"), WiFi.softAPmacAddress()); + // http.addHeader(F("x-ESP32-free-space"), String(ESP.getFreeSketchSpace())); + // http.addHeader(F("x-ESP32-sketch-size"), String(ESP.getSketchSize())); + // http.addHeader(F("x-ESP32-sketch-md5"), String(ESP.getSketchMD5())); + // http.addHeader(F("x-ESP32-chip-size"), String(ESP.getFlashChipRealSize())); + http.addHeader(F("x-ESP32-sdk-version"), ESP.getSdkVersion()); + + if(spiffs) { + http.addHeader(F("x-ESP32-mode"), F("spiffs")); + } else { + http.addHeader(F("x-ESP32-mode"), F("sketch")); + } + + if(currentVersion && currentVersion[0] != 0x00) { + http.addHeader(F("x-ESP32-version"), currentVersion); + } + + const char * headerkeys[] = { "x-MD5" }; + size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*); + + // track these headers + http.collectHeaders(headerkeys, headerkeyssize); + + + int code = http.GET(); + int len = http.getSize(); + + 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); + DEBUG_HTTP_UPDATE("[httpUpdate] - len: %d\n", len); + + if(http.hasHeader("x-MD5")) { + DEBUG_HTTP_UPDATE("[httpUpdate] - MD5: %s\n", http.header("x-MD5").c_str()); + } + + if(currentVersion && currentVersion[0] != 0x00) { + DEBUG_HTTP_UPDATE("[httpUpdate] - current version: %s\n", currentVersion.c_str() ); + } + + switch(code) { + case HTTP_CODE_OK: ///< OK (Start Update) + if(len > 0) { + bool startUpdate = true; + if(spiffs) { + size_t spiffsSize = ((size_t) SPIFFS.totalBytes() - (size_t) SPIFFS.usedBytes()); + if(len > (int) spiffsSize) { + DEBUG_HTTP_UPDATE("[httpUpdate] spiffsSize to low (%d) needed: %d\n", spiffsSize, len); + startUpdate = false; + } + } else { + //if(len > (int) ESP.getFreeSketchSpace()) { + // DEBUG_HTTP_UPDATE("[httpUpdate] FreeSketchSpace to low (%d) needed: %d\n", ESP.getFreeSketchSpace(), len); + // startUpdate = false; + //} + } + + if(!startUpdate) { + _lastError = HTTP_UE_TOO_LESS_SPACE; + ret = HTTP_UPDATE_FAILED; + } else { + + WiFiClient * tcp = http.getStreamPtr(); + + //WiFiUDP::stopAll(); + //WiFiClient::stopAllExcept(tcp); + + delay(100); + + int command; + + if(spiffs) { + command = U_SPIFFS; + DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate spiffs...\n"); + } else { + command = U_FLASH; + DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate flash...\n"); + } + + if(!spiffs) { + + /* + uint8_t buf[4]; + if(tcp->peekBytes(&buf[0], 4) != 4) { + DEBUG_HTTP_UPDATE("[httpUpdate] peekBytes magic header failed\n"); + _lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED; + http.end(); + return HTTP_UPDATE_FAILED; + } + + // check for valid first magic byte + if(buf[0] != 0xE9) { + DEBUG_HTTP_UPDATE("[httpUpdate] magic header not starts with 0xE9\n"); + _lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED; + http.end(); + return HTTP_UPDATE_FAILED; + + } + */ + + // uint32_t bin_flash_size = ESP.magicFlashChipSize((buf[3] & 0xf0) >> 4); + + /* + // check if new bin fits to SPI flash + if(bin_flash_size > ESP.getFlashChipRealSize()) { + DEBUG_HTTP_UPDATE("[httpUpdate] magic header, new bin not fits SPI Flash\n"); + _lastError = HTTP_UE_BIN_FOR_WRONG_FLASH; + http.end(); + return HTTP_UPDATE_FAILED; + } + */ + } + + if(runUpdate(*tcp, len, http.header("x-MD5"), command)) { + ret = HTTP_UPDATE_OK; + DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n"); + http.end(); + + if(_rebootOnUpdate && !spiffs) { + ESP.restart(); + } + + } else { + ret = HTTP_UPDATE_FAILED; + DEBUG_HTTP_UPDATE("[httpUpdate] Update failed\n"); + } + } + } 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"); + } + break; + case HTTP_CODE_NOT_MODIFIED: + ///< 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; +} + +/** + * write Update to flash + * @param in Stream& + * @param size uint32_t + * @param md5 String + * @return true if Update ok + */ +bool ESP32HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int command) +{ + + 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()); + return false; + } + + if(md5.length()) { + if(!Update.setMD5(md5.c_str())) { + _lastError = HTTP_UE_SERVER_FAULTY_MD5; + DEBUG_HTTP_UPDATE("[httpUpdate] Update.setMD5 failed! (%s)\n", md5.c_str()); + return false; + } + } + + 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()); + return false; + } + + 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()); + return false; + } + + return true; +} + +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_HTTPUPDATE) +ESP32HTTPUpdate ESPhttpUpdate; +#endif diff --git a/libraries/esp32-http-update/src/ESP32httpUpdate.h b/libraries/esp32-http-update/src/ESP32httpUpdate.h new file mode 100644 index 0000000..31d45e9 --- /dev/null +++ b/libraries/esp32-http-update/src/ESP32httpUpdate.h @@ -0,0 +1,116 @@ +/** + * + * @file ESP32HTTPUpdate.h + * @date 27.11.2017 + * @author Matej Sychra + * + * Copyright (c) 2017 Matej Sychra. All rights reserved. + * This file is part of the ESP32 Http Updater. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef ESP32HTTPUPDATE_H_ +#define ESP32HTTPUPDATE_H_ + +#include +#include +#include +#include +#include +#include + +#include "FS.h" +#include "SPIFFS.h" + +#ifdef DEBUG_ESP_HTTP_UPDATE +#ifdef DEBUG_ESP_PORT +#define DEBUG_HTTP_UPDATE(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ ) +#endif +#endif + +#ifndef DEBUG_HTTP_UPDATE +#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) +#define HTTP_UE_SERVER_FAULTY_MD5 (-105) +#define HTTP_UE_BIN_VERIFY_HEADER_FAILED (-106) +#define HTTP_UE_BIN_FOR_WRONG_FLASH (-107) + +enum HTTPUpdateResult { + HTTP_UPDATE_FAILED, + HTTP_UPDATE_NO_UPDATES, + HTTP_UPDATE_OK +}; + +typedef HTTPUpdateResult t_httpUpdate_return; // backward compatibility + +class ESP32HTTPUpdate +{ +public: + ESP32HTTPUpdate(void); + ~ESP32HTTPUpdate(void); + + void rebootOnUpdate(bool reboot) + { + _rebootOnUpdate = reboot; + } + + // This function is deprecated, use rebootOnUpdate and the next one instead + t_httpUpdate_return update(const String& url, const String& currentVersion, + const String& httpsCertificate, bool reboot) __attribute__((deprecated)); + t_httpUpdate_return update(const String& url, const String& currentVersion = ""); + t_httpUpdate_return update(const String& url, const String& currentVersion, + const String& httpsCertificate); + + // This function is deprecated, use one of the overloads below along with rebootOnUpdate + t_httpUpdate_return update(const String& host, uint16_t port, const String& uri, const String& currentVersion, + bool https, const String& httpsCertificate, bool reboot) __attribute__((deprecated)); + + t_httpUpdate_return update(const String& host, uint16_t port, const String& uri = "/", + const String& currentVersion = ""); + t_httpUpdate_return update(const String& host, uint16_t port, const String& url, + const String& currentVersion, const String& httpsCertificate); + + // This function is deprecated, use rebootOnUpdate and the next one instead + t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion, + const String& httpsCertificate, bool reboot) __attribute__((deprecated)); + t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion = ""); + t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion, const String& httpsCertificate); + + + int getLastError(void); + String getLastErrorString(void); + +protected: + t_httpUpdate_return handleUpdate(HTTPClient& http, const String& currentVersion, bool spiffs = false); + bool runUpdate(Stream& in, uint32_t size, String md5, int command = U_FLASH); + + int _lastError; + bool _rebootOnUpdate = true; +}; + +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_HTTPUPDATE) +extern ESP32HTTPUpdate ESPhttpUpdate; +#endif + +#endif /* ESP32HTTPUPDATE_H_ */