Skip to content

Commit

Permalink
Cherry picked @vortigont's #101
Browse files Browse the repository at this point in the history
  • Loading branch information
tobozo committed Sep 29, 2022
1 parent a3a85f8 commit aa66960
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 34 deletions.
68 changes: 36 additions & 32 deletions src/esp32FOTA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ bool esp32FOTA::execOTA()
{
setupStream();

if( _flashFileSystemUrl != "" ) { // a data partition was specified in the json manifest, handle the spiffs partition first
if( !_flashFileSystemUrl.isEmpty() ) { // a data partition was specified in the json manifest, handle the spiffs partition first
if( _fs ) { // Possible risk of overwriting certs and signatures, cancel flashing!
Serial.println("Cowardly refusing to overwrite U_SPIFFS with "+_flashFileSystemUrl+". Use setCertFileSystem(nullptr) along with setPubKey()/setCAPem() to enable this feature.");
return false;
Expand All @@ -410,10 +410,10 @@ bool esp32FOTA::execOTA()
bool esp32FOTA::execOTA( int partition, bool restart_after )
{
// health checks
if( partition == U_SPIFFS && _flashFileSystemUrl == "" ) {
if( partition == U_SPIFFS && _flashFileSystemUrl.isEmpty() ) {
log_i("[SKIP] No spiffs/littlefs/fatfs partition was specified");
return true; // data partition is optional, so not an error
} else if ( partition == U_FLASH && _firmwareUrl == "" ) {
} else if ( partition == U_FLASH && _firmwareUrl.isEmpty() ) {
log_e("No app partition was specified");
return false; // app partition is mandatory
} else if( partition != U_SPIFFS && partition != U_FLASH ) {
Expand Down Expand Up @@ -481,11 +481,11 @@ bool esp32FOTA::execOTA( int partition, bool restart_after )

if ( written == fwsize ) {
Serial.println("Written : " + String(written) + " successfully");
updateSize = written; // flatten value to prevent overflow when checking signature
} else {
Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Premature end of stream?");
F_abort();
return false;
//updateSize = written; // flatten value to prevent overflow when checking signature
}

if (!F_UpdateEnd()) {
Expand Down Expand Up @@ -594,8 +594,8 @@ bool esp32FOTA::checkJSONManifest(JsonVariant doc)
}
log_i("Payload type in manifest %s matches current firmware %s", doc["type"].as<const char *>(), _cfg.name );

_flashFileSystemUrl = "";
_firmwareUrl = "";
_flashFileSystemUrl.clear();
_firmwareUrl.clear();

if(doc["version"].is<uint16_t>()) {
uint16_t v = doc["version"].as<uint16_t>();
Expand All @@ -614,26 +614,26 @@ bool esp32FOTA::checkJSONManifest(JsonVariant doc)
debugSemVer("Payload firmware version", _payload_sem.ver() );

// Memoize some values to help with the decision tree
bool has_url = doc.containsKey("url") && doc["url"].is<String>();
bool has_firmware = doc.containsKey("bin") && doc["bin"].is<String>();
bool has_hostname = doc.containsKey("host") && doc["host"].is<String>();
bool has_port = doc.containsKey("port") && doc["port"].is<uint16_t>();
uint16_t portnum = has_port ? doc["port"].as<uint16_t>() : 0;
bool has_url = doc["url"].is<const char*>();
bool has_firmware = doc["bin"].is<const char*>();
bool has_hostname = doc["host"].is<const char*>();
bool has_port = doc["port"].is<uint16_t>();
uint16_t portnum = doc["port"].as<uint16_t>();
bool has_tls = has_port ? (portnum == 443 || portnum == 4433) : false;
bool has_spiffs = doc.containsKey("spiffs") && doc["spiffs"].is<String>();
bool has_littlefs = doc.containsKey("littlefs") && doc["littlefs"].is<String>();
bool has_fatfs = doc.containsKey("fatfs") && doc["fatfs"].is<String>();
bool has_spiffs = doc["spiffs"].is<const char*>();
bool has_littlefs = doc["littlefs"].is<const char*>();
bool has_fatfs = doc["fatfs"].is<const char*>();
bool has_filesystem = has_littlefs || has_spiffs || has_fatfs;

String protocol = has_tls ? "https" : "http";
String protocol(has_tls ? "https" : "http");
String flashFSPath =
has_filesystem
? (
has_littlefs
? doc["littlefs"].as<String>()
? doc["littlefs"].as<const char*>()
: has_spiffs
? doc["spiffs"].as<String>()
: doc["fatfs"].as<String>()
? doc["spiffs"].as<const char*>()
: doc["fatfs"].as<const char*>()
)
: "";

Expand All @@ -646,14 +646,14 @@ bool esp32FOTA::checkJSONManifest(JsonVariant doc)
);

if( has_url ) { // Basic scenario: a complete URL was provided in the JSON manifest, all other keys will be ignored
_firmwareUrl = doc["url"].as<String>();
_firmwareUrl = doc["url"].as<const char*>();
if( has_hostname ) { // If the manifest provides both, warn the user
log_w("Manifest provides both url and host - Using URL");
}
} else if( has_firmware && has_hostname && has_port ) { // Precise scenario: Hostname, Port and Firmware Path were provided
_firmwareUrl = protocol + "://" + doc["host"].as<String>() + ":" + String( portnum ) + doc["bin"].as<String>();
_firmwareUrl = protocol + "://" + doc["host"].as<const char*>() + ":" + portnum + doc["bin"].as<const char*>();
if( has_filesystem ) { // More complex scenario: the manifest also provides a [spiffs, littlefs or fatfs] partition
_flashFileSystemUrl = protocol + "://" + doc["host"].as<String>() + ":" + String( portnum ) + flashFSPath;
_flashFileSystemUrl = protocol + "://" + doc["host"].as<const char*>() + ":" + portnum + flashFSPath;
}
} else { // JSON was malformed - no firmware target was provided
log_e("JSON manifest was missing one of the required keys :(" );
Expand All @@ -676,7 +676,7 @@ bool esp32FOTA::execHTTPcheck()
String useURL = String( _cfg.manifest_url );

// being deprecated, soon unsupported!
if( useURL=="" && checkURL!="" ) {
if( useURL.isEmpty() && !checkURL.isEmpty() ) {
Serial.println("checkURL will soon be unsupported, use FOTAConfig_t::manifest_url instead!!");
useURL = checkURL;
}
Expand All @@ -701,6 +701,7 @@ bool esp32FOTA::execHTTPcheck()
log_i("Getting HTTP: %s", useURL.c_str());
log_i("------");

//_http.useHTTP10(true);
if(! setupHTTP( useURL.c_str() ) ) {
log_e("Unable to setup http, aborting!");
return false;
Expand All @@ -721,19 +722,18 @@ bool esp32FOTA::execHTTPcheck()
return false;
}

String payload = _http.getString();
_http.end(); // We're done with HTTP - free the resources

// TODO: use payload.length() to speculate on JSONResult buffer size
#define JSON_FW_BUFF_SIZE 2048
DynamicJsonDocument JSONResult( JSON_FW_BUFF_SIZE );
DeserializationError err = deserializeJson( JSONResult, payload.c_str() );
DeserializationError err = deserializeJson( JSONResult, _http.getStream() );

if (err) { // Check for errors in parsing, or JSON length may exceed buffer size
Serial.printf("JSON Parsing failed (%s, in=%d bytes, buff=%d bytes):\n%s\n", err.c_str(), payload.length(), JSON_FW_BUFF_SIZE, payload.c_str() );
Serial.printf("JSON Parsing failed (%s, in=%d bytes, buff=%d bytes):\n", err.c_str(), _http.getSize(), JSON_FW_BUFF_SIZE );
return false;
}

_http.end(); // We're done with HTTP - free the resources

if (JSONResult.is<JsonArray>()) {
// Although improbable given the size on JSONResult buffer, we already received an array of multiple firmware types and/or versions
JsonArray arr = JSONResult.as<JsonArray>();
Expand Down Expand Up @@ -764,19 +764,23 @@ String esp32FOTA::getDeviceID()


// Force a firmware update regardless on current version
void esp32FOTA::forceUpdate(String firmwareURL, bool validate )
void esp32FOTA::forceUpdate(const char* firmwareURL, bool validate )
{
_firmwareUrl = firmwareURL;
_cfg.check_sig = validate;
execOTA();
}


void esp32FOTA::forceUpdate(String firmwareHost, uint16_t firmwarePort, String firmwarePath, bool validate )
void esp32FOTA::forceUpdate(const char* firmwareHost, uint16_t firmwarePort, const char* firmwarePath, bool validate )
{
String firmwareURL = ( firmwarePort == 443 || firmwarePort == 4433 ) ? "https" : "http";
firmwareURL += firmwareHost + ":" + String( firmwarePort ) + firmwarePath;
forceUpdate( firmwareURL, validate );
String firmwareURL("http");
if ( firmwarePort == 443 || firmwarePort == 4433 ) firmwareURL += "s";
firmwareURL += String(firmwareHost);
firmwareURL += ":";
firmwareURL += String(firmwarePort);
firmwareURL += firmwarePath;
forceUpdate( firmwareURL.c_str(), validate );
}


Expand Down
4 changes: 2 additions & 2 deletions src/esp32FOTA.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ class esp32FOTA : public UpdateClass

//template <class U> static U& getInstance() { static U updater; return updater; }

void forceUpdate(String firmwareHost, uint16_t firmwarePort, String firmwarePath, bool validate );
void forceUpdate(String firmwareURL, bool validate );
void forceUpdate(const char* firmwareHost, uint16_t firmwarePort, const char* firmwarePath, bool validate );
void forceUpdate(const char* firmwareURL, bool validate );
void forceUpdate(bool validate );

bool execOTA();
Expand Down

0 comments on commit aa66960

Please sign in to comment.