From 8131994f9663f5d9701aa922bd8778bd4e48edbf Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 21:02:55 +0100 Subject: [PATCH 1/9] Added new loader sketch --- .../Loaders/DirectLoader/DirectLoader.ino | 280 ++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 examples/Loaders/DirectLoader/DirectLoader.ino diff --git a/examples/Loaders/DirectLoader/DirectLoader.ino b/examples/Loaders/DirectLoader/DirectLoader.ino new file mode 100644 index 00000000..f49d2940 --- /dev/null +++ b/examples/Loaders/DirectLoader/DirectLoader.ino @@ -0,0 +1,280 @@ +/* + Warning: This is not for first time users. Use the IASLoader instead! + + This sketch is meant for adding large quantities of devices to an existing Devicebatch + without having to do/repeat the initial setup.(Wifi, registration etc.) + + This sketch: + - Erases EEPROM + - Sets up initial hardcode WiFi connection + - Contacts IOTAppStory.com over https + - Registers your device with IOTAppStory.com + - Saves the device activation code + - Saves generated device name (eg. XXXX-22, XXXX-23 ...) + - Saves the Fingerprint or Certificate (depends on config.h settings) + - Saves the WiFi credentials (optional) + - Calls home to get the latest firmware + + You will need: + - IOTAppStory.com account + - Device hash + - Local WiFi credentials + + Copyright (c) [2020] [Onno Dirkzwager] + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#define COMPDATE __DATE__ __TIME__ +#define MODEBUTTON 0 // Button pin on the esp for selecting modes. D3 for the Wemos! + + +#include // IOTAppStory.com library +IOTAppStory IAS(COMPDATE, MODEBUTTON); // Initialize IOTAppStory + + + +// ================================================ VARS ================================================= +const char* ssid = "***"; // Wifi SSID +const char* password = "***"; // WiFi password +const bool saveWifiCred = true; // true : Save the Wifi credentials for future use + // false: only use Wifi credentials for adding this device and doing the initial update + +const char* hash = "***"; +const char* host = "iotappstory.com"; +const char* url = "/ota/addtoaccount"; + + +#if defined ESP8266 && HTTPS_8266_TYPE == FNGPRINT + // Use web browser to view and copy SHA1 fingerprint of the certificate + const char fingerprint[] PROGMEM = "2b 14 1a f1 5e 54 87 fc 0d f4 6f 0e 01 1c 0d 77 25 28 5b 9e"; +#else + // Use web browser to save a copy of the root certificate + const char ROOT_CA[] = \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb\n" \ + "MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\n" \ + "GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj\n" \ + "YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL\n" \ + "MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" \ + "BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM\n" \ + "GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" \ + "ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua\n" \ + "BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe\n" \ + "3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4\n" \ + "YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR\n" \ + "rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm\n" \ + "ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU\n" \ + "oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF\n" \ + "MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v\n" \ + "QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t\n" \ + "b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF\n" \ + "AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q\n" \ + "GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz\n" \ + "Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2\n" \ + "G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi\n" \ + "l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3\n" \ + "smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\n" \ + "-----END CERTIFICATE-----\n"; +#endif + + + +// ================================================ SETUP ================================================ +void setup() { + Serial.println(FPSTR(SER_DEV)); // print divider + IAS.eraseEEPROM('F'); // Optional! What to do with EEPROM on First boot of the app? 'F' Fully erase | 'P' Partial erase + // This should not be necessary on new devices, but may be for existing (test) devices that have used EEPROM + + // setup Wifi connection + Serial.printf("\n Connecting to %s\n ", ssid); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + IAS.WiFiConnected = true; + Serial.print(F("\n WiFi connected\n IP address: ")); + Serial.println(WiFi.localIP()); + + { + // Synchronize the internal clock useing SNTP | used for verifying certificates on the ESP8266 + #if defined ESP8266 && HTTPS_8266_TYPE == CERTIFICATE + IAS.setClock(); + IAS.ntpWaitForSync(); + #endif + + // Use WiFiClientSecure class to create TLS connection + WiFiClientSecure client; + Serial.printf("\n Connecting to %s\n", host); + + #if defined ESP8266 + #if HTTPS_8266_TYPE == FNGPRINT + Serial.printf(" Using fingerprint '%s'\n", fingerprint); + client.setFingerprint(fingerprint); + #else + client.setCACert((uint8_t*)ROOT_CA, strlen(ROOT_CA)); + #endif + #elif defined ESP32 + client.setCACert(ROOT_CA); + #endif + + Serial.print(" "); + while (!client.connect(host, 443)) { + delay(500); + Serial.print("."); + } + + // request url from host + Serial.printf("\n Requesting URL: %s%s\n", host, url); + client.print(String("GET ") + url + "?hash=" + hash + F(" HTTP/1.1") + + F("\r\nHost: ") + host + + F("\r\nUser-Agent: ESP-http-Update") + + F("\r\nx-ESP-STA-MAC: ") + WiFi.macAddress() + + F("\r\nx-ESP-LOCIP: ") + WiFi.localIP().toString() + + F("\r\nx-ESP-SKETCH-MD5: ") + ESP.getSketchMD5() + + F("\r\nx-ESP-FLASHCHIP-ID: ") + ESP_GETFLASHCHIPID + + F("\r\nx-ESP-CHIP-ID: ") + ESP_GETCHIPID + + F("\r\nx-ESP-FLASHCHIP-SIZE: ") + ESP.getFlashChipSize() + + F("\r\nConnection: close\r\n\r\n")); + + // process server respons header & return error if not 200 - OK + int code; + String actcode, deviceName; + while (client.connected()) { + String line = client.readStringUntil('\n'); + + if(line.startsWith(F("HTTP/1.1 "))) { + line.remove(0, 9); + code = line.substring(0, 3).toInt(); + + if(code != 200){ + line.remove(0, 4); + Serial.print(F(" Request error!\n Code\t\t: ")); + Serial.print(code); + Serial.print(F("\n Message\t: ")); + Serial.println(line); + break; + } + }else if(line.startsWith(F("actcode: "))) { + line.remove(0, 9); + actcode = line; + }else if(line.startsWith(F("devname: "))) { + line.remove(0, 9); + deviceName = line; + }else if (line == "\r") { + Serial.println(F("\n Headers received")); + break; + } + } + + // Close connection + client.stop(); + Serial.println(F(" Closing connection")); + + + // If server respons code is OK and we received the activation code + if(code == 200 && actcode != ""){ + Serial.println(F("\n Success! Added device to IAS.\n Updating device...")); + + // create new config struc + ConfigStruct newConfig; + + // read config | this gets the default settings + IAS.readConfig(newConfig); + { + // copy activation code to newConfig struct + actcode.toCharArray(newConfig.actCode, 7); + Serial.println(F(" - Added activation code.")); + + // copy deviceName to newConfig struct + deviceName.toCharArray(newConfig.deviceName, STRUCT_BNAME_SIZE); + Serial.print(" - Added device name: "); + Serial.println(deviceName); + + // copy fingerprint to newConfig struct OR certificate to SPIFFS + #if defined ESP8266 && HTTPS_8266_TYPE == FNGPRINT + strcpy(newConfig.sha1, fingerprint); + Serial.println(F(" - Added fingerprint")); + #endif + + // write config to EEPROM + IAS.writeConfig(newConfig); + delay(100); + + // if set write certificate to SPIFFS for future use + #if defined ESP32 || HTTPS_8266_TYPE == CERTIFICATE + + // Mount SPIFFS + if(!ESP_SPIFFSBEGIN){ + Serial.println(F("- Failed to mount SPIFFS")); + } + + // open new SPIFFS file for writing data + File fsUploadFile; + fsUploadFile = SPIFFS.open("/cert/iasRootCa.cer", "w"); /// close file + + // write certificate(hardcoded char array) to SPIFFS file + if(fsUploadFile.write((uint8_t *)ROOT_CA, strlen(ROOT_CA)) != strlen(ROOT_CA)){ + Serial.println(F(" - Failed to write certificate to SPIFFS")); + } + + // close SPIFFS FILE + fsUploadFile.close(); + + Serial.println(F(" - Added Certificate to SPIFFS")); + #endif + } + + // write WiFi credentials to EEPROM + if(saveWifiCred){ + WiFiConnector WiFiConn; + WiFiConn.addAPtoEEPROM(ssid, password, 1); + Serial.println(F(" - Added WiFi credentials")); + } + + // print divider + Serial.println(FPSTR(SER_DEV)); + }else{ + return; + } + } + + // callback for showing update progress + IAS.onFirmwareUpdateProgress([](int written, int total){ + Serial.print("."); + }); + + // callhome and get the latest firmware + IAS.callHome(); + + // if callhome failed retry every 60 sec + IAS.setCallHomeInterval(60); +} + + + +// ================================================ LOOP ================================================= +void loop() { + IAS.loop(); // this routine handles the calling home functionality, + // reaction of the MODEBUTTON pin. If short press (<4 sec): update of sketch, long press (>7 sec): Configuration + // reconnecting WiFi when the connection is lost, + // and setting the internal clock (ESP8266 for BearSSL) +} From d609cd977ba2161983ef612fdd02e4ee63733299 Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 21:04:02 +0100 Subject: [PATCH 2/9] Update DirectLoader.ino --- examples/Loaders/DirectLoader/DirectLoader.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Loaders/DirectLoader/DirectLoader.ino b/examples/Loaders/DirectLoader/DirectLoader.ino index f49d2940..6c89b645 100644 --- a/examples/Loaders/DirectLoader/DirectLoader.ino +++ b/examples/Loaders/DirectLoader/DirectLoader.ino @@ -20,7 +20,7 @@ - Device hash - Local WiFi credentials - Copyright (c) [2020] [Onno Dirkzwager] + Copyright (c) [2021] [Onno Dirkzwager] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 894dfa004fe43b6dedbb08ece13ef43c72ea0246 Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 21:06:24 +0100 Subject: [PATCH 3/9] Update BatchLoader.ino - Updated for serverside changes - Updated used function names --- examples/Loaders/BatchLoader/BatchLoader.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Loaders/BatchLoader/BatchLoader.ino b/examples/Loaders/BatchLoader/BatchLoader.ino index fe0c8bbc..c06095e7 100644 --- a/examples/Loaders/BatchLoader/BatchLoader.ino +++ b/examples/Loaders/BatchLoader/BatchLoader.ino @@ -18,8 +18,7 @@ You will need: - IOTAppStory.com account - - Existing Devicebatch with at least 1 added device of the same - type as the devices you want to use this sketch for. + - Existing Devicebatch - Devicebatch hash - Local WiFi credentials @@ -59,9 +58,10 @@ const char* password = "***"; // WiFi password const bool saveWifiCred = true; // true : Save the Wifi credentials for future use // false: only use Wifi credentials for adding this device and doing the initial update +const char* hash = "***"; const char* host = "iotappstory.com"; const char* url = "/ota/addtobatch"; -const char* hash = "***"; + #if defined ESP8266 && HTTPS_8266_TYPE == FNGPRINT // Use web browser to view and copy SHA1 fingerprint of the certificate @@ -120,7 +120,7 @@ void setup() { // Synchronize the internal clock useing SNTP | used for verifying certificates on the ESP8266 #if defined ESP8266 && HTTPS_8266_TYPE == CERTIFICATE IAS.setClock(); - IAS.ntpSync(); + IAS.ntpWaitForSync(); #endif // Use WiFiClientSecure class to create TLS connection From ee27a6d627a365962a91d7b7855f8a89c2868edb Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 21:20:40 +0100 Subject: [PATCH 4/9] Update IASLoader.ino Check for updates on boot --- examples/Loaders/IASLoader/IASLoader.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/Loaders/IASLoader/IASLoader.ino b/examples/Loaders/IASLoader/IASLoader.ino index 0d269fba..a08025a8 100644 --- a/examples/Loaders/IASLoader/IASLoader.ino +++ b/examples/Loaders/IASLoader/IASLoader.ino @@ -75,7 +75,6 @@ void setup() { IAS.preSetDeviceName(deviceName); // preset deviceName this is also your MDNS responder: http://deviceName-123.local IAS.preSetAppName(F("INITLoader")); // preset appName | The appName & appVersion get updated when you receive OTA updates. As this is your first app we will set it manually. IAS.preSetAppVersion(F("1.3.1")); // preset appVersion - IAS.preSetAutoUpdate(false); // automaticUpdate (true, false) // You can configure callback functions that can give feedback to the app user about the current state of the application. From 8df5f772a33877607453e3f7733d652a7b7938e7 Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 22:03:03 +0100 Subject: [PATCH 5/9] Update VirginSoil-Full.ino Changed both the default value as the added field for timezone to reflect the library changes. --- examples/VirginSoil-Full/VirginSoil-Full.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/VirginSoil-Full/VirginSoil-Full.ino b/examples/VirginSoil-Full/VirginSoil-Full.ino index bf8bb0f6..2e584622 100644 --- a/examples/VirginSoil-Full/VirginSoil-Full.ino +++ b/examples/VirginSoil-Full/VirginSoil-Full.ino @@ -54,7 +54,7 @@ char* chosen = "0"; char* updInt = "60"; char* ledPin = "2"; -char* timeZone = "0.0"; +char* timeZone = "Europe/Amsterdam"; @@ -83,7 +83,7 @@ void setup() { IAS.addField(updInt, "Interval", 8, 'I'); IAS.addField(ledPin, "ledPin", 2, 'P'); - IAS.addField(timeZone, "Timezone", 4, 'Z'); + IAS.addField(timeZone, "Timezone", 48, 'Z'); From 017929947ca9a94b29e8d418bc67a2070ca448c7 Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 22:07:09 +0100 Subject: [PATCH 6/9] Update Wemos-IASLoader.ino Check for updates on boot --- .../LOLIN(WEMOS) D1 mini/Wemos-IASLoader/Wemos-IASLoader.ino | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/LOLIN(WEMOS) D1 mini/Wemos-IASLoader/Wemos-IASLoader.ino b/examples/LOLIN(WEMOS) D1 mini/Wemos-IASLoader/Wemos-IASLoader.ino index 96ca1229..ec44bce4 100644 --- a/examples/LOLIN(WEMOS) D1 mini/Wemos-IASLoader/Wemos-IASLoader.ino +++ b/examples/LOLIN(WEMOS) D1 mini/Wemos-IASLoader/Wemos-IASLoader.ino @@ -67,16 +67,15 @@ void setup() { IAS.preSetDeviceName(deviceName); // preset deviceName this is also your MDNS responder: http://deviceName-123.local IAS.preSetAppName(F("Wemos")); // preset appName | The appName & appVersion get updated when you receive OTA updates. As this is your first app we will set it manually. IAS.preSetAppVersion(F("1.3.1")); // preset appVersion - IAS.preSetAutoUpdate(false); // automaticUpdate (true, false) - // default mode button not connected on LOLIN oled v2.1.0 shield + // default mode button not connected on LOLIN oled v2.1.0 shield IAS.onModeButtonShortPress([]() { Serial.println(F(" If mode button is released, I will enter in firmware update mode.")); Serial.println(F("*-------------------------------------------------------------------------*")); dispTemplate_threeLineV2(F("Release"), F("for"), F("Updates")); }); - // default mode button not connected on LOLIN oled v2.1.0 shield + // default mode button not connected on LOLIN oled v2.1.0 shield IAS.onModeButtonLongPress([]() { Serial.println(F(" If mode button is released, I will enter in configuration mode.")); Serial.println(F("*-------------------------------------------------------------------------*")); From 039c23b9101d293a2a9562cee6beb9fc057d0fea Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 22:11:17 +0100 Subject: [PATCH 7/9] Update libraryUpgrader.ino - Small changes & alignments to code - Added certificate to copy to SPIFFS --- examples/libraryUpgrader/libraryUpgrader.ino | 37 +++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/examples/libraryUpgrader/libraryUpgrader.ino b/examples/libraryUpgrader/libraryUpgrader.ino index 469d5bfa..da7cb6b1 100644 --- a/examples/libraryUpgrader/libraryUpgrader.ino +++ b/examples/libraryUpgrader/libraryUpgrader.ino @@ -1,4 +1,4 @@ -/* +or /* This sketch is an example of how you can upgrade from the previous library(2.0.X) to the new 2.1.0 library EEPROM layout. If successful all the previous settings like Wifi, IAS device registration and added fields get "rewritten" to the new @@ -51,8 +51,8 @@ IOTAppStory IAS(COMPDATE, MODEBUTTON); // Initialize IOTAppStory #define NROFADDEDFIELDS 8 // How many added fields should we search for? #define LARGESTLENGTH 5 // What is de largest "max char return" -int fieldMaxLength[NROFADDEDFIELDS] = {2 ,5}; // Max returns as used in the added fields. -char fieldType[NROFADDEDFIELDS] = {'P','N'}; // Field types as used in the added fields. (L if none was entered!) +int fieldMaxLength[NROFADDEDFIELDS] = {2, 5}; // Max returns as used in the added fields. +char fieldType[NROFADDEDFIELDS] = {'p', 'n'}; // Field types as used in the added fields. (L if none was entered!) @@ -62,7 +62,7 @@ char fieldType[NROFADDEDFIELDS] = {'P','N'}; // Field types as used in the #define OLD_STRUCT_BNAME_SIZE 30 #define OLD_STRUCT_COMPDATE_SIZE 20 -typedef struct oldConfig{ +typedef struct oldConfig_v20X{ char actCode[7]; // saved IotAppStory activation code char appName[33]; char appVersion[12]; @@ -80,6 +80,34 @@ typedef struct oldConfig{ }; +// This certificate gets copied to a file in SPIFFS: /cert/iasRootCa.cer +const char ROOT_CA[] = \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb\n" \ + "MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\n" \ + "GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj\n" \ + "YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL\n" \ + "MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" \ + "BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM\n" \ + "GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" \ + "ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua\n" \ + "BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe\n" \ + "3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4\n" \ + "YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR\n" \ + "rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm\n" \ + "ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU\n" \ + "oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF\n" \ + "MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v\n" \ + "QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t\n" \ + "b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF\n" \ + "AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q\n" \ + "GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz\n" \ + "Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2\n" \ + "G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi\n" \ + "l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3\n" \ + "smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\n" \ + "-----END CERTIFICATE-----\n"; + // ================================================ SETUP ================================================ void setup() { @@ -101,6 +129,7 @@ void setup() { }); IAS.onFirstBoot([]() { + Serial.println("IAS.onFirstBoot()"); runUpgrade(); // Run the library upgrader }); From 5cb8604aedba0bd51423cbdebc10372a63e32191 Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 22:12:28 +0100 Subject: [PATCH 8/9] Update upgradeHelper.ino - Small changes & alignments to code - Added code to copy the certificate to SPIFFS --- examples/libraryUpgrader/upgradeHelper.ino | 40 +++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/examples/libraryUpgrader/upgradeHelper.ino b/examples/libraryUpgrader/upgradeHelper.ino index 7d089a17..a46fe30c 100644 --- a/examples/libraryUpgrader/upgradeHelper.ino +++ b/examples/libraryUpgrader/upgradeHelper.ino @@ -26,9 +26,9 @@ char tempValue[NROFADDEDFIELDS][LARGESTLENGTH]; // ================================================ functions ========================================= void runUpgrade(){ - oldConfig oldCfg; + oldConfig_v20X oldCfg; const int oldCfgStartAddress = 0; - const int oldMagicBytesBegin = oldCfgStartAddress + sizeof(oldConfig) - 4; + const int oldMagicBytesBegin = oldCfgStartAddress + sizeof(oldConfig_v20X) - 4; int nrOfFieldsFound = 0; EEPROM.begin(EEPROM_SIZE); @@ -39,7 +39,7 @@ void runUpgrade(){ // check for magicBytes to confirm the old config struct is stored in EEPROM if(EEPROM.read(oldMagicBytesBegin) == MAGICBYTES[0] && EEPROM.read(oldMagicBytesBegin + 1) == MAGICBYTES[1] && EEPROM.read(oldMagicBytesBegin + 2) == MAGICBYTES[2]){ - Serial.printf(" Found config! Size: %d\n", sizeof(oldConfig)); + Serial.printf(" Found config! Size: %d\n", sizeof(oldConfig_v20X)); // get the old config from EEPROM EEPROM.get(oldCfgStartAddress, oldCfg); @@ -76,14 +76,14 @@ void runUpgrade(){ // write the board details to the new config struct in EEPROM - configStruct newConfig; + ConfigStruct newConfig; strcpy(newConfig.actCode, oldCfg.actCode); strcpy(newConfig.appName, oldCfg.appName); strcpy(newConfig.appVersion, oldCfg.appVersion); strcpy(newConfig.deviceName, oldCfg.deviceName); strcpy(newConfig.compDate, oldCfg.compDate); - #if defined ESP8266 + #if defined ESP8266 && HTTPS_8266_TYPE == FNGPRINT strcpy(newConfig.sha1, oldCfg.sha1); #endif #if CFG_AUTHENTICATE == true @@ -97,6 +97,30 @@ void runUpgrade(){ if(nrOfFieldsFound > 0){ writeAddedFields(nrOfFieldsFound); } + + + // if set write certificate to SPIFFS for future use + #if defined ESP32 || HTTPS_8266_TYPE == CERTIFICATE + + // Mount SPIFFS + if(!ESP_SPIFFSBEGIN){ + Serial.println(F(" Failed to mount SPIFFS")); + } + + // open new SPIFFS file for writing data + File fsUploadFile; + fsUploadFile = SPIFFS.open("/cert/iasRootCa.cer", "w"); /// close file + + // write certificate(hardcoded char array) to SPIFFS file + if(fsUploadFile.write((uint8_t *)ROOT_CA, strlen(ROOT_CA)) != strlen(ROOT_CA)){ + Serial.println(F(" Failed to write certificate to SPIFFS")); + } + + // close SPIFFS FILE + fsUploadFile.close(); + + Serial.println(F(" Added Certificate to SPIFFS")); + #endif #endif }else{ @@ -108,7 +132,7 @@ void runUpgrade(){ -void showOldConfig(oldConfig &oldCfg){ +void showOldConfig(oldConfig_v20X &oldCfg){ Serial.println(FPSTR(SER_DEV)); Serial.println(F("\n Old config values")); @@ -164,7 +188,7 @@ int findAddedFields(){ int fieldSearchStartAddress; if(lastFieldEndAt == 0){ - fieldSearchStartAddress = sizeof(oldConfig); + fieldSearchStartAddress = sizeof(oldConfig_v20X); }else{ fieldSearchStartAddress = lastFieldEndAt; } @@ -234,7 +258,7 @@ void writeAddedFields(int fieldsFound){ for(int i=0; i < fieldsFound; i++){ // init fieldStruct - addFieldStruct fieldStruct; + AddFieldStruct fieldStruct; // calculate EEPROM addresses const int eepStartAddress = FIELD_EEP_START_ADDR + (i * sizeof(fieldStruct)); From e6dd934caf614ff094f6640c8d09ee904ff80a17 Mon Sep 17 00:00:00 2001 From: Onno-Dirkzwager Date: Sat, 13 Mar 2021 22:15:26 +0100 Subject: [PATCH 9/9] Rename libraryUpgrader.ino to libraryUpgrader_20X_to_210.ino As it is more descriptive when more upgraders get added. --- .../{libraryUpgrader.ino => libraryUpgrader_20X_to_210.ino} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/libraryUpgrader/{libraryUpgrader.ino => libraryUpgrader_20X_to_210.ino} (100%) diff --git a/examples/libraryUpgrader/libraryUpgrader.ino b/examples/libraryUpgrader/libraryUpgrader_20X_to_210.ino similarity index 100% rename from examples/libraryUpgrader/libraryUpgrader.ino rename to examples/libraryUpgrader/libraryUpgrader_20X_to_210.ino