diff --git a/examples/LOLIN_32_Blink/LOLIN_32_Blink.ino.ota b/examples/LOLIN_32_Blink/LOLIN_32_Blink.ino.ota new file mode 100644 index 0000000..2782244 Binary files /dev/null and b/examples/LOLIN_32_Blink/LOLIN_32_Blink.ino.ota differ diff --git a/examples/NANO_ESP32_Blink/NANO_ESP32_Blink.ino.ota b/examples/NANO_ESP32_Blink/NANO_ESP32_Blink.ino.ota new file mode 100644 index 0000000..098393e Binary files /dev/null and b/examples/NANO_ESP32_Blink/NANO_ESP32_Blink.ino.ota differ diff --git a/examples/OTA/OTA.ino b/examples/OTA_Arduino_Server/OTA_Arduino_Server.ino similarity index 100% rename from examples/OTA/OTA.ino rename to examples/OTA_Arduino_Server/OTA_Arduino_Server.ino diff --git a/examples/OTA/arduino_secrets.h b/examples/OTA_Arduino_Server/arduino_secrets.h similarity index 100% rename from examples/OTA/arduino_secrets.h rename to examples/OTA_Arduino_Server/arduino_secrets.h diff --git a/examples/OTA/root_ca.h b/examples/OTA_Arduino_Server/root_ca.h similarity index 100% rename from examples/OTA/root_ca.h rename to examples/OTA_Arduino_Server/root_ca.h diff --git a/examples/OTA_GitHub_Server/OTA_GitHub_Server.ino b/examples/OTA_GitHub_Server/OTA_GitHub_Server.ino new file mode 100644 index 0000000..9673c79 --- /dev/null +++ b/examples/OTA_GitHub_Server/OTA_GitHub_Server.ino @@ -0,0 +1,115 @@ +/* + * This example demonstrates how to use to update the firmware using Arduino_ESP_OTA library + * + * Steps: + * 1) Create a sketch for your ESP board and verify + * that it both compiles and works. + * 2) In the IDE select: Sketch -> Export compiled Binary. + * 3) Create an OTA update file utilising the tools 'lzss.py' and 'bin2ota.py' stored in + * https://github.com/arduino-libraries/ArduinoIoTCloud/tree/master/extras/tools . + * A) ./lzss.py --encode SKETCH.bin SKETCH.lzss + * B) ./bin2ota.py ESP SKETCH.lzss SKETCH.ota + * 4) Upload the OTA file to a network reachable location, e.g. LOLIN_32_Blink.ino.ota + * has been uploaded to: http://downloads.arduino.cc/ota/LOLIN_32_Blink.ino.ota + * 5) Verify if a custom ca_cert is needed by default Amazon root CA are used + * https://www.amazontrust.com/repository/ + * 6) Perform an OTA update via steps outlined below. + */ + +/****************************************************************************** + * INCLUDE + ******************************************************************************/ + +#include + +#include + +#include "arduino_secrets.h" + +#include "root_ca.h" + +/****************************************************************************** + * CONSTANT + ******************************************************************************/ + +/* Please enter your sensitive data in the Secret tab/arduino_secrets.h */ +static char const SSID[] = SECRET_SSID; /* your network SSID (name) */ +static char const PASS[] = SECRET_PASS; /* your network password (use for WPA, or use as key for WEP) */ + + +#if defined(ARDUINO_NANO_ESP32) +static char const OTA_FILE_LOCATION[] = "https://raw.githubusercontent.com/arduino-libraries/Arduino_ESP32_OTA/main/examples/NANO_ESP32_Blink/NANO_ESP32_Blink.ino.ota"; +#else +static char const OTA_FILE_LOCATION[] = "https://raw.githubusercontent.com/arduino-libraries/Arduino_ESP32_OTA/main/examples/LOLIN_32_Blink/LOLIN_32_Blink.ino.ota" +#endif + +/****************************************************************************** + * SETUP/LOOP + ******************************************************************************/ + +void setup() +{ + Serial.begin(9600); + while (!Serial) {} + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print ("Attempting to connect to '"); + Serial.print (SSID); + Serial.println("'"); + WiFi.begin(SSID, PASS); + delay(2000); + } + Serial.print ("You're connected to '"); + Serial.print (WiFi.SSID()); + Serial.println("'"); + + Arduino_ESP32_OTA ota; + Arduino_ESP32_OTA::Error ota_err = Arduino_ESP32_OTA::Error::None; + + /* Configure custom Root CA */ + ota.setCACert(root_ca); + + Serial.println("Initializing OTA storage"); + if ((ota_err = ota.begin()) != Arduino_ESP32_OTA::Error::None) + { + Serial.print ("Arduino_ESP_OTA::begin() failed with error code "); + Serial.println((int)ota_err); + return; + } + + + Serial.println("Starting download to flash ..."); + int const ota_download = ota.download(OTA_FILE_LOCATION); + if (ota_download <= 0) + { + Serial.print ("Arduino_ESP_OTA::download failed with error code "); + Serial.println(ota_download); + return; + } + Serial.print (ota_download); + Serial.println(" bytes stored."); + + + Serial.println("Verify update integrity and apply ..."); + if ((ota_err = ota.update()) != Arduino_ESP32_OTA::Error::None) + { + Serial.print ("ota.update() failed with error code "); + Serial.println((int)ota_err); + return; + } + + Serial.println("Performing a reset after which the bootloader will start the new firmware."); +#if defined(ARDUINO_NANO_ESP32) + Serial.println("Hint: Arduino NANO ESP32 will blink Red Green and Blue."); +#else + Serial.println("Hint: LOLIN32 will blink Blue."); +#endif + delay(1000); /* Make sure the serial message gets out before the reset. */ + ota.reset(); +} + +void loop() +{ + +} diff --git a/examples/OTA_GitHub_Server/arduino_secrets.h b/examples/OTA_GitHub_Server/arduino_secrets.h new file mode 100644 index 0000000..0c9fdd5 --- /dev/null +++ b/examples/OTA_GitHub_Server/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS "" diff --git a/examples/OTA_GitHub_Server/root_ca.h b/examples/OTA_GitHub_Server/root_ca.h new file mode 100644 index 0000000..ba07ba0 --- /dev/null +++ b/examples/OTA_GitHub_Server/root_ca.h @@ -0,0 +1,55 @@ +const char* root_ca = \ +/*DigiCert TLS Hybrid ECC SHA384 2020 CA1*/ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIEFzCCAv+gAwIBAgIQB/LzXIeod6967+lHmTUlvTANBgkqhkiG9w0BAQwFADBh\n" \ +"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" \ +"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" \ +"QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaMFYxCzAJBgNVBAYTAlVT\n" \ +"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMDAuBgNVBAMTJ0RpZ2lDZXJ0IFRMUyBI\n" \ +"eWJyaWQgRUNDIFNIQTM4NCAyMDIwIENBMTB2MBAGByqGSM49AgEGBSuBBAAiA2IA\n" \ +"BMEbxppbmNmkKaDp1AS12+umsmxVwP/tmMZJLwYnUcu/cMEFesOxnYeJuq20ExfJ\n" \ +"qLSDyLiQ0cx0NTY8g3KwtdD3ImnI8YDEe0CPz2iHJlw5ifFNkU3aiYvkA8ND5b8v\n" \ +"c6OCAYIwggF+MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAq8CCkXjKU5\n" \ +"bXoOzjPHLrPt+8N6MB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA4G\n" \ +"A1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYI\n" \ +"KwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j\n" \ +"b20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp\n" \ +"Q2VydEdsb2JhbFJvb3RDQS5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2Ny\n" \ +"bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAE\n" \ +"NjA0MAsGCWCGSAGG/WwCATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgG\n" \ +"BmeBDAECAzANBgkqhkiG9w0BAQwFAAOCAQEAR1mBf9QbH7Bx9phdGLqYR5iwfnYr\n" \ +"6v8ai6wms0KNMeZK6BnQ79oU59cUkqGS8qcuLa/7Hfb7U7CKP/zYFgrpsC62pQsY\n" \ +"kDUmotr2qLcy/JUjS8ZFucTP5Hzu5sn4kL1y45nDHQsFfGqXbbKrAjbYwrwsAZI/\n" \ +"BKOLdRHHuSm8EdCGupK8JvllyDfNJvaGEwwEqonleLHBTnm8dqMLUeTF0J5q/hos\n" \ +"Vq4GNiejcxwIfZMy0MJEGdqN9A57HSgDKwmKdsp33Id6rHtSJlWncg+d0ohP/rEh\n" \ +"xRqhqjn1VtvChMQ1H3Dau0bwhr9kAMQ+959GG50jBbl9s08PqUU643QwmA==\n" \ +"-----END CERTIFICATE-----\n" +/*DigiCert TLS RSA SHA256 2020 CA1*/ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIEvjCCA6agAwIBAgIQBtjZBNVYQ0b2ii+nVCJ+xDANBgkqhkiG9w0BAQsFADBh\n" \ +"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" \ +"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" \ +"QTAeFw0yMTA0MTQwMDAwMDBaFw0zMTA0MTMyMzU5NTlaME8xCzAJBgNVBAYTAlVT\n" \ +"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxKTAnBgNVBAMTIERpZ2lDZXJ0IFRMUyBS\n" \ +"U0EgU0hBMjU2IDIwMjAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n" \ +"AQEAwUuzZUdwvN1PWNvsnO3DZuUfMRNUrUpmRh8sCuxkB+Uu3Ny5CiDt3+PE0J6a\n" \ +"qXodgojlEVbbHp9YwlHnLDQNLtKS4VbL8Xlfs7uHyiUDe5pSQWYQYE9XE0nw6Ddn\n" \ +"g9/n00tnTCJRpt8OmRDtV1F0JuJ9x8piLhMbfyOIJVNvwTRYAIuE//i+p1hJInuW\n" \ +"raKImxW8oHzf6VGo1bDtN+I2tIJLYrVJmuzHZ9bjPvXj1hJeRPG/cUJ9WIQDgLGB\n" \ +"Afr5yjK7tI4nhyfFK3TUqNaX3sNk+crOU6JWvHgXjkkDKa77SU+kFbnO8lwZV21r\n" \ +"eacroicgE7XQPUDTITAHk+qZ9QIDAQABo4IBgjCCAX4wEgYDVR0TAQH/BAgwBgEB\n" \ +"/wIBADAdBgNVHQ4EFgQUt2ui6qiqhIx56rTaD5iyxZV2ufQwHwYDVR0jBBgwFoAU\n" \ +"A95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQG\n" \ +"CCsGAQUFBwMBBggrBgEFBQcDAjB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGG\n" \ +"GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2Nh\n" \ +"Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNydDBCBgNV\n" \ +"HR8EOzA5MDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRH\n" \ +"bG9iYWxSb290Q0EuY3JsMD0GA1UdIAQ2MDQwCwYJYIZIAYb9bAIBMAcGBWeBDAEB\n" \ +"MAgGBmeBDAECATAIBgZngQwBAgIwCAYGZ4EMAQIDMA0GCSqGSIb3DQEBCwUAA4IB\n" \ +"AQCAMs5eC91uWg0Kr+HWhMvAjvqFcO3aXbMM9yt1QP6FCvrzMXi3cEsaiVi6gL3z\n" \ +"ax3pfs8LulicWdSQ0/1s/dCYbbdxglvPbQtaCdB73sRD2Cqk3p5BJl+7j5nL3a7h\n" \ +"qG+fh/50tx8bIKuxT8b1Z11dmzzp/2n3YWzW2fP9NsarA4h20ksudYbj/NhVfSbC\n" \ +"EXffPgK2fPOre3qGNm+499iTcc+G33Mw+nur7SpZyEKEOxEXGlLzyQ4UfaJbcme6\n" \ +"ce1XR2bFuAJKZTRei9AqPCCcUZlM51Ke92sRKw2Sfh3oius2FkOH6ipjv3U/697E\n" \ +"A7sKPPcw7+uvTPyLNhBzPvOk\n" \ +"-----END CERTIFICATE-----\n"; diff --git a/src/Arduino_ESP32_OTA.cpp b/src/Arduino_ESP32_OTA.cpp index 57aad7d..cb5303d 100644 --- a/src/Arduino_ESP32_OTA.cpp +++ b/src/Arduino_ESP32_OTA.cpp @@ -182,7 +182,25 @@ int Arduino_ESP32_OTA::download(const char * ota_url) DEBUG_VERBOSE("%s: Length of OTA binary according to HTTP header = %d bytes", __FUNCTION__, content_length_val); /* Read the OTA header ... */ - _client->read(_ota_header.buf, sizeof(OtaHeader)); + bool is_http_data_timeout = false; + for(int i = 0; i < sizeof(OtaHeader) && !is_http_data_timeout; i++) + { + for(unsigned long const start = millis();;) + { + is_http_data_timeout = (millis() - start) > ARDUINO_ESP32_OTA_BINARY_BYTE_RECEIVE_TIMEOUT_ms; + if (is_http_data_timeout) + { + DEBUG_ERROR("%s: timeout waiting data", __FUNCTION__); + break; + } + if (_client->available()) + { + _ota_header.buf[i] = _client->read(); + break; + } + } + } + //_client->read(_ota_header.buf, sizeof(OtaHeader)); /* ... and check first length ... */ if (_ota_header.header.len != (content_length_val - sizeof(_ota_header.header.len) - sizeof(_ota_header.header.crc32))) {