Last active
February 25, 2019 00:25
ESP8266 OTA update over HTTPS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ESP8266-12 Firmware OTA update over HTTPS using WiFiClientBearSSL and CA certificate | |
// | |
/* | |
[env:nodemcuv2] | |
platform = https://github.com/platformio/platform-espressif8266.git#v2.0.0 | |
board = nodemcuv2 | |
framework = arduino | |
upload_port = /dev/tty.SLAB_USBtoUART | |
src_build_flags = -D STASSID=ssid | |
-D STAPSK=password | |
log: | |
espressif-esp8266 2.5.0 | |
PLATFORM: Espressif 8266 > NodeMCU 1.0 (ESP-12E Module) | |
HARDWARE: ESP8266 80MHz 80KB RAM (4MB Flash) | |
Dependency Graph | |
|-- <ESP8266httpUpdate> 1.3 | |
| |-- <ESP8266HTTPClient> 1.2 | |
| | |-- <ESP8266WiFi> 1.0 | |
| |-- <ESP8266WiFi> 1.0 | |
|-- <ESP8266WiFi> 1.0 | |
*/ | |
#include <time.h> | |
#include <ESP8266WiFi.h> | |
#include <WiFiClientSecure.h> | |
#include "ESP8266httpUpdate.h" | |
#define DEBUG_ESP_WIFI | |
#define VALUE_TO_STRING(x) #x | |
#define VALUE(x) VALUE_TO_STRING(x) | |
#ifndef STASSID | |
#define STASSID "" | |
#define STAPSK "" | |
#endif | |
const char *ssid = VALUE(STASSID); | |
const char *pass = VALUE(STAPSK); | |
const char * host = "192.168.1.10"; | |
const uint16_t port = 5000; | |
//ca_cer.pem | |
static const char digicert[] PROGMEM = R"EOF( | |
-----BEGIN CERTIFICATE----- | |
MIID/TCCAuWgAwIBAgIJAJ3fU5UnunjmMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNV | |
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX | |
aWRnaXRzIFB0eSBMdGQxFTATBgNVBAMTDDE5Mi4xNjguMS40MjAeFw0xOTAyMjQw | |
MTEzMDhaFw0zMDA1MTMwMTEzMDhaMFwxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT | |
b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFTAT | |
BgNVBAMTDDE5Mi4xNjguMS40MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC | |
ggEBAL1wPb/g+A+TkzS9KiHi5rMv81jMaFERqhTp3yThVoKTmB0+2oUdttdTvWqH | |
zuXg30dH5E8tR2oPRmhkaDoiev6n8feAH3Nweu6R9w7EO9DR42ETMK2YXxVIKi8t | |
VjxvGhEy1cTX8Z23gwP0PWFkW7vutSLrU1GDd+vtASRT4AcWfuggDWb61dj/dSaT | |
Hr4X8wNk3fMGHt+MgZteE86JACc9GNFOGJlfIhPLD9hPs22PhK6Q7rgWtT2UGqhn | |
H17IBr9ItmqhM9NtlelG8O8UuHVMqkr/AFr/HU4zxEUAB0+FNCVa7riPeWET7ugA | |
kL7IqgKKzW2QUZUq1j4bEyzzlLcCAwEAAaOBwTCBvjAdBgNVHQ4EFgQUKJ6eyeip | |
kIdvoSOmLSVq+9NCTkkwgY4GA1UdIwSBhjCBg4AUKJ6eyeipkIdvoSOmLSVq+9NC | |
TkmhYKReMFwxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYD | |
VQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFTATBgNVBAMTDDE5Mi4xNjgu | |
MS40MoIJAJ3fU5UnunjmMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB | |
AK/Uqhn6Y2qR0onLLUO2bU8TI/9CY/UbWKOknrih8Pq1a5r145Pi/7y5sXJc+IhM | |
LTV/6YbILO6nQ1MiQTvd2jXCJwgclInk59KwHFw3s30Mh34IUrpmvpSH1W0bKlQS | |
TFElKzVdy76bXyVnStgp6142g+hbyqgM5DVzrV+km0YmfBvUeM4DSkixY09LQbV2 | |
0EaXGB3TjIAP+taYJf/sOKfTq+q26TZDAnbW2bFge0LLrslvWEYUBgyACs1jqjUd | |
ihlEy/Dq+KYDBllDV0fmPCJA2Dny9Rnn+VIW0lKgFwIXe0kGyvRvs5A2SLhB02Ze | |
K9SgRnixMN8XORtmus7juGI= | |
-----END CERTIFICATE----- | |
)EOF"; | |
// Set time via NTP, as required for x.509 validation | |
void setClock() { | |
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); | |
Serial.print("Waiting for NTP time sync: "); | |
time_t now = time(nullptr); | |
while (now < 8 * 3600 * 2) { | |
delay(500); | |
Serial.print("."); | |
now = time(nullptr); | |
} | |
Serial.println(""); | |
struct tm timeinfo; | |
gmtime_r(&now, &timeinfo); | |
Serial.print("Current time: "); | |
Serial.print(asctime(&timeinfo)); | |
} | |
void setup() { | |
delay(5000); | |
Serial.begin(115200); | |
Serial.println(); | |
Serial.println(); | |
// We start by connecting to a WiFi network | |
//Serial.println("THIS IS NEW UPDATE !!"); | |
Serial.print("Connecting to "); | |
Serial.println(ssid); | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(ssid, pass); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi connected"); | |
Serial.println("IP address: "); | |
Serial.println(WiFi.localIP()); | |
BearSSL::WiFiClientSecure client; | |
BearSSL::X509List cert; | |
cert.append(digicert); | |
setClock(); | |
bool mfln = client.probeMaxFragmentLength(host, port, 1024); // server must be the same as in ESPhttpUpdate.update() | |
Serial.printf("MFLN supported: %s\n", mfln ? "yes" : "no"); | |
if (mfln) { | |
client.setBufferSizes(1024, 1024); | |
} | |
client.setTrustAnchors(&cert); | |
//update | |
ESP.resetFreeContStack(); | |
uint32_t freeStackStart = ESP.getFreeContStack(); | |
// The line below is optional. It can be used to blink the LED on the board during flashing | |
// The LED will be on during download of one buffer of data from the network. The LED will | |
// be off during writing that buffer to flash | |
// On a good connection the LED should flash regularly. On a bad connection the LED will be | |
// on much longer than it will be off. Other pins than LED_BUILTIN may be used. The second | |
// value is used to put the LED on. If the LED is on with HIGH, that value should be passed | |
ESPhttpUpdate.setLedPin(LED_BUILTIN, LOW); | |
auto http_ret = ESPhttpUpdate.update(client, host, port, "/update", "0.1"); | |
//if success reboot | |
switch (http_ret) { | |
case HTTP_UPDATE_FAILED: | |
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); | |
break; | |
case HTTP_UPDATE_NO_UPDATES: | |
Serial.println("HTTP_UPDATE_NO_UPDATES"); | |
break; | |
} | |
uint32_t freeStackEnd = ESP.getFreeContStack(); | |
Serial.printf("\nCONT stack used: %d\n-------\n\n", freeStackStart - freeStackEnd); | |
} | |
void loop () | |
{ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment