Skip to content

Pass in filesystem rather than requiring SPIFFS (Fixes #74) #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,12 @@ In this example a version 1 of 'esp32-fota-http' is in use, it would be updated
```cpp
#include <esp32fota.h>
#include <WiFi.h>
#include <SPIFFS.h>

const char *ssid = "";
const char *password = "";

esp32FOTA esp32FOTA("esp32-fota-http", "1.0.0");
esp32FOTA esp32FOTA("esp32-fota-http", "1.0.0", SPIFFS);

void setup()
{
Expand Down
8 changes: 5 additions & 3 deletions examples/HTTP/HTTP.ino
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@

*/

#include <SPIFFS.h>
#include <esp32fota.h>
#include <WiFi.h>
#include <SPIFFS.h>

// Change to your WiFi credentials
const char *ssid = "";
const char *password = "";

// esp32fota esp32fota("<Type of Firme for this device>", <this version>, <validate signature>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, false);
// esp32FOTA esp32FOTA("<Type of Firmware for this device>", <this version>, <filesystem>, <validate signature>, <allow insecure https>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, SPIFFS, false, false);

void setup_wifi()
{
Expand Down Expand Up @@ -59,4 +61,4 @@ void loop()
}

delay(2000);
}
}
6 changes: 3 additions & 3 deletions examples/HTTP/HTTPS.ino
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
const char *ssid = "";
const char *password = "";

// esp32fota esp32fota("<Type of Firme for this device>", <this version>, <validate signature>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, false);
// esp32FOTA esp32FOTA("<Type of Firmware for this device>", <this version>, <filesystem>, <validate signature>, <allow insecure https>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, SPIFFS, false, false);

void setup_wifi()
{
Expand Down Expand Up @@ -69,4 +69,4 @@ void loop()
}

delay(2000);
}
}
6 changes: 3 additions & 3 deletions examples/HTTP/HTTPS_without_root_cert.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
const char *ssid = "";
const char *password = "";

// esp32fota esp32fota("<Type of Firmware for this device>", <this version>, <validate signature>, <allow insecure https>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, false, true);
// esp32FOTA esp32FOTA("<Type of Firmware for this device>", <this version>, <filesystem>, <validate signature>, <allow insecure https>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, SPIFFS, false, true);

void setup_wifi()
{
Expand Down Expand Up @@ -66,4 +66,4 @@ void loop()
}

delay(2000);
}
}
6 changes: 3 additions & 3 deletions examples/HTTP/HTTP_signature_check.ino
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
const char *ssid = "";
const char *password = "";

// esp32fota esp32fota("<Type of Firme for this device>", <this version>, <validate signature>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, true);
// esp32FOTA esp32FOTA("<Type of Firmware for this device>", <this version>, <filesystem>, <validate signature>, <allow insecure https>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, SPIFFS, true, false);

void setup_wifi()
{
Expand Down Expand Up @@ -66,4 +66,4 @@ void loop()
}

delay(2000);
}
}
7 changes: 4 additions & 3 deletions examples/forceUpdate/forceUpdate.ino
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@

#include <esp32fota.h>
#include <WiFi.h>
#include <SPIFFS.h>

// Change to your WiFi credentials
const char *ssid = "";
const char *password = "";

// esp32fota esp32fota("<Type of Firmware for this device>", <this version>, <validate signature>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, false);
// esp32FOTA esp32FOTA("<Type of Firmware for this device>", <this version>, <filesystem>, <validate signature>, <allow insecure https>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, SPIFFS, false, false);

void setup()
{
Expand Down Expand Up @@ -57,4 +58,4 @@ void loop()
// Alternatively, forceUpdate can be called with a complete URL:
//esp32FOTA.forceUpdate("http://192.168.0.100/fota/esp32-fota-http-2.bin", true ); // check signature: true

}
}
7 changes: 4 additions & 3 deletions examples/withDeviceID/withDeviceID.ino
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@

#include <esp32fota.h>
#include <WiFi.h>
#include <SPIFFS.h>

// Change to your WiFi credentials
const char *ssid = "";
const char *password = "";

// esp32fota esp32fota("<Type of Firme for this device>", <this version>, <validate signature>);
esp32FOTA FOTA("esp32-fota-http", 1, false);
// esp32FOTA esp32FOTA("<Type of Firmware for this device>", <this version>, <filesystem>, <validate signature>, <allow insecure https>);
esp32FOTA esp32FOTA("esp32-fota-http", 1, SPIFFS, false, false);

void setup()
{
Expand Down Expand Up @@ -60,4 +61,4 @@ void loop()
}

delay(2000);
}
}
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "esp32FOTA",
"version": "0.1.6",
"version": "1.0.0",
"keywords": "firmware, OTA, Over The Air Updates, ArduinoOTA",
"description": "Allows for firmware to be updated from a webserver, the device can check for updates at any time. Uses a simple JSON file to outline if a new firmware is avaiable.",
"examples": "examples/*/*.ino",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=esp32FOTA
version=0.1.6
version=1.0.0
author=Chris Joyce
maintainer=Chris Joyce <chris@joyce.id.au>
sentence=A simple library for firmware OTA updates
Expand Down
54 changes: 34 additions & 20 deletions src/esp32fota.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Author: Moritz Meintker <https://thinksilicon.de>
Remarks: Re-written/removed a bunch of functions around HTTPS. The library is
now URL-agnostic. This means if you provide an https://-URL it will
use the root_ca.pem (needs to be provided via SPIFFS) to verify the
use the root_ca.pem (needs to be provided via SPIFFS/LITTLEFS) to verify the
server certificate and then download the ressource through an encrypted
connection unless you set the allow_insecure_https option.
Otherwise it will just use plain HTTP which will still offer to sign
Expand All @@ -22,7 +22,6 @@
#include <Update.h>
#include "ArduinoJson.h"
#include <FS.h>
#include <SPIFFS.h>


#include "mbedtls/pk.h"
Expand All @@ -32,36 +31,49 @@

#include <WiFiClientSecure.h>

esp32FOTA::esp32FOTA(String firmwareType, int firmwareVersion, boolean validate, boolean allow_insecure_https)
esp32FOTA::esp32FOTA(String firmwareType, int firmwareVersion, const fs::FS& fs, boolean validate, boolean allow_insecure_https)
:useDeviceID(false), _fs(fs), _firmwareType(firmwareType), _firmwareVersion(semver_t{firmwareVersion}), _check_sig(validate),_allow_insecure_https(allow_insecure_https)
{
_firmwareType = firmwareType;
_firmwareVersion = semver_t{firmwareVersion};
_check_sig = validate;
_allow_insecure_https = allow_insecure_https;
useDeviceID = false;

char version_no[256] = {'\0'}; // If we are passed firmwareVersion as an int, we're assuming it's a major version
semver_render(&_firmwareVersion, version_no);
log_i("Current firmware version: %s", version_no );

}

esp32FOTA::esp32FOTA(String firmwareType, String firmwareSemanticVersion, boolean validate, boolean allow_insecure_https)

esp32FOTA::esp32FOTA(String firmwareType, String firmwareSemanticVersion, const fs::FS& fs, boolean validate, boolean allow_insecure_https)
:useDeviceID(false), _fs(fs), _firmwareType(firmwareType), _check_sig(validate),_allow_insecure_https(allow_insecure_https)
{
if (semver_parse(firmwareSemanticVersion.c_str(), &_firmwareVersion)) {
log_e( "Invalid semver string %s passed to constructor. Defaulting to 0", firmwareSemanticVersion.c_str() );
_firmwareVersion = semver_t {0};
}

_firmwareType = firmwareType;
_check_sig = validate;
_allow_insecure_https = allow_insecure_https;
useDeviceID = false;

char version_no[256] = {'\0'};
semver_render(&_firmwareVersion, version_no);
log_i("Current firmware version: %s", version_no );
}


esp32FOTA::esp32FOTA(String firmwareType, int firmwareVersion, const fs::FS& fs, boolean validate, boolean allow_insecure_https, String url)
:useDeviceID(false), checkURL(url), _fs(fs), _firmwareType(firmwareType), _firmwareVersion(semver_t{firmwareVersion}), _check_sig(validate),_allow_insecure_https(allow_insecure_https)
{
char version_no[256] = {'\0'}; // If we are passed firmwareVersion as an int, we're assuming it's a major version
semver_render(&_firmwareVersion, version_no);
log_i("Current firmware version: %s", version_no );
}


esp32FOTA::esp32FOTA(String firmwareType, String firmwareSemanticVersion, const fs::FS& fs, boolean validate, boolean allow_insecure_https, String url)
:useDeviceID(false), checkURL(url), _fs(fs), _firmwareType(firmwareType), _check_sig(validate),_allow_insecure_https(allow_insecure_https)
{
if (semver_parse(firmwareSemanticVersion.c_str(), &_firmwareVersion)) {
log_e( "Invalid semver string %s passed to constructor. Defaulting to 0", firmwareSemanticVersion.c_str() );
_firmwareVersion = semver_t {0};
}

char version_no[256] = {'\0'};
semver_render(&_firmwareVersion, version_no);
log_i("Current firmware version: %s", version_no );
}


Expand All @@ -79,7 +91,7 @@ bool esp32FOTA::validate_sig( unsigned char *signature, uint32_t firmware_size )
mbedtls_md_context_t rsa;

{ // Open RSA public key:
File public_key_file = SPIFFS.open( "/rsa_key.pub" );
fs::File public_key_file = _fs.open( "/rsa_key.pub" );
if( !public_key_file ) {
log_e( "Failed to open rsa_key.pub for reading" );
return false;
Expand Down Expand Up @@ -189,7 +201,7 @@ void esp32FOTA::execOTA()
// and provide the root_ca.pem
log_i( "Loading root_ca.pem" );
//WiFiClientSecure client;
File root_ca_file = SPIFFS.open( "/root_ca.pem" );
fs::File root_ca_file = _fs.open( "/root_ca.pem" );
if( !root_ca_file ) {
log_e( "Could not open root_ca.pem" );
return;
Expand Down Expand Up @@ -388,6 +400,7 @@ bool esp32FOTA::execHTTPcheck()

log_i("Getting HTTP: %s",useURL.c_str());
log_i("------");

if ((WiFi.status() != WL_CONNECTED)) { //Check the current connection status
log_w("WiFi not connected - skipping HTTP check");
return false; // WiFi not connected
Expand All @@ -400,7 +413,7 @@ bool esp32FOTA::execHTTPcheck()
if (!_allow_insecure_https) {
// If the checkURL is https load the root-CA and connect with that
log_i( "Loading root_ca.pem" );
File root_ca_file = SPIFFS.open( "/root_ca.pem" );
fs::File root_ca_file = _fs.open( "/root_ca.pem" );
if( !root_ca_file ) {
log_e( "Could not open root_ca.pem" );
return false;
Expand All @@ -421,6 +434,7 @@ bool esp32FOTA::execHTTPcheck()
} else {
http.begin(useURL); //Specify the URL
}

int httpCode = http.GET(); //Make the request

if( httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY ) { //Check is a file was returned
Expand Down Expand Up @@ -450,7 +464,7 @@ bool esp32FOTA::execHTTPcheck()
}
}
} else if (JSONResult.is<JsonObject>()) {
if(checkJSONManifest(JSONResult.as<JsonVariant>()))
if(checkJSONManifest(JSONResult.as<JsonVariant>()))
return true;
}

Expand Down
14 changes: 11 additions & 3 deletions src/esp32fota.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Author: Moritz Meintker <https://thinksilicon.de>
Remarks: Re-written/removed a bunch of functions around HTTPS. The library is
now URL-agnostic. This means if you provide an https://-URL it will
use the root_ca.pem (needs to be provided via SPIFFS) to verify the
use the root_ca.pem (needs to be provided via SPIFFS/LittleFS) to verify the
server certificate and then download the ressource through an encrypted
connection.
Otherwise it will just use plain HTTP which will still offer to sign
Expand All @@ -19,14 +19,21 @@
#define esp32fota_h

#include <Arduino.h>
#include <FS.h>
#include <ArduinoJson.h>
#include "semver/semver.h"

class esp32FOTA
{
using File = fs::File;
using FS = fs::FS;

public:
esp32FOTA(String firwmareType, int firwmareVersion, boolean validate = false, boolean allow_insecure_https = false );
esp32FOTA(String firwmareType, String firmwareSemanticVersion, boolean validate = false, boolean allow_insecure_https = false );
esp32FOTA(String firwmareType, int firwmareVersion, const fs::FS& fs, boolean validate, boolean allow_insecure_https);
esp32FOTA(String firwmareType, String firmwareSemanticVersion, const fs::FS& fs, boolean validate, boolean allow_insecure_https);

esp32FOTA(String firwmareType, int firwmareVersion, const fs::FS& fs, boolean validate, boolean allow_insecure_https, String url);
esp32FOTA(String firwmareType, String firmwareSemanticVersion, const fs::FS& fs, boolean validate, boolean allow_insecure_https, String url);
~esp32FOTA();
void forceUpdate(String firmwareHost, uint16_t firmwarePort, String firmwarePath, boolean validate );
void forceUpdate(String firmwareURL, boolean validate );
Expand All @@ -40,6 +47,7 @@ class esp32FOTA
bool validate_sig( unsigned char *signature, uint32_t firmware_size );

private:
FS _fs;
String getDeviceID();
String _firmwareType;
semver_t _firmwareVersion = {0};
Expand Down
4 changes: 2 additions & 2 deletions src/semver/semver.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,15 +499,15 @@ semver_free (semver_t *x) {
*/

static void
concat_num (char * str, int x, char * sep) {
concat_num (char * str, int x, const char * sep) {
char buf[SLICE_SIZE] = {0};
if (sep == NULL) sprintf(buf, "%d", x);
else sprintf(buf, "%s%d", sep, x);
strcat(str, buf);
}

static void
concat_char (char * str, char * x, char * sep) {
concat_char (char * str, char * x, const char * sep) {
char buf[SLICE_SIZE] = {0};
sprintf(buf, "%s%s", sep, x);
strcat(str, buf);
Expand Down