diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index 14a49ad29..a0126cf2c 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -86,10 +86,12 @@ jobs: fqbn: "arduino:renesas_uno:unor4wifi" additional-sketch-paths: | - libraries/WiFiS3 + - libraries/OTAUpdate - board: fqbn: "arduino-git:renesas:unor4wifi" additional-sketch-paths: | - libraries/WiFiS3 + - libraries/OTAUpdate steps: - name: Checkout repository diff --git a/extras/uno-r4-wifi-usb-bridge b/extras/uno-r4-wifi-usb-bridge index 2b49c4939..3f4e668d1 160000 --- a/extras/uno-r4-wifi-usb-bridge +++ b/extras/uno-r4-wifi-usb-bridge @@ -1 +1 @@ -Subproject commit 2b49c49391f0cfacaa32164e4fd863d88be45281 +Subproject commit 3f4e668d1318feeaa7088c788e7fd88a26a5a671 diff --git a/libraries/OTAUpdate/.unor4_only b/libraries/OTAUpdate/.unor4_only new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/OTAUpdate/examples/OTA/OTA.ino b/libraries/OTAUpdate/examples/OTA/OTA.ino new file mode 100644 index 000000000..586026f87 --- /dev/null +++ b/libraries/OTAUpdate/examples/OTA/OTA.ino @@ -0,0 +1,113 @@ +/* + OTA + + This sketch demonstrates how to make an OTA Update on the UNO R4 WiFi. + Upload the sketch and wait for the invasion! + +*/ + + +#include "WiFiS3.h" +#include "OTAUpdate.h" +#include "root_ca.h" +#include "arduino_secrets.h" + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) + +int status = WL_IDLE_STATUS; + +OTAUpdate ota; +static char const OTA_FILE_LOCATION[] = "https://downloads.arduino.cc/ota/UNOR4WIFI_Animation.ota"; + +/* -------------------------------------------------------------------------- */ +void setup() { +/* -------------------------------------------------------------------------- */ + //Initialize serial and wait for port to open: + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // check for the Wi-Fi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with Wi-Fi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + + // attempt to connect to Wi-Fi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); + + // wait 1 seconds for connection: + delay(1000); + } + + printWiFiStatus(); + + OTAUpdate::Error ret = OTAUpdate::Error::None; + ret = ota.begin("/update.bin"); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.begin() error: "); + Serial.println((int)ret); + return; + } + ret = ota.setCACert(root_ca); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.setCACert() error: "); + Serial.println((int)ret); + return; + } + if(ota.download(OTA_FILE_LOCATION, "/update.bin") <= 0) { + Serial.println("ota.download() error: "); + Serial.println((int)ret); + return; + } + ret = ota.verify(); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.verify() error: "); + Serial.println((int)ret); + return; + } + + ret = ota.update("/update.bin"); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.update() error: "); + Serial.println((int)ret); + return; + } +} + +/* -------------------------------------------------------------------------- */ +void loop() { +/* -------------------------------------------------------------------------- */ + delay(1000); +} + +/* -------------------------------------------------------------------------- */ +void printWiFiStatus() { +/* -------------------------------------------------------------------------- */ + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.print(rssi); + Serial.println(" dBm"); +} diff --git a/libraries/OTAUpdate/examples/OTA/arduino_secrets.h b/libraries/OTAUpdate/examples/OTA/arduino_secrets.h new file mode 100644 index 000000000..0c9fdd556 --- /dev/null +++ b/libraries/OTAUpdate/examples/OTA/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS "" diff --git a/libraries/OTAUpdate/examples/OTA/root_ca.h b/libraries/OTAUpdate/examples/OTA/root_ca.h new file mode 100644 index 000000000..ff7d2f738 --- /dev/null +++ b/libraries/OTAUpdate/examples/OTA/root_ca.h @@ -0,0 +1,88 @@ +const char* root_ca = \ +/* Baltimore CyberTrust Root */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE\n" \ +"ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li\n" \ +"ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC\n" \ +"SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs\n" \ +"dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME\n" \ +"uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB\n" \ +"UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C\n" \ +"G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9\n" \ +"XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr\n" \ +"l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI\n" \ +"VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB\n" \ +"BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh\n" \ +"cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5\n" \ +"hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa\n" \ +"Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H\n" \ +"RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n" \ +"-----END CERTIFICATE-----\n" \ +/* Amazon Root CA 1 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD\n" \ +"VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1\n" \ +"MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv\n" \ +"bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" \ +"ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH\n" \ +"FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ\n" \ +"gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t\n" \ +"dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce\n" \ +"VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB\n" \ +"/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3\n" \ +"DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM\n" \ +"CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy\n" \ +"8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa\n" \ +"2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2\n" \ +"xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5\n" \ +"-----END CERTIFICATE-----\n" \ +/* Amazon Root CA 2 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD\n" \ +"VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1\n" \ +"MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv\n" \ +"bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\n" \ +"ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4\n" \ +"kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp\n" \ +"N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9\n" \ +"AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd\n" \ +"fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx\n" \ +"kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS\n" \ +"btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0\n" \ +"Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN\n" \ +"c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+\n" \ +"3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw\n" \ +"DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA\n" \ +"A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY\n" \ +"+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE\n" \ +"YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW\n" \ +"xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ\n" \ +"gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW\n" \ +"aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV\n" \ +"Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3\n" \ +"KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi\n" \ +"JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=\n" \ +"-----END CERTIFICATE-----\n" \ +/* Amazon Root CA 3 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG\n" \ +"EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy\n" \ +"NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\n" \ +"MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB\n" \ +"f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr\n" \ +"Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43\n" \ +"rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc\n" \ +"eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==\n" \ +"-----END CERTIFICATE-----\n" \ +/* Amazon Root CA 4 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG\n" \ +"EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy\n" \ +"NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\n" \ +"MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN\n" \ +"/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri\n" \ +"83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n" \ +"HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA\n" \ +"MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1\n" \ +"AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==\n" \ +"-----END CERTIFICATE-----\n"; diff --git a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino new file mode 100644 index 000000000..8bde18088 --- /dev/null +++ b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino @@ -0,0 +1,133 @@ +/* + OTA + + This sketch demonstrates how to make the UNO R4 WiFi self-update its Wi-Fi module + firmware via OTA. Upload the Sketch and wait for Serial detach. After the update + the new Wi-Fi firmware version will be 98.98.98 + + WARNING: running this sketch will load a test Wi-Fi firmware version on the UNO R4 + WiFi module. To restore a production firmware use the Arduino Firmware Uploader or + the update packages available here: + + https://github.com/arduino/uno-r4-wifi-usb-bridge/releases + +*/ + + +#include "WiFiS3.h" +#include "OTAUpdate.h" +#include "root_ca.h" +#include "arduino_secrets.h" + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) + +int status = WL_IDLE_STATUS; + +OTAUpdate ota; +static char const OTA_FILE_LOCATION[] = "https://downloads.arduino.cc/ota/UNOR4USBBridge.ino.ota"; + +/* -------------------------------------------------------------------------- */ +void setup() { +/* -------------------------------------------------------------------------- */ + //Initialize serial and wait for port to open: + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // check for the Wi-Fi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with Wi-Fi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + + Serial.print("Current Wi-Fi firmware version: "); + Serial.println(fv); + + // attempt to connect to Wi-Fi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); + + // wait 1 seconds for connection: + delay(1000); + } + + printWiFiStatus(); + + OTAUpdate::Error ret = OTAUpdate::Error::None; + ret = ota.begin(); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.begin() error: "); + Serial.println((int)ret); + return; + } + ret = ota.setCACert(root_ca); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.setCACert() error: "); + Serial.println((int)ret); + return; + } + if(ota.download(OTA_FILE_LOCATION) <= 0) { + Serial.println("ota.download() error: "); + Serial.println((int)ret); + return; + } + ret = ota.verify(); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.verify() error: "); + Serial.println((int)ret); + return; + } + ret = ota.update(); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.update() error: "); + Serial.println((int)ret); + return; + } + ret = ota.reset(); + if(ret != OTAUpdate::Error::None) { + Serial.println("ota.reset() error: "); + Serial.println((int)ret); + return; + } +} + + +/* -------------------------------------------------------------------------- */ +void loop() { +/* -------------------------------------------------------------------------- */ + + String fv = WiFi.firmwareVersion(); + Serial.print("Updated Wi-Fi firmware version: "); + Serial.println(fv); + delay(1000); +} + +/* -------------------------------------------------------------------------- */ +void printWiFiStatus() { +/* -------------------------------------------------------------------------- */ + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.print(rssi); + Serial.println(" dBm"); +} diff --git a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/arduino_secrets.h b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/arduino_secrets.h new file mode 100644 index 000000000..0c9fdd556 --- /dev/null +++ b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS "" diff --git a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/root_ca.h b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/root_ca.h new file mode 100644 index 000000000..ff7d2f738 --- /dev/null +++ b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/root_ca.h @@ -0,0 +1,88 @@ +const char* root_ca = \ +/* Baltimore CyberTrust Root */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE\n" \ +"ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li\n" \ +"ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC\n" \ +"SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs\n" \ +"dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME\n" \ +"uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB\n" \ +"UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C\n" \ +"G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9\n" \ +"XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr\n" \ +"l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI\n" \ +"VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB\n" \ +"BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh\n" \ +"cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5\n" \ +"hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa\n" \ +"Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H\n" \ +"RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n" \ +"-----END CERTIFICATE-----\n" \ +/* Amazon Root CA 1 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD\n" \ +"VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1\n" \ +"MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv\n" \ +"bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" \ +"ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH\n" \ +"FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ\n" \ +"gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t\n" \ +"dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce\n" \ +"VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB\n" \ +"/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3\n" \ +"DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM\n" \ +"CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy\n" \ +"8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa\n" \ +"2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2\n" \ +"xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5\n" \ +"-----END CERTIFICATE-----\n" \ +/* Amazon Root CA 2 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD\n" \ +"VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1\n" \ +"MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv\n" \ +"bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\n" \ +"ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4\n" \ +"kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp\n" \ +"N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9\n" \ +"AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd\n" \ +"fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx\n" \ +"kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS\n" \ +"btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0\n" \ +"Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN\n" \ +"c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+\n" \ +"3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw\n" \ +"DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA\n" \ +"A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY\n" \ +"+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE\n" \ +"YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW\n" \ +"xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ\n" \ +"gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW\n" \ +"aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV\n" \ +"Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3\n" \ +"KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi\n" \ +"JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=\n" \ +"-----END CERTIFICATE-----\n" \ +/* Amazon Root CA 3 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG\n" \ +"EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy\n" \ +"NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\n" \ +"MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB\n" \ +"f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr\n" \ +"Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43\n" \ +"rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc\n" \ +"eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==\n" \ +"-----END CERTIFICATE-----\n" \ +/* Amazon Root CA 4 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG\n" \ +"EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy\n" \ +"NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\n" \ +"MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN\n" \ +"/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri\n" \ +"83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n" \ +"HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA\n" \ +"MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1\n" \ +"AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==\n" \ +"-----END CERTIFICATE-----\n"; diff --git a/libraries/OTAUpdate/library.properties b/libraries/OTAUpdate/library.properties new file mode 100644 index 000000000..a542e05d8 --- /dev/null +++ b/libraries/OTAUpdate/library.properties @@ -0,0 +1,9 @@ +name=OTAUpdate +version=0.0.1 +author=Arduino +maintainer=Arduino +sentence=Library for Arduino UNO R4 WiFi OTA Update +paragraph= +category=Communication +url= +architectures=renesas,renesas_uno \ No newline at end of file diff --git a/libraries/OTAUpdate/src/OTAUpdate.cpp b/libraries/OTAUpdate/src/OTAUpdate.cpp new file mode 100644 index 000000000..c98afda07 --- /dev/null +++ b/libraries/OTAUpdate/src/OTAUpdate.cpp @@ -0,0 +1,123 @@ +/* + OTA.cpp + Copyright (c) 2023 Arduino SA. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "OTAUpdate.h" + +using namespace std; + +OTAUpdate::OTAUpdate() {} + +OTAUpdate::Error OTAUpdate::setCACert(const char* root_ca) { + string res = ""; + if ( root_ca != nullptr && strlen(root_ca) > 0) { + modem.write_nowait(string(PROMPT(_OTA_SETCAROOT)), res, "%s%d\r\n", CMD_WRITE(_OTA_SETCAROOT), strlen(root_ca)); + if(modem.passthrough((uint8_t *)root_ca, strlen(root_ca))) { + return Error::None; + } + return Error::Modem; + } + return Error::Library; +} + +OTAUpdate::Error OTAUpdate::begin() { + string res = ""; + if (modem.write(string(PROMPT(_OTA_BEGIN)), res, "%s", CMD(_OTA_BEGIN))) { + return static_cast(atoi(res.c_str())); + } + return Error::Modem; +} + +OTAUpdate::Error OTAUpdate::begin(const char* file_path) { + string res = ""; + if ( file_path != nullptr && strlen(file_path) > 0) { + if (modem.write(string(PROMPT(_OTA_BEGIN)), res, "%s%s\r\n", CMD_WRITE(_OTA_BEGIN), file_path)) { + return static_cast(atoi(res.c_str())); + } + return Error::Modem; + } + return Error::Library; +} + +int OTAUpdate::download(const char* url) { + string res = ""; + int ret = -1; + if ( url != nullptr && strlen(url) > 0) { + modem.timeout(EXTENDED_MODEM_TIMEOUT); + if(modem.write(string(PROMPT(_OTA_DOWNLOAD)), res, "%s%s\r\n", CMD_WRITE(_OTA_DOWNLOAD), url)) { + ret = atoi(res.c_str()); + } else { + ret = static_cast(Error::Modem); + } + } else { + ret = static_cast(Error::Library); + } + modem.timeout(MODEM_TIMEOUT); + return ret; +} + +int OTAUpdate::download(const char* url, const char* file_path) { + string res = ""; + int ret = -1; + if ( url != nullptr && strlen(url) > 0 && file_path != nullptr && strlen(file_path) >0) { + modem.timeout(EXTENDED_MODEM_TIMEOUT); + if(modem.write(string(PROMPT(_OTA_DOWNLOAD)), res, "%s%s,%s\r\n", CMD_WRITE(_OTA_DOWNLOAD), url, file_path)) { + ret = atoi(res.c_str()); + } else { + ret = static_cast(Error::Modem); + } + } else { + ret = static_cast(Error::Library); + } + modem.timeout(MODEM_TIMEOUT); + return ret; +} + +OTAUpdate::Error OTAUpdate::verify() { + string res = ""; + if (modem.write(string(PROMPT(_OTA_VERIFY)), res, "%s", CMD(_OTA_VERIFY))) { + return static_cast(atoi(res.c_str())); + } + return Error::Modem; +} + +OTAUpdate::Error OTAUpdate::update() { + string res = ""; + if (modem.write(string(PROMPT(_OTA_UPDATE)), res, "%s", CMD(_OTA_UPDATE))) { + return static_cast(atoi(res.c_str())); + } + return Error::Modem; +} + +OTAUpdate::Error OTAUpdate::update(const char* file_path) { + string res = ""; + if ( file_path != nullptr && strlen(file_path) > 0) { + if (modem.write(string(PROMPT(_OTA_UPDATE)), res, "%s%s\r\n", CMD_WRITE(_OTA_UPDATE), file_path)) { + return Error::None; + } + return Error::Modem; + } + return Error::Library; +} + +OTAUpdate::Error OTAUpdate::reset() { + string res = ""; + if (modem.write(string(PROMPT(_OTA_RESET)), res, "%s", CMD(_OTA_RESET))) { + return Error::None; + } + return Error::Modem; +} diff --git a/libraries/OTAUpdate/src/OTAUpdate.h b/libraries/OTAUpdate/src/OTAUpdate.h new file mode 100644 index 000000000..4afeaf0e2 --- /dev/null +++ b/libraries/OTAUpdate/src/OTAUpdate.h @@ -0,0 +1,63 @@ +/* + OTA.h + Copyright (c) 2023 Arduino SA. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef OTA_UPDATE_H +#define OTA_UPDATE_H + +#include "Arduino.h" +#include "WiFiCommands.h" +#include "Modem.h" + +class OTAUpdate { + +public: + + enum class Error: int { + None = 0, + StorageConfig = -1, + NoOtaStorage = -2, + OtaStorageInit = -3, + OtaStorageEnd = -4, + UrlParseError = -5, + ServerConnectError = -6, + HttpHeaderError = -7, + ParseHttpHeader = -8, + OtaHeaderLength = -9, + OtaHeaderCrc = -10, + OtaHeaderMagicNumber = -11, + OtaDownload = -12, + OtaFlash = -13, + Library = -14, + Modem = -15, + }; + + OTAUpdate(); + OTAUpdate::Error setCACert(const char* root_ca); + OTAUpdate::Error begin(); + OTAUpdate::Error begin(const char* file_path); + int download(const char* url); + int download(const char* url, const char* file_path); + OTAUpdate::Error verify(); + OTAUpdate::Error update(); + OTAUpdate::Error update(const char* file_path); + OTAUpdate::Error reset(); + +}; + +#endif /* OTA_UPDATE_H */ diff --git a/libraries/WiFiS3/src/Modem.h b/libraries/WiFiS3/src/Modem.h index 39bfd8150..3d8aee5b5 100644 --- a/libraries/WiFiS3/src/Modem.h +++ b/libraries/WiFiS3/src/Modem.h @@ -9,8 +9,9 @@ /* uncomment this will allow debug for passthrough "binary" commands */ #define MODEM_DEBUG_PASSTHROUGH -#define MODEM_TIMEOUT 10000 -#define MAX_BUFF_SIZE 64 +#define MODEM_TIMEOUT 10000 +#define EXTENDED_MODEM_TIMEOUT 60000 +#define MAX_BUFF_SIZE 128 #define DO_NOT_CHECK_CMD "NO_CMD_CHECK" @@ -62,6 +63,8 @@ class ModemClass { void debug(bool e) {enable_dbg = e;} #endif + void timeout(size_t timeout_ms) {_timeout = timeout_ms;} + private: bool buf_read(const std::string &cmd, std::string &data_res); bool delete_serial; diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index f1891ac96..0f4edc451 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -483,12 +483,14 @@ const char* CWifi::SSID() { if(modem.write(string(PROMPT(_MODE)),res, "%s" , CMD_READ(_MODE))) { if(atoi(res.c_str()) == 1) { if(modem.write(string(PROMPT(_GETSSID)), res, CMD_READ(_GETSSID))) { - return res.c_str(); + ssid = res; + return ssid.c_str(); } } else if(atoi(res.c_str()) == 2) { if(modem.write(string(PROMPT(_GETSOFTAPSSID)), res, CMD_READ(_GETSOFTAPSSID))) { - return res.c_str(); + apssid = res; + return apssid.c_str(); } } } @@ -521,7 +523,8 @@ const char* CWifi::softAPSSID() { /* -------------------------------------------------------------------------- */ string res = ""; if(modem.write(string(PROMPT(_GETSOFTAPSSID)), res, CMD_READ(_GETSOFTAPSSID))) { - return res.c_str(); + apssid = res; + return apssid.c_str(); } return ""; } diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index 43d1b0787..587d1648a 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -14,7 +14,7 @@ #define DEFAULT_NM_AP_ADDRESS IPAddress(255,255,255,0) -#define WIFI_FIRMWARE_LATEST_VERSION "0.2.1" +#define WIFI_FIRMWARE_LATEST_VERSION "0.3.0" class CAccessPoint { public: @@ -35,6 +35,8 @@ class CWifi { unsigned long _timeout; uint8_t mac[6]; std::vector access_points; + std::string ssid; + std::string apssid; IPAddress ip_ap = DEFAULT_IP_AP_ADDRESS;