|
|
|
#include "XD0OTA.h"
|
|
|
|
|
|
|
|
#include <WiFi.h>
|
|
|
|
#include <WiFiClient.h>
|
|
|
|
|
|
|
|
#include <HTTPClient.h>
|
|
|
|
#include <HTTPUpdate.h>
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
static const char* TAG = "OTA";
|
|
|
|
|
|
|
|
XD0OTA::XD0OTA(String deviceName) : deviceName{deviceName} {}
|
|
|
|
|
|
|
|
// Set time via NTP, as required for x.509 validation
|
|
|
|
void XD0OTA::setClock() {
|
|
|
|
configTime(0, 0, "pool.ntp.org", "time.nist.gov"); // UTC
|
|
|
|
|
|
|
|
Serial.print(F("Waiting for NTP time sync: "));
|
|
|
|
time_t now = time(nullptr);
|
|
|
|
int tries = 0;
|
|
|
|
while (now < 8 * 3600 * 2) {
|
|
|
|
yield();
|
|
|
|
delay(500);
|
|
|
|
Serial.print(F("."));
|
|
|
|
now = time(nullptr);
|
|
|
|
tries++;
|
|
|
|
if (tries>15) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Serial.println(F(""));
|
|
|
|
struct tm timeinfo;
|
|
|
|
gmtime_r(&now, &timeinfo);
|
|
|
|
Serial.print(F("Current time: "));
|
|
|
|
Serial.print(asctime(&timeinfo));
|
|
|
|
}
|
|
|
|
|
|
|
|
String XD0OTA::getMAC() {
|
|
|
|
uint8_t mac[6];
|
|
|
|
char result[14];
|
|
|
|
|
|
|
|
WiFi.macAddress( mac );
|
|
|
|
snprintf( result, sizeof( result ), "%02x%02x%02x%02x%02x%02x", mac[ 0 ], mac[ 1 ], mac[ 2 ], mac[ 3 ], mac[ 4 ], mac[ 5 ] );
|
|
|
|
|
|
|
|
return String( result );
|
|
|
|
}
|
|
|
|
|
|
|
|
String XD0OTA::getUpdateURL(String file, String extension) {
|
|
|
|
String updateURL = String(fwUrlBase);
|
|
|
|
updateURL.concat(file);
|
|
|
|
updateURL.concat(extension);
|
|
|
|
return updateURL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XD0OTA::update(void) {
|
|
|
|
setClock();
|
|
|
|
|
|
|
|
// try device specific image first
|
|
|
|
String fwURL = getUpdateURL(getMAC(), ".bin");
|
|
|
|
int newVersion = checkForUpdates(fwURL + ".version");
|
|
|
|
|
|
|
|
if (newVersion < 1) {
|
|
|
|
ESP_LOGW(TAG, "[update] no device specific update found..\n");
|
|
|
|
fwURL = getUpdateURL(deviceName, ".bin");
|
|
|
|
newVersion = checkForUpdates(fwURL + ".version");
|
|
|
|
// try project specific image
|
|
|
|
if (newVersion < 1) {
|
|
|
|
ESP_LOGW(TAG, "[update] Error while looking for updates..\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( newVersion > FW_VERSION ) {
|
|
|
|
ESP_LOGW(TAG, "Preparing to update.\n" );
|
|
|
|
|
|
|
|
ESP_LOGW(TAG, "Firmware image URL: " );
|
|
|
|
ESP_LOGW(TAG, "%s\n", fwURL.c_str() );
|
|
|
|
|
|
|
|
WiFiClientSecure client;
|
|
|
|
client.setCACert(rootCACertificate);
|
|
|
|
|
|
|
|
client.setTimeout(12); // seconds
|
|
|
|
|
|
|
|
httpUpdate.setLedPin(LED_BUILTIN, HIGH);
|
|
|
|
|
|
|
|
t_httpUpdate_return ret = httpUpdate.update( client, fwURL );
|
|
|
|
|
|
|
|
switch(ret) {
|
|
|
|
case HTTP_UPDATE_FAILED:
|
|
|
|
ESP_LOGW(TAG, "HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
|
|
|
|
break;
|
|
|
|
case HTTP_UPDATE_NO_UPDATES:
|
|
|
|
ESP_LOGW(TAG, "HTTP_UPDATE_NO_UPDATES\n");
|
|
|
|
break;
|
|
|
|
case HTTP_UPDATE_OK:
|
|
|
|
ESP_LOGW(TAG, "[update] Update ok.\n"); // may not called we reboot the ESP
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ESP_LOGW(TAG, "[update] Already on latest version\n" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int XD0OTA::checkForUpdates(String url) {
|
|
|
|
int newVersion = -1;
|
|
|
|
|
|
|
|
ESP_LOGW(TAG, "Checking for firmware updates.\n" );
|
|
|
|
ESP_LOGW(TAG, "Firmware version URL: " );
|
|
|
|
ESP_LOGW(TAG, "%s\n", url.c_str() );
|
|
|
|
|
|
|
|
WiFiClientSecure client;
|
|
|
|
client.setCACert(rootCACertificate);
|
|
|
|
client.setTimeout(5); // seconds
|
|
|
|
|
|
|
|
HTTPClient httpClient;
|
|
|
|
|
|
|
|
httpClient.begin( client, url );
|
|
|
|
int httpCode = httpClient.GET();
|
|
|
|
if( httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY ) {
|
|
|
|
String newFWVersion = httpClient.getString();
|
|
|
|
|
|
|
|
ESP_LOGW(TAG, "Current firmware version: " );
|
|
|
|
ESP_LOGW(TAG, "%s\n", String(FW_VERSION).c_str() );
|
|
|
|
ESP_LOGW(TAG, "Available firmware version: " );
|
|
|
|
ESP_LOGW(TAG, "%s\n", newFWVersion.c_str() );
|
|
|
|
|
|
|
|
newVersion = newFWVersion.toInt();
|
|
|
|
} else {
|
|
|
|
ESP_LOGW(TAG, "Firmware version check failed, got HTTP response code " );
|
|
|
|
ESP_LOGW(TAG, "%d\n", httpCode );
|
|
|
|
newVersion = -1;
|
|
|
|
}
|
|
|
|
httpClient.end();
|
|
|
|
client.stop();
|
|
|
|
return newVersion;
|
|
|
|
}
|