Hendrik Langer
5 years ago
6 changed files with 237 additions and 2 deletions
@ -0,0 +1,13 @@ |
|||||
|
Import("env") |
||||
|
|
||||
|
import time |
||||
|
|
||||
|
ver = time.time() |
||||
|
|
||||
|
f = open("version.txt", "w") |
||||
|
f.write(str(ver)) |
||||
|
f.close() |
||||
|
|
||||
|
env.Append(CPPDEFINES=[ |
||||
|
("FW_VERSION", ver) |
||||
|
]) |
@ -0,0 +1,132 @@ |
|||||
|
#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); |
||||
|
while (now < 8 * 3600 * 2) { |
||||
|
yield(); |
||||
|
delay(500); |
||||
|
Serial.print(F(".")); |
||||
|
now = time(nullptr); |
||||
|
} |
||||
|
|
||||
|
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(); |
||||
|
return newVersion; |
||||
|
} |
@ -0,0 +1,84 @@ |
|||||
|
#ifndef _XD0OTA_H |
||||
|
#define _XD0OTA_H |
||||
|
|
||||
|
#include <Arduino.h> |
||||
|
|
||||
|
class XD0OTA { |
||||
|
public: |
||||
|
XD0OTA(String deviceName); |
||||
|
void update(void); |
||||
|
int checkForUpdates(String url); |
||||
|
private: |
||||
|
String deviceName; |
||||
|
const char* fwUrlBase = "https://fwupdate.xd0.de:444/fota/"; |
||||
|
const char* httpsFingerprint = "37 42 61 B9 E6 EE 22 36 D1 59 67 7D 55 53 6E A4 C7 AA 60 26"; |
||||
|
const char* rootCACertificate = \ |
||||
|
"-----BEGIN CERTIFICATE-----\n" \ |
||||
|
"MIID8DCCAtigAwIBAgIJAPSONy8RRejRMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD\n" \ |
||||
|
"VQQGEwJERTEeMBwGA1UECAwVTm9ydGhyaGluZS1XZXN0cGhhbGlhMQ4wDAYDVQQH\n" \ |
||||
|
"DAVFc3NlbjEPMA0GA1UECgwGeGQwLmRlMRgwFgYDVQQDDA9md3VwZGF0ZS54ZDAu\n" \ |
||||
|
"ZGUxITAfBgkqhkiG9w0BCQEWEmhlbmRyaWsrZGV2QHhkMC5kZTAgFw0xODA2MTYx\n" \ |
||||
|
"MTAzMTVaGA8yMDY4MDYxNjExMDMxNVowgYsxCzAJBgNVBAYTAkRFMR4wHAYDVQQI\n" \ |
||||
|
"DBVOb3J0aHJoaW5lLVdlc3RwaGFsaWExDjAMBgNVBAcMBUVzc2VuMQ8wDQYDVQQK\n" \ |
||||
|
"DAZ4ZDAuZGUxGDAWBgNVBAMMD2Z3dXBkYXRlLnhkMC5kZTEhMB8GCSqGSIb3DQEJ\n" \ |
||||
|
"ARYSaGVuZHJpaytkZXZAeGQwLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" \ |
||||
|
"CgKCAQEAx37S1YgaG74IhTysaaZQMFI50TDeGkxxdpNoIBX0UBeVtKI/3u3MAqBz\n" \ |
||||
|
"kKTDHFu4IQDj0PvBdlqPFGdSinFgrIvr49uAr+alNKUtkuSTT7nXI0fzqAxv1taj\n" \ |
||||
|
"0mNhigVvYikX2BUU/rNLnQclyBdPNVsOf9cv0t5+UcOHRt6oEwk5nFtG7s7k4+wu\n" \ |
||||
|
"wRdGlLy2LwLihYFon4LHAs05JW3qs0IQI4etc8E2JWjF2YwBg3+ooyzUFFIGjPSl\n" \ |
||||
|
"Lpi7WvAAR19HITbt5FJXQkFZnFxnfbQv/5f7n8vWfFmzYsEgvldwMZv+Eg6wPb2h\n" \ |
||||
|
"rgH7T6RSb55JrZE/JUY5C6pKvTJ3AwIDAQABo1MwUTAdBgNVHQ4EFgQUCnZywNj+\n" \ |
||||
|
"djz6n0sIARPx8dp+7bQwHwYDVR0jBBgwFoAUCnZywNj+djz6n0sIARPx8dp+7bQw\n" \ |
||||
|
"DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAto7IGXpNYTiPUgnA\n" \ |
||||
|
"DE6osdgSV1yVYJj75v+Y8aUGgQ93Ipl/0+PQL99wbGgjDhfxGADLtljwoEAz/fep\n" \ |
||||
|
"RqCh8swjL34XV9XjMzfhEMDCybSO6mK7ZmCKwhz9yBaK/Qjdj0YUoLhJ9Huzb70m\n" \ |
||||
|
"lGzbOhY4JJKFVaA5AcZhYHqjCmzHCVJ/H0zeuPGyKutbvSx23a24LmebfY4q2D62\n" \ |
||||
|
"U85ox3Ojek6Mc8J4V+RjORygDGAO4gZClEhAza4koAg7lCO/kSSk5PrXdlz2dqtA\n" \ |
||||
|
"D5Npv9M5363apnO1VlVR+OuO1NEJusRK1aWk9RLZsTPxzwOWwdkifXxUEJ+f8mGn\n" \ |
||||
|
"o+6SCw==\n" \ |
||||
|
"-----END CERTIFICATE-----\n"; |
||||
|
String getMAC(void); |
||||
|
String getUpdateURL(String file, String extension); |
||||
|
void setClock(void); |
||||
|
}; |
||||
|
|
||||
|
#endif /* _XD0OTA_H */ |
||||
|
|
||||
|
|
||||
|
/*
|
||||
|
|
||||
|
MAKE SURE TO RESET THE ESP8266 ONCE AFTER NORMAL FLASHING! OTHERWISE OTA WON'T WORK! |
||||
|
|
||||
|
|
||||
|
openssl req -x509 -nodes -days 18263 -newkey rsa:2048 -keyout /etc/ssl/private/xd0-fwupdate-selfsigned.key -out /etc/ssl/certs/xd0-fwupdate-selfsigned.crt |
||||
|
|
||||
|
openssl x509 -noout -fingerprint -sha1 -inform pem -in /etc/ssl/certs/xd0-fwupdate-selfsigned.crt |
||||
|
|
||||
|
|
||||
|
scp .pioenvs/nodemcuv2/firmware.bin user@webserver:/var/www/fwupdate/fota/macaddress.bin |
||||
|
and change macaddress.version |
||||
|
|
||||
|
|
||||
|
server { |
||||
|
listen 444 ssl; |
||||
|
listen [::]:444 ssl; |
||||
|
server_name fwupdate.xd0.de; |
||||
|
|
||||
|
# SSL configuration |
||||
|
ssl_certificate /etc/ssl/certs/xd0-fwupdate-selfsigned.crt; |
||||
|
ssl_certificate_key /etc/ssl/private/xd0-fwupdate-selfsigned.key; |
||||
|
ssl_buffer_size 4k; |
||||
|
|
||||
|
root /var/www/fwupdate; |
||||
|
|
||||
|
location / { |
||||
|
# First attempt to serve request as file, then |
||||
|
# as directory, then fall back to displaying a 404. |
||||
|
try_files $uri $uri/ =404; |
||||
|
} |
||||
|
|
||||
|
access_log /var/log/nginx/fwupdate_access.log; |
||||
|
error_log /var/log/nginx/fwupdate_error.log; |
||||
|
} |
||||
|
|
||||
|
*/ |
Loading…
Reference in new issue