diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 18d6908..7a4f0d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p Please ensure to specify the following: * Arduino IDE version (e.g. 1.8.19) or Platform.io version -* `ArduinoCore-mbed` Core Version (e.g. `ArduinoCore-mbed` mbed_portenta core v3.3.0) +* `ArduinoCore-mbed` Core Version (e.g. `ArduinoCore-mbed` mbed_portenta core v3.4.1) * `Portenta_H7` Board type (e.g. Portenta_H7 Rev2 ABX00042, etc.) * Contextual information (e.g. what you were trying to achieve) * Simplest possible steps to reproduce @@ -28,14 +28,13 @@ Please ensure to specify the following: ``` Arduino IDE version: 1.8.19 -`ArduinoCore-mbed` mbed_portenta core v3.3.0 +`ArduinoCore-mbed` mbed_portenta core v3.4.1 Portenta_H7 Rev2 ABX00042 OS: Ubuntu 20.04 LTS -Linux xy-Inspiron-3593 5.15.0-48-generic #54~20.04.1-Ubuntu SMP Thu Sep 1 16:17:26 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux +Linux xy-Inspiron-3593 5.15.0-52-generic #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux Context: I encountered a crash while using this library - Steps to reproduce: 1. ... 2. ... @@ -43,13 +42,37 @@ Steps to reproduce: 4. ... ``` +### Additional context + +Add any other context about the problem here. + +--- + ### Sending Feature Requests Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. +--- + ### Sending Pull Requests Pull Requests with changes and fixes are also welcome! +Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) + +1. Change directory to the library GitHub + +``` +xy@xy-Inspiron-3593:~$ cd Arduino/xy/Portenta_H7_AsyncWebServer_GitHub/ +xy@xy-Inspiron-3593:~/Arduino/xy/Portenta_H7_AsyncWebServer_GitHub$ +``` + +2. Issue astyle command + +``` +xy@xy-Inspiron-3593:~/Arduino/xy/Portenta_H7_AsyncWebServer_GitHub$ bash utils/restyle.sh +``` + + diff --git a/changelog.md b/changelog.md index b7aa674..c81fae3 100644 --- a/changelog.md +++ b/changelog.md @@ -5,12 +5,18 @@ [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) [![GitHub issues](https://img.shields.io/github/issues/khoih-prog/Portenta_H7_AsyncWebServer.svg)](http://github.com/khoih-prog/Portenta_H7_AsyncWebServer/issues) +Donate to my libraries using BuyMeACoffee + + + + --- --- ## Table of Contents * [Changelog](#changelog) + * [Releases v1.4.2](#Releases-v142) * [Releases v1.4.1](#Releases-v141) * [Releases v1.4.0](#Releases-v140) * [Releases v1.3.0](#Releases-v130) @@ -25,6 +31,12 @@ ## Changelog +### Releases v1.4.2 + +1. Add examples [Async_AdvancedWebServer_SendChunked](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/tree/main/examples/Async_AdvancedWebServer_SendChunked) and [AsyncWebServer_SendChunked](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/tree/main/examples/AsyncWebServer_SendChunked) to demo how to use `beginChunkedResponse()` to send large `html` in chunks +2. Use `allman astyle` and add `utils` +3. Update `Packages_Patches` + ### Releases v1.4.1 1. Don't need `memmove()`, CString no longer destroyed. Check [All memmove() removed - string no longer destroyed #11](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/pull/11) diff --git a/examples/Ethernet/AsyncWebServer_SendChunked/AsyncWebServer_SendChunked.ino b/examples/Ethernet/AsyncWebServer_SendChunked/AsyncWebServer_SendChunked.ino new file mode 100644 index 0000000..3b8288b --- /dev/null +++ b/examples/Ethernet/AsyncWebServer_SendChunked/AsyncWebServer_SendChunked.ino @@ -0,0 +1,254 @@ +/**************************************************************************************************************************** + AsyncWebServer_SendChunked.ino + + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi + + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi + + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) + Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer + Licensed under GPLv3 license + *****************************************************************************************************************************/ + +#if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) + #error For Portenta_H7 only +#endif + +#define _PORTENTA_H7_ATCP_LOGLEVEL_ 1 +#define _PORTENTA_H7_AWS_LOGLEVEL_ 4 + +#define USE_ETHERNET_PORTENTA_H7 true + +#include +#include +#warning Using Portenta_Ethernet lib for Portenta_H7. + +#include + +// In bytes +#define STRING_SIZE 50000 + +// Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 + +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, +}; +// Select the IP address according to your local network +IPAddress ip(192, 168, 2, 232); + +AsyncWebServer server(80); + +int reqCount = 0; // number of requests received + +#define BUFFER_SIZE 512 +char temp[BUFFER_SIZE]; + +void createPage(String &pageInput) +{ + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; + + snprintf(temp, BUFFER_SIZE - 1, + "\ +\ +\ +AsyncWebServer-%s\ +\ +\ +\ +

AsyncWebServer_SendChunked_Portenta_H7!

\ +

running on %s

\ +

Uptime: %d d %02d:%02d:%02d

\ +\ +", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); + + pageInput = temp; +} + +void handleNotFound(AsyncWebServerRequest *request) +{ + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); +} + +String out; + +void handleRoot(AsyncWebServerRequest *request) +{ + char temp[70]; + + // clear the String to start over + out = String(); + + createPage(out); + + out += "\r\n"; + + for (uint16_t lineIndex = 0; lineIndex < 500; lineIndex++) + { + out += ""; + } + + out += "
INDEXDATA
"; + out += String(lineIndex); + out += ""; + out += "Portenta_H7_AsyncWebServer_SendChunked_ABCDEFGHIJKLMNOPQRSTUVWXYZ
\r\n"; + + AWS_LOGDEBUG1("Total length to send in chunks =", out.length()); + + AsyncWebServerResponse *response = request->beginChunkedResponse("text/html", [](uint8_t *buffer, size_t maxLen, size_t filledLength) -> size_t + { + size_t len = min(maxLen, out.length() - filledLength); + memcpy(buffer, out.c_str() + filledLength, len); + + AWS_LOGDEBUG1("Bytes sent in chunk =", len); + + return len; + }); + + request->send(response); +} + +void setup() +{ + out.reserve(STRING_SIZE); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart AsyncWebServer_SendChunked on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); + + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + + Serial.print(F("AsyncWebServer is @ IP : ")); + Serial.println(Ethernet.localIP()); +} + +void heartBeatPrint() +{ + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } +} + +void check_status() +{ + static unsigned long checkstatus_timeout = 0; + +#define STATUS_CHECK_INTERVAL 10000L + + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } +} + +void loop() +{ + check_status(); +} diff --git a/examples/Ethernet/Async_AdvancedWebServer/Async_AdvancedWebServer.ino b/examples/Ethernet/Async_AdvancedWebServer/Async_AdvancedWebServer.ino index 0656c90..8c6e840 100644 --- a/examples/Ethernet/Async_AdvancedWebServer/Async_AdvancedWebServer.ino +++ b/examples/Ethernet/Async_AdvancedWebServer/Async_AdvancedWebServer.ino @@ -2,7 +2,7 @@ Async_AdvancedWebServer.ino - Dead simple AsyncWebServer for STM32 LAN8720 or built-in LAN8742A Ethernet For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) @@ -39,7 +39,7 @@ *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_ATCP_LOGLEVEL_ 1 @@ -58,26 +58,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); @@ -95,15 +95,15 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); - int sec = millis() / 1000; - int min = sec / 60; - int hr = min / 60; - int day = hr / 24; + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; - snprintf(temp, BUFFER_SIZE - 1, - "\ + snprintf(temp, BUFFER_SIZE - 1, + "\ \ \ AsyncWebServer-%s\ @@ -119,162 +119,166 @@ body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Col \ ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); - request->send(200, "text/html", temp); + request->send(200, "text/html", temp); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - String message = "File Not Found\n\n"; - - message += "URI: "; - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } void drawGraph(AsyncWebServerRequest *request) { - String out; - - out.reserve(4000); - char temp[70]; - - out += "\n"; - out += "\n"; - out += "\n"; - int y = rand() % 130; - - for (int x = 10; x < 300; x += 10) - { - int y2 = rand() % 130; - sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); - out += temp; - y = y2; - } - out += "\n\n"; - - request->send(200, "image/svg+xml", out); + String out; + + out.reserve(4000); + char temp[70]; + + out += "\n"; + out += "\n"; + out += "\n"; + int y = rand() % 130; + + for (int x = 10; x < 300; x += 10) + { + int y2 = rand() % 130; + sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); + out += temp; + y = y2; + } + + out += "\n\n"; + + request->send(200, "image/svg+xml", out); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); - Serial.begin(115200); - while (!Serial && millis() < 5000); + delay(200); - delay(200); + Serial.print("\nStart Async_AdvancedWebServer on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - Serial.print("\nStart Async_AdvancedWebServer on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + /////////////////////////////////// - /////////////////////////////////// + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } + Serial.print(F("Using mac index = ")); + Serial.println(index); - Serial.print(F("Using mac index = ")); - Serial.println(index); + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); + /////////////////////////////////// - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); - server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) - { - drawGraph(request); - }); + server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) + { + drawGraph(request); + }); - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); - server.onNotFound(handleNotFound); + server.onNotFound(handleNotFound); - server.begin(); + server.begin(); - Serial.print(F("HTTP EthernetWebServer is @ IP : ")); - Serial.println(Ethernet.localIP()); + Serial.print(F("HTTP EthernetWebServer is @ IP : ")); + Serial.println(Ethernet.localIP()); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/Ethernet/Async_AdvancedWebServer_MemoryIssues_SendArduinoString/Async_AdvancedWebServer_MemoryIssues_SendArduinoString.ino b/examples/Ethernet/Async_AdvancedWebServer_MemoryIssues_SendArduinoString/Async_AdvancedWebServer_MemoryIssues_SendArduinoString.ino index 7ab9e18..b29484e 100644 --- a/examples/Ethernet/Async_AdvancedWebServer_MemoryIssues_SendArduinoString/Async_AdvancedWebServer_MemoryIssues_SendArduinoString.ino +++ b/examples/Ethernet/Async_AdvancedWebServer_MemoryIssues_SendArduinoString/Async_AdvancedWebServer_MemoryIssues_SendArduinoString.ino @@ -2,7 +2,7 @@ Async_AdvancedWebServer_MemoryIssues_SendArduinoString.ino - - Dead simple AsyncWebServer for Portenta_H7 For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) @@ -39,7 +39,7 @@ *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_ATCP_LOGLEVEL_ 1 @@ -61,26 +61,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); @@ -98,15 +98,15 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); - int sec = millis() / 1000; - int min = sec / 60; - int hr = min / 60; - int day = hr / 24; + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; - snprintf(temp, BUFFER_SIZE - 1, - "\ + snprintf(temp, BUFFER_SIZE - 1, + "\ \ \ AsyncWebServer-%s\ @@ -122,210 +122,213 @@ body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Col \ ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); - request->send(200, "text/html", temp); + request->send(200, "text/html", temp); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - String message = "File Not Found\n\n"; - - message += "URI: "; - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } void PrintHeapData(String hIn) { - static mbed_stats_heap_t heap_stats; - static uint32_t maxHeapSize = 0; - - mbed_stats_heap_get(&heap_stats); - - // Print and update only when different - if (maxHeapSize != heap_stats.max_size) - { - maxHeapSize = heap_stats.max_size; - - Serial.print("\nHEAP DATA - "); - Serial.print(hIn); - - Serial.print(" Cur heap: "); - Serial.print(heap_stats.current_size); - Serial.print(" Res Size: "); - Serial.print(heap_stats.reserved_size); - Serial.print(" Max heap: "); - Serial.println(heap_stats.max_size); - } + static mbed_stats_heap_t heap_stats; + static uint32_t maxHeapSize = 0; + + mbed_stats_heap_get(&heap_stats); + + // Print and update only when different + if (maxHeapSize != heap_stats.max_size) + { + maxHeapSize = heap_stats.max_size; + + Serial.print("\nHEAP DATA - "); + Serial.print(hIn); + + Serial.print(" Cur heap: "); + Serial.print(heap_stats.current_size); + Serial.print(" Res Size: "); + Serial.print(heap_stats.reserved_size); + Serial.print(" Max heap: "); + Serial.println(heap_stats.max_size); + } } void PrintStringSize(String & out) -{ - static uint32_t count = 0; +{ + static uint32_t count = 0; - // Print only when cStr length too large and corrupting memory or every (20 * 5) s - if ( (out.length() >= STRING_SIZE) || (++count > 20) ) - { - Serial.print("\nOut String Length="); - Serial.println(out.length()); + // Print only when cStr length too large and corrupting memory or every (20 * 5) s + if ( (out.length() >= STRING_SIZE) || (++count > 20) ) + { + Serial.print("\nOut String Length="); + Serial.println(out.length()); - count = 0; - } + count = 0; + } } void drawGraph(AsyncWebServerRequest *request) { - String out; + String out; + + out.reserve(STRING_SIZE); + char temp[70]; - out.reserve(STRING_SIZE); - char temp[70]; + out += "\n"; + out += "\n"; + out += "\n"; + int y = rand() % 130; - out += "\n"; - out += "\n"; - out += "\n"; - int y = rand() % 130; + for (int x = 10; x < 5000; x += 10) + { + int y2 = rand() % 130; + sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); + out += temp; + y = y2; + } - for (int x = 10; x < 5000; x += 10) - { - int y2 = rand() % 130; - sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); - out += temp; - y = y2; - } - - out += "\n\n"; + out += "\n\n"; - PrintHeapData("Pre Send"); + PrintHeapData("Pre Send"); - PrintStringSize(out); + PrintStringSize(out); - request->send(200, "image/svg+xml", out); + request->send(200, "image/svg+xml", out); - PrintHeapData("Post Send"); + PrintHeapData("Post Send"); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); - Serial.begin(115200); - while (!Serial && millis() < 5000); + delay(200); - delay(200); + Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_SendArduinoString on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_SendArduinoString on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + AWS_LOGDEBUG3("TCP_MSS =", TCP_MSS, ", TCP_SND_BUF =", TCP_SND_BUF); - AWS_LOGDEBUG3("TCP_MSS =", TCP_MSS, ", TCP_SND_BUF =", TCP_SND_BUF); + /////////////////////////////////// - /////////////////////////////////// + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } + Serial.print(F("Using mac index = ")); + Serial.println(index); - Serial.print(F("Using mac index = ")); - Serial.println(index); + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); + /////////////////////////////////// - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); - server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) - { - drawGraph(request); - }); + server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) + { + drawGraph(request); + }); - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); - server.onNotFound(handleNotFound); + server.onNotFound(handleNotFound); - server.begin(); + server.begin(); - Serial.print(F("HTTP EthernetWebServer is @ IP : ")); - Serial.println(Ethernet.localIP()); + Serial.print(F("HTTP EthernetWebServer is @ IP : ")); + Serial.println(Ethernet.localIP()); - PrintHeapData("Pre Create Arduino String"); + PrintHeapData("Pre Create Arduino String"); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/Ethernet/Async_AdvancedWebServer_MemoryIssues_Send_CString/Async_AdvancedWebServer_MemoryIssues_Send_CString.ino b/examples/Ethernet/Async_AdvancedWebServer_MemoryIssues_Send_CString/Async_AdvancedWebServer_MemoryIssues_Send_CString.ino index d9f1f0a..d65b46b 100644 --- a/examples/Ethernet/Async_AdvancedWebServer_MemoryIssues_Send_CString/Async_AdvancedWebServer_MemoryIssues_Send_CString.ino +++ b/examples/Ethernet/Async_AdvancedWebServer_MemoryIssues_Send_CString/Async_AdvancedWebServer_MemoryIssues_Send_CString.ino @@ -1,8 +1,8 @@ /**************************************************************************************************************************** Async_AdvancedWebServer_MemoryIssues_Send_CString.ino - Dead simple AsyncWebServer for Portenta_H7 - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) @@ -39,7 +39,7 @@ *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_ATCP_LOGLEVEL_ 1 @@ -62,7 +62,7 @@ char *cStr; #define USING_CSTRING_IN_SDRAM true #if USING_CSTRING_IN_SDRAM - #include "SDRAM.h" + #include "SDRAM.h" #endif // Enter a MAC address and IP address for your controller below. @@ -70,26 +70,26 @@ char *cStr; byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); @@ -106,15 +106,15 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); - int sec = millis() / 1000; - int min = sec / 60; - int hr = min / 60; - int day = hr / 24; + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; - snprintf(temp, BUFFER_SIZE - 1, - "\ + snprintf(temp, BUFFER_SIZE - 1, + "\ \ \ AsyncWebServer-%s\ @@ -130,228 +130,230 @@ body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Col \ ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); - request->send(200, "text/html", temp, false); + request->send(200, "text/html", temp, false); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - String message = "File Not Found\n\n"; - - message += "URI: "; - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } void PrintHeapData(String hIn) { - static mbed_stats_heap_t heap_stats; - static uint32_t maxHeapSize = 0; - - mbed_stats_heap_get(&heap_stats); - - // Print and update only when different - if (maxHeapSize != heap_stats.max_size) - { - maxHeapSize = heap_stats.max_size; - - Serial.print("\nHEAP DATA - "); - Serial.print(hIn); - - Serial.print(" Cur heap: "); - Serial.print(heap_stats.current_size); - Serial.print(" Res Size: "); - Serial.print(heap_stats.reserved_size); - Serial.print(" Max heap: "); - Serial.println(heap_stats.max_size); - } + static mbed_stats_heap_t heap_stats; + static uint32_t maxHeapSize = 0; + + mbed_stats_heap_get(&heap_stats); + + // Print and update only when different + if (maxHeapSize != heap_stats.max_size) + { + maxHeapSize = heap_stats.max_size; + + Serial.print("\nHEAP DATA - "); + Serial.print(hIn); + + Serial.print(" Cur heap: "); + Serial.print(heap_stats.current_size); + Serial.print(" Res Size: "); + Serial.print(heap_stats.reserved_size); + Serial.print(" Max heap: "); + Serial.println(heap_stats.max_size); + } } void PrintStringSize(const char* cStr) -{ - Serial.print("\nOut String Length="); - Serial.println(strlen(cStr)); +{ + Serial.print("\nOut String Length="); + Serial.println(strlen(cStr)); } -void drawGraph(AsyncWebServerRequest *request) +void drawGraph(AsyncWebServerRequest *request) { - char temp[80]; + char temp[80]; - cStr[0] = '\0'; + cStr[0] = '\0'; - strcat(cStr, "\n"); - strcat(cStr, "\n"); - strcat(cStr, "\n"); - int y = rand() % 130; + strcat(cStr, "\n"); + strcat(cStr, "\n"); + strcat(cStr, "\n"); + int y = rand() % 130; - for (int x = 10; x < 5000; x += 10) - { - int y2 = rand() % 130; - sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); - strcat(cStr, temp); - y = y2; - } - - strcat(cStr, "\n\n"); + for (int x = 10; x < 5000; x += 10) + { + int y2 = rand() % 130; + sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); + strcat(cStr, temp); + y = y2; + } - PrintHeapData("Pre Send"); + strcat(cStr, "\n\n"); - // Print only when cStr length too large and corrupting memory - if ( (strlen(cStr) >= CSTRING_SIZE)) - { - PrintStringSize(cStr); - } + PrintHeapData("Pre Send"); - request->send(200, "image/svg+xml", cStr, false); + // Print only when cStr length too large and corrupting memory + if ( (strlen(cStr) >= CSTRING_SIZE)) + { + PrintStringSize(cStr); + } - PrintHeapData("Post Send"); + request->send(200, "image/svg+xml", cStr, false); + + PrintHeapData("Post Send"); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); - Serial.begin(115200); - while (!Serial && millis() < 5000); + while (!Serial && millis() < 5000); - delay(200); + delay(200); #if USING_CSTRING_IN_SDRAM - Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString using SDRAM on "); + Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString using SDRAM on "); #else - Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString on "); + Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString on "); #endif - - Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - AWS_LOGDEBUG3("TCP_MSS =", TCP_MSS, ", TCP_SND_BUF =", TCP_SND_BUF); - + + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + AWS_LOGDEBUG3("TCP_MSS =", TCP_MSS, ", TCP_SND_BUF =", TCP_SND_BUF); + #if USING_CSTRING_IN_SDRAM - SDRAM.begin(); + SDRAM.begin(); - cStr = (char *) SDRAM.malloc(CSTRING_SIZE); // make a little larger than required + cStr = (char *) SDRAM.malloc(CSTRING_SIZE); // make a little larger than required #else - cStr = (char *) malloc(CSTRING_SIZE); // make a little larger than required + cStr = (char *) malloc(CSTRING_SIZE); // make a little larger than required #endif - if (cStr == NULL) - { - Serial.println("Unable top Allocate RAM"); - - for(;;); - } + if (cStr == NULL) + { + Serial.println("Unable top Allocate RAM"); + + for (;;); + } + + /////////////////////////////////// - /////////////////////////////////// + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } + Serial.print(F("Using mac index = ")); + Serial.println(index); - Serial.print(F("Using mac index = ")); - Serial.println(index); + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); + /////////////////////////////////// - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); - server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) - { - drawGraph(request); - }); + server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) + { + drawGraph(request); + }); - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); - server.onNotFound(handleNotFound); + server.onNotFound(handleNotFound); - server.begin(); + server.begin(); - Serial.print(F("HTTP EthernetWebServer is @ IP : ")); - Serial.println(Ethernet.localIP()); + Serial.print(F("HTTP EthernetWebServer is @ IP : ")); + Serial.println(Ethernet.localIP()); - PrintHeapData("Pre Create Arduino String"); + PrintHeapData("Pre Create Arduino String"); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - //Serial.println(); - PrintStringSize(cStr); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + //Serial.println(); + PrintStringSize(cStr); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/Ethernet/Async_AdvancedWebServer_SendChunked/Async_AdvancedWebServer_SendChunked.ino b/examples/Ethernet/Async_AdvancedWebServer_SendChunked/Async_AdvancedWebServer_SendChunked.ino new file mode 100644 index 0000000..cb75ceb --- /dev/null +++ b/examples/Ethernet/Async_AdvancedWebServer_SendChunked/Async_AdvancedWebServer_SendChunked.ino @@ -0,0 +1,302 @@ +/**************************************************************************************************************************** + Async_AdvancedWebServer_SendChunked.ino + + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi + + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi + + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) + Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer + Licensed under GPLv3 license + + Copyright (c) 2015, Majenko Technologies + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + Neither the name of Majenko Technologies nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************************************************************/ + +#if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) + #error For Portenta_H7 only +#endif + +#define _PORTENTA_H7_ATCP_LOGLEVEL_ 1 +#define _PORTENTA_H7_AWS_LOGLEVEL_ 4 + +#define USE_ETHERNET_PORTENTA_H7 true + +#include +#include +#warning Using Portenta_Ethernet lib for Portenta_H7. + +#include + +// In bytes +#define STRING_SIZE 40000 + +// Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 + +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, +}; +// Select the IP address according to your local network +IPAddress ip(192, 168, 2, 232); + +AsyncWebServer server(80); + +int reqCount = 0; // number of requests received + +#define LED_OFF HIGH +#define LED_ON LOW + +#define BUFFER_SIZE 512 +char temp[BUFFER_SIZE]; + +void handleRoot(AsyncWebServerRequest *request) +{ + digitalWrite(LED_BUILTIN, LED_ON); + + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; + + snprintf(temp, BUFFER_SIZE - 1, + "\ +\ +\ +AsyncWebServer-%s\ +\ +\ +\ +

Async_AdvancedWebServer_SendChunked!

\ +

running on %s

\ +

Uptime: %d d %02d:%02d:%02d

\ +\ +\ +", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); + + request->send(200, "text/html", temp); + + digitalWrite(LED_BUILTIN, LED_OFF); +} + +void handleNotFound(AsyncWebServerRequest *request) +{ + digitalWrite(LED_BUILTIN, LED_ON); + + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + + digitalWrite(LED_BUILTIN, LED_OFF); +} + +String out; + +void drawGraph(AsyncWebServerRequest *request) +{ + char temp[70]; + + out = String(); + + out += "\n"; + out += "\n"; + out += "\n"; + int y = rand() % 130; + + for (int x = 10; x < 5000; x += 10) + { + int y2 = rand() % 130; + sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); + out += temp; + y = y2; + } + + out += "\n\n"; + + AWS_LOGDEBUG1(F("Total length to send in chunks ="), out.length()); + + AsyncWebServerResponse *response = request->beginChunkedResponse("image/svg+xml", [](uint8_t *buffer, size_t maxLen, size_t filledLength) -> size_t + { + size_t len = min(maxLen, out.length() - filledLength); + memcpy(buffer, out.c_str() + filledLength, len); + + AWS_LOGDEBUG1(F("Bytes sent in chunk ="), len); + + return len; + }); + + request->send(response); +} + +void setup() +{ + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + out.reserve(STRING_SIZE); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_AdvancedWebServer_SendChunked on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); + + server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) + { + drawGraph(request); + }); + + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + + Serial.print(F("AsyncWebServer is @ IP : ")); + Serial.println(Ethernet.localIP()); +} + +void heartBeatPrint() +{ + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } +} + +void check_status() +{ + static unsigned long checkstatus_timeout = 0; + +#define STATUS_CHECK_INTERVAL 10000L + + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } +} + +void loop() +{ + check_status(); +} diff --git a/examples/Ethernet/Async_HelloServer/Async_HelloServer.ino b/examples/Ethernet/Async_HelloServer/Async_HelloServer.ino index 2051fc5..9b73ccd 100644 --- a/examples/Ethernet/Async_HelloServer/Async_HelloServer.ino +++ b/examples/Ethernet/Async_HelloServer/Async_HelloServer.ino @@ -1,17 +1,17 @@ /**************************************************************************************************************************** Async_HelloServer.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 4 @@ -29,26 +29,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); @@ -63,139 +63,142 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); - snprintf(temp, BUFFER_SIZE - 1, "Hello from Async_HelloServer on %s\n", BOARD_NAME); - request->send(200, "text/plain", temp); - - digitalWrite(LED_BUILTIN, LED_OFF); + snprintf(temp, BUFFER_SIZE - 1, "Hello from Async_HelloServer on %s\n", BOARD_NAME); + request->send(200, "text/plain", temp); + + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - - String message = "File Not Found\n\n"; - - message += "URI: "; - //message += server.uri(); - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + + String message = "File Not Found\n\n"; + + message += "URI: "; + //message += server.uri(); + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); - - Serial.begin(115200); - while (!Serial && millis() < 5000); - - delay(200); - - Serial.print("\nStart Async_HelloServer on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; - - // Use Static IP - //Ethernet.begin(mac[index], ip); - //Ethernet.begin(ip); - // Use DHCP dynamic IP and random mac - //Ethernet.begin(mac[index]); - Ethernet.begin(); - - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); - - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } - - Serial.print(F("Using mac index = ")); - Serial.println(index); - - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); - - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); - - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); - - server.onNotFound(handleNotFound); - - server.begin(); - - Serial.print(F("HTTP EthernetWebServer is @ IP : ")); - Serial.println(Ethernet.localIP()); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_HelloServer on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + //Ethernet.begin(ip); + // Use DHCP dynamic IP and random mac + //Ethernet.begin(mac[index]); + Ethernet.begin(); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); + + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + + Serial.print(F("HTTP EthernetWebServer is @ IP : ")); + Serial.println(Ethernet.localIP()); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - //check_status(); + //check_status(); } diff --git a/examples/Ethernet/Async_HelloServer2/Async_HelloServer2.ino b/examples/Ethernet/Async_HelloServer2/Async_HelloServer2.ino index 49497c8..a048c64 100644 --- a/examples/Ethernet/Async_HelloServer2/Async_HelloServer2.ino +++ b/examples/Ethernet/Async_HelloServer2/Async_HelloServer2.ino @@ -1,17 +1,17 @@ /**************************************************************************************************************************** Async_HelloServer.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -29,26 +29,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); @@ -63,159 +63,162 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); + + snprintf(temp, BUFFER_SIZE - 1, "Hello from Async_HelloServer2 on %s\n", BOARD_NAME); + request->send(200, "text/plain", temp); - snprintf(temp, BUFFER_SIZE - 1, "Hello from Async_HelloServer2 on %s\n", BOARD_NAME); - request->send(200, "text/plain", temp); - - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - String message = "File Not Found\n\n"; - - message += "URI: "; - //message += server.uri(); - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + //message += server.uri(); + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); - - Serial.begin(115200); - while (!Serial && millis() < 5000); - - delay(200); - - Serial.print("\nStart Async_HelloServer2 on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; - - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); - - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); - - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } - - Serial.print(F("Using mac index = ")); - Serial.println(index); - - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); - - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); - - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); - - server.on("/gif", [](AsyncWebServerRequest * request) - { - static const uint8_t gif[] = - { - 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x01, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x19, 0x8c, 0x8f, 0xa9, 0xcb, 0x9d, - 0x00, 0x5f, 0x74, 0xb4, 0x56, 0xb0, 0xb0, 0xd2, 0xf2, 0x35, 0x1e, 0x4c, - 0x0c, 0x24, 0x5a, 0xe6, 0x89, 0xa6, 0x4d, 0x01, 0x00, 0x3b - }; - - char gif_colored[sizeof(gif)]; - - memcpy(gif_colored, gif, sizeof(gif)); - - // Set the background to a random set of colors - gif_colored[16] = millis() % 256; - gif_colored[17] = millis() % 256; - gif_colored[18] = millis() % 256; - - request->send(200, (char *) "image/gif", gif_colored); - }); - - server.onNotFound(handleNotFound); - - server.begin(); - - Serial.print("HTTP EthernetWebServer started @ IP : "); - Serial.println(Ethernet.localIP()); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_HelloServer2 on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); + + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); + + server.on("/gif", [](AsyncWebServerRequest * request) + { + static const uint8_t gif[] = + { + 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x01, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x19, 0x8c, 0x8f, 0xa9, 0xcb, 0x9d, + 0x00, 0x5f, 0x74, 0xb4, 0x56, 0xb0, 0xb0, 0xd2, 0xf2, 0x35, 0x1e, 0x4c, + 0x0c, 0x24, 0x5a, 0xe6, 0x89, 0xa6, 0x4d, 0x01, 0x00, 0x3b + }; + + char gif_colored[sizeof(gif)]; + + memcpy(gif_colored, gif, sizeof(gif)); + + // Set the background to a random set of colors + gif_colored[16] = millis() % 256; + gif_colored[17] = millis() % 256; + gif_colored[18] = millis() % 256; + + request->send(200, (char *) "image/gif", gif_colored); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + + Serial.print("HTTP EthernetWebServer started @ IP : "); + Serial.println(Ethernet.localIP()); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/Ethernet/Async_HttpBasicAuth/Async_HttpBasicAuth.ino b/examples/Ethernet/Async_HttpBasicAuth/Async_HttpBasicAuth.ino index f8e107e..79e5f5d 100644 --- a/examples/Ethernet/Async_HttpBasicAuth/Async_HttpBasicAuth.ino +++ b/examples/Ethernet/Async_HttpBasicAuth/Async_HttpBasicAuth.ino @@ -1,17 +1,17 @@ /**************************************************************************************************************************** Async_HttpBasicAuth.ino - Dead simple AsyncWebServer for STM32 LAN8720 or built-in LAN8742A Ethernet - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -29,26 +29,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); @@ -60,108 +60,111 @@ const char* www_password = "portenta"; void setup() { - Serial.begin(115200); - while (!Serial && millis() < 5000); - - delay(200); - - Serial.print("\nStart Async_HTTPBasicAuth on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; - - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); - - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); - - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } - - Serial.print(F("Using mac index = ")); - Serial.println(index); - - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); - - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - if (!request->authenticate(www_username, www_password)) - { - return request->requestAuthentication(); - } - - request->send(200, "text/plain", "Login OK"); - }); - - - server.begin(); - - Serial.print(F("Async_HttpBasicAuth started @ IP : ")); - Serial.println(Ethernet.localIP()); - - Serial.print(F("Open http://")); - Serial.print(Ethernet.localIP()); - Serial.println(F("/ in your browser to see it working")); - - Serial.print(F("Login using username = ")); - Serial.print(www_username); - Serial.print(F(" and password = ")); - Serial.println(www_password); + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_HTTPBasicAuth on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + if (!request->authenticate(www_username, www_password)) + { + return request->requestAuthentication(); + } + + request->send(200, "text/plain", "Login OK"); + }); + + + server.begin(); + + Serial.print(F("Async_HttpBasicAuth started @ IP : ")); + Serial.println(Ethernet.localIP()); + + Serial.print(F("Open http://")); + Serial.print(Ethernet.localIP()); + Serial.println(F("/ in your browser to see it working")); + + Serial.print(F("Login using username = ")); + Serial.print(www_username); + Serial.print(F(" and password = ")); + Serial.println(www_password); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/Ethernet/Async_PostServer/Async_PostServer.ino b/examples/Ethernet/Async_PostServer/Async_PostServer.ino index 363968f..cf2616a 100644 --- a/examples/Ethernet/Async_PostServer/Async_PostServer.ino +++ b/examples/Ethernet/Async_PostServer/Async_PostServer.ino @@ -1,17 +1,17 @@ /**************************************************************************************************************************** Async_PostServer.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -29,26 +29,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); @@ -79,158 +79,165 @@ body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Col void handleRoot(AsyncWebServerRequest *request) { - request->send(200, "text/html", postForms); + request->send(200, "text/html", postForms); } void handlePlain(AsyncWebServerRequest *request) { - if (request->method() != HTTP_POST) - { - request->send(405, "text/plain", "Method Not Allowed"); - } - else - { - request->send(200, "text/plain", "POST body was:\n" + request->arg("plain")); - } + if (request->method() != HTTP_POST) + { + request->send(405, "text/plain", "Method Not Allowed"); + } + else + { + request->send(200, "text/plain", "POST body was:\n" + request->arg("plain")); + } } void handleForm(AsyncWebServerRequest *request) { - if (request->method() != HTTP_POST) - { - request->send(405, "text/plain", "Method Not Allowed"); - } - else - { - String message = "POST form was:\n"; - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - request->send(200, "text/plain", message); - } + if (request->method() != HTTP_POST) + { + request->send(405, "text/plain", "Method Not Allowed"); + } + else + { + String message = "POST form was:\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(200, "text/plain", message); + } } void handleNotFound(AsyncWebServerRequest *request) { - String message = "File Not Found\n\n"; - message += "URI: "; - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - request->send(404, "text/plain", message); + String message = "File Not Found\n\n"; + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); } void setup() { - Serial.begin(115200); - while (!Serial && millis() < 5000); + Serial.begin(115200); + + while (!Serial && millis() < 5000); - delay(200); + delay(200); - Serial.print("\nStart Async_PostServer on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + Serial.print("\nStart Async_PostServer on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - /////////////////////////////////// + /////////////////////////////////// - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } - Serial.print(F("Using mac index = ")); - Serial.println(index); + Serial.print(F("Using mac index = ")); + Serial.println(index); - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); - /////////////////////////////////// + /////////////////////////////////// - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); - //server.on("/postplain/", handlePlain); - server.on("/postplain/", HTTP_POST, [](AsyncWebServerRequest * request) - { - handlePlain(request); - }); + //server.on("/postplain/", handlePlain); + server.on("/postplain/", HTTP_POST, [](AsyncWebServerRequest * request) + { + handlePlain(request); + }); - //server.on("/postform/", handleForm); - server.on("/postform/", HTTP_POST, [](AsyncWebServerRequest * request) - { - handleForm(request); - }); + //server.on("/postform/", handleForm); + server.on("/postform/", HTTP_POST, [](AsyncWebServerRequest * request) + { + handleForm(request); + }); - server.onNotFound(handleNotFound); + server.onNotFound(handleNotFound); - server.begin(); + server.begin(); - Serial.print(F("HTTP EthernetWebServer started @ IP : ")); - Serial.println(Ethernet.localIP()); + Serial.print(F("HTTP EthernetWebServer started @ IP : ")); + Serial.println(Ethernet.localIP()); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/Ethernet/MQTTClient_Auth/MQTTClient_Auth.ino b/examples/Ethernet/MQTTClient_Auth/MQTTClient_Auth.ino index 76a921e..5f26e86 100644 --- a/examples/Ethernet/MQTTClient_Auth/MQTTClient_Auth.ino +++ b/examples/Ethernet/MQTTClient_Auth/MQTTClient_Auth.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** MQTTClient_Auth.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -39,18 +39,18 @@ const char *subTopic = "MQTT_Sub"; // Topic to subcribe to //IPAddress mqttServer(172, 16, 0, 2); -void callback(char* topic, byte* payload, unsigned int length) +void callback(char* topic, byte* payload, unsigned int length) { - Serial.print("Message arrived ["); - Serial.print(topic); - Serial.print("] "); - - for (unsigned int i = 0; i < length; i++) - { - Serial.print((char)payload[i]); - } - - Serial.println(); + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + + for (unsigned int i = 0; i < length; i++) + { + Serial.print((char)payload[i]); + } + + Serial.println(); } EthernetClient ethClient; @@ -61,119 +61,122 @@ const char *pubData = data.c_str(); void reconnect() { - // Loop until we're reconnected - while (!client.connected()) - { - Serial.print("Attempting MQTT connection to "); - Serial.print(mqttServer); - - // Attempt to connect - if (client.connect("arduino", "try", "try")) - { - Serial.println("...connected"); - - // Once connected, publish an announcement... - client.publish(TOPIC, data.c_str()); - - //Serial.println("Published connection message successfully!"); - //Serial.print("Subcribed to: "); - //Serial.println(subTopic); - - client.subscribe(subTopic); - // for loopback testing - client.subscribe(TOPIC); - } - else - { - Serial.print("...failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - - // Wait 5 seconds before retrying - delay(5000); - } - } + // Loop until we're reconnected + while (!client.connected()) + { + Serial.print("Attempting MQTT connection to "); + Serial.print(mqttServer); + + // Attempt to connect + if (client.connect("arduino", "try", "try")) + { + Serial.println("...connected"); + + // Once connected, publish an announcement... + client.publish(TOPIC, data.c_str()); + + //Serial.println("Published connection message successfully!"); + //Serial.print("Subcribed to: "); + //Serial.println(subTopic); + + client.subscribe(subTopic); + // for loopback testing + client.subscribe(TOPIC); + } + else + { + Serial.print("...failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + + // Wait 5 seconds before retrying + delay(5000); + } + } } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart MQTTClient_Auth on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; - - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); - - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); - - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } - - Serial.print(F("Using mac index = ")); - Serial.println(index); - - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); - - /////////////////////////////////// - - // Note - the default maximum packet size is 128 bytes. If the - // combined length of clientId, username and password exceed this use the - // following to increase the buffer size: - // client.setBufferSize(255); + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart MQTTClient_Auth on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + // Note - the default maximum packet size is 128 bytes. If the + // combined length of clientId, username and password exceed this use the + // following to increase the buffer size: + // client.setBufferSize(255); } #define MQTT_PUBLISH_INTERVAL_MS 5000L unsigned long lastMsg = 0; -void loop() +void loop() { - static unsigned long now; - - if (!client.connected()) - { - reconnect(); - } - - // Sending Data - now = millis(); - - if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) - { - lastMsg = now; - - if (!client.publish(TOPIC, pubData)) - { - Serial.println("Message failed to send."); - } - - Serial.print("Message Send : " + String(TOPIC) + " => "); - Serial.println(data); - } - - client.loop(); + static unsigned long now; + + if (!client.connected()) + { + reconnect(); + } + + // Sending Data + now = millis(); + + if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) + { + lastMsg = now; + + if (!client.publish(TOPIC, pubData)) + { + Serial.println("Message failed to send."); + } + + Serial.print("Message Send : " + String(TOPIC) + " => "); + Serial.println(data); + } + + client.loop(); } diff --git a/examples/Ethernet/MQTTClient_Auth/defines.h b/examples/Ethernet/MQTTClient_Auth/defines.h index 4baffb2..865ba7d 100644 --- a/examples/Ethernet/MQTTClient_Auth/defines.h +++ b/examples/Ethernet/MQTTClient_Auth/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -16,7 +16,7 @@ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -34,26 +34,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); diff --git a/examples/Ethernet/MQTTClient_Basic/MQTTClient_Basic.ino b/examples/Ethernet/MQTTClient_Basic/MQTTClient_Basic.ino index 90c7535..020a8df 100644 --- a/examples/Ethernet/MQTTClient_Basic/MQTTClient_Basic.ino +++ b/examples/Ethernet/MQTTClient_Basic/MQTTClient_Basic.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** MQTTClient_Basic.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -18,7 +18,7 @@ - publishes "hello world" to the topic "outTopic" - subscribes to the topic "inTopic", printing out any messages it receives. NB - it assumes the received payloads are strings not binary - + It will reconnect to the server if the connection is lost using a blocking reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to achieve the same result without blocking the main loop. @@ -38,18 +38,18 @@ const char *ID = "MQTTClient_SSL-Client"; // Name of our device, must be const char *TOPIC = "MQTT_Pub"; // Topic to subcribe to const char *subTopic = "MQTT_Sub"; // Topic to subcribe to -void callback(char* topic, byte* payload, unsigned int length) +void callback(char* topic, byte* payload, unsigned int length) { - Serial.print("Message arrived ["); - Serial.print(topic); - Serial.print("] "); - - for (unsigned int i = 0; i < length; i++) - { - Serial.print((char)payload[i]); - } - - Serial.println(); + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + + for (unsigned int i = 0; i < length; i++) + { + Serial.print((char)payload[i]); + } + + Serial.println(); } EthernetClient ethClient; @@ -60,120 +60,123 @@ const char *pubData = data.c_str(); void reconnect() { - // Loop until we're reconnected - while (!client.connected()) - { - Serial.print("Attempting MQTT connection to "); - Serial.print(mqttServer); - - // Attempt to connect - if (client.connect(ID, "try", "try")) - { - Serial.println("...connected"); - - // Once connected, publish an announcement... - client.publish(TOPIC, data.c_str()); - - //Serial.println("Published connection message successfully!"); - //Serial.print("Subcribed to: "); - //Serial.println(subTopic); - - client.subscribe(subTopic); - // for loopback testing - client.subscribe(TOPIC); - } - else - { - Serial.print("...failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - - // Wait 5 seconds before retrying - delay(5000); - } - } + // Loop until we're reconnected + while (!client.connected()) + { + Serial.print("Attempting MQTT connection to "); + Serial.print(mqttServer); + + // Attempt to connect + if (client.connect(ID, "try", "try")) + { + Serial.println("...connected"); + + // Once connected, publish an announcement... + client.publish(TOPIC, data.c_str()); + + //Serial.println("Published connection message successfully!"); + //Serial.print("Subcribed to: "); + //Serial.println(subTopic); + + client.subscribe(subTopic); + // for loopback testing + client.subscribe(TOPIC); + } + else + { + Serial.print("...failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + + // Wait 5 seconds before retrying + delay(5000); + } + } } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart MQTTClient_Basic on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; - - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); - - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); - - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } - - Serial.print(F("Using mac index = ")); - Serial.println(index); - - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); - - /////////////////////////////////// - - client.setServer(mqttServer, 1883); - client.setCallback(callback); - - // Allow the hardware to sort itself out - delay(1500); + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart MQTTClient_Basic on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + client.setServer(mqttServer, 1883); + client.setCallback(callback); + + // Allow the hardware to sort itself out + delay(1500); } #define MQTT_PUBLISH_INTERVAL_MS 5000L unsigned long lastMsg = 0; -void loop() +void loop() { - static unsigned long now; - - if (!client.connected()) - { - reconnect(); - } - - // Sending Data - now = millis(); - - if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) - { - lastMsg = now; - - if (!client.publish(TOPIC, pubData)) - { - Serial.println("Message failed to send."); - } - - Serial.print("Message Send : " + String(TOPIC) + " => "); - Serial.println(data); - } - - client.loop(); + static unsigned long now; + + if (!client.connected()) + { + reconnect(); + } + + // Sending Data + now = millis(); + + if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) + { + lastMsg = now; + + if (!client.publish(TOPIC, pubData)) + { + Serial.println("Message failed to send."); + } + + Serial.print("Message Send : " + String(TOPIC) + " => "); + Serial.println(data); + } + + client.loop(); } diff --git a/examples/Ethernet/MQTTClient_Basic/defines.h b/examples/Ethernet/MQTTClient_Basic/defines.h index 4baffb2..865ba7d 100644 --- a/examples/Ethernet/MQTTClient_Basic/defines.h +++ b/examples/Ethernet/MQTTClient_Basic/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -16,7 +16,7 @@ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -34,26 +34,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); diff --git a/examples/Ethernet/MQTT_ThingStream/MQTT_ThingStream.ino b/examples/Ethernet/MQTT_ThingStream/MQTT_ThingStream.ino index 8bfe964..4625585 100644 --- a/examples/Ethernet/MQTT_ThingStream/MQTT_ThingStream.ino +++ b/examples/Ethernet/MQTT_ThingStream/MQTT_ThingStream.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** MQTT_ThingStream.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -41,28 +41,28 @@ const char my_key[] = "FIXME"; #if USING_THINGSTREAM_IO -const char *MQTT_PREFIX_TOPIC = "esp32-sniffer/"; -const char *MQTT_ANNOUNCE_TOPIC = "/status"; -const char *MQTT_CONTROL_TOPIC = "/control"; -const char *MQTT_BLE_TOPIC = "/ble"; + const char *MQTT_PREFIX_TOPIC = "esp32-sniffer/"; + const char *MQTT_ANNOUNCE_TOPIC = "/status"; + const char *MQTT_CONTROL_TOPIC = "/control"; + const char *MQTT_BLE_TOPIC = "/ble"; -// GOT FROM ThingsStream! -const char *MQTT_SERVER = "mqtt.thingstream.io"; -const char *MQTT_USER = "MQTT_USER"; -const char *MQTT_PASS = "MQTT_PASS"; -const char *MQTT_CLIENT_ID = "MQTT_CLIENT_ID"; + // GOT FROM ThingsStream! + const char *MQTT_SERVER = "mqtt.thingstream.io"; + const char *MQTT_USER = "MQTT_USER"; + const char *MQTT_PASS = "MQTT_PASS"; + const char *MQTT_CLIENT_ID = "MQTT_CLIENT_ID"; -String topic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; -String subTopic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; + String topic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; + String subTopic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; #else -const char* MQTT_SERVER = "broker.emqx.io"; // Broker address + const char* MQTT_SERVER = "broker.emqx.io"; // Broker address -const char* ID = "MQTT_ThingStream"; // Name of our device, must be unique -String topic = "STM32_Pub"; // Topic to subcribe to -String subTopic = "STM32_Sub"; // Topic to subcribe to + const char* ID = "MQTT_ThingStream"; // Name of our device, must be unique + String topic = "STM32_Pub"; // Topic to subcribe to + String subTopic = "STM32_Sub"; // Topic to subcribe to #endif @@ -86,150 +86,153 @@ const char *pubData = data.c_str(); /* Called whenever a payload is received from a subscribed MQTT topic */ -void mqtt_receive_callback(char* topic, byte* payload, unsigned int length) +void mqtt_receive_callback(char* topic, byte* payload, unsigned int length) { - Serial.print("MQTT Message receive ["); - Serial.print(topic); - Serial.print("] "); - - for (unsigned int i = 0; i < length; i++) - { - Serial.print((char)payload[i]); - } - - Serial.println(); + Serial.print("MQTT Message receive ["); + Serial.print(topic); + Serial.print("] "); + + for (unsigned int i = 0; i < length; i++) + { + Serial.print((char)payload[i]); + } + + Serial.println(); } -void reconnect() +void reconnect() { - // Loop until we're reconnected - while (!client.connected()) - { - Serial.print("Attempting MQTT connection to "); - Serial.println(MQTT_SERVER); + // Loop until we're reconnected + while (!client.connected()) + { + Serial.print("Attempting MQTT connection to "); + Serial.println(MQTT_SERVER); - // Attempt to connect + // Attempt to connect #if USING_THINGSTREAM_IO - int connect_status = client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, topic.c_str(), 2, false, ""); + int connect_status = client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, topic.c_str(), 2, false, ""); #else - int connect_status = client.connect(ID); + int connect_status = client.connect(ID); #endif - if (connect_status) - { - Serial.println("...connected"); - - // Once connected, publish an announcement... - client.publish(topic.c_str(), data.c_str()); - - Serial.println("Published connection message successfully!"); - - Serial.print("Subcribed to: "); - Serial.println(subTopic); - - // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 - //ethClientSSL.flush(); - // ... and resubscribe - client.subscribe(subTopic.c_str()); - // for loopback testing - client.subscribe(topic.c_str()); - // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 - //ethClientSSL.flush(); - } - else - { - Serial.print("failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - - // Wait 5 seconds before retrying - delay(5000); - } - } + if (connect_status) + { + Serial.println("...connected"); + + // Once connected, publish an announcement... + client.publish(topic.c_str(), data.c_str()); + + Serial.println("Published connection message successfully!"); + + Serial.print("Subcribed to: "); + Serial.println(subTopic); + + // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 + //ethClientSSL.flush(); + // ... and resubscribe + client.subscribe(subTopic.c_str()); + // for loopback testing + client.subscribe(topic.c_str()); + // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 + //ethClientSSL.flush(); + } + else + { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + + // Wait 5 seconds before retrying + delay(5000); + } + } } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart MQTT_ThingStream on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; - - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); - - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); - - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } - - Serial.print(F("Using mac index = ")); - Serial.println(index); - - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); - - /////////////////////////////////// - - // Note - the default maximum packet size is 256 bytes. If the - // combined length of clientId, username and password exceed this use the - // following to increase the buffer size: - //client.setBufferSize(256); - - Serial.println("***************************************"); - Serial.println(topic); - Serial.println("***************************************"); + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart MQTT_ThingStream on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + // Note - the default maximum packet size is 256 bytes. If the + // combined length of clientId, username and password exceed this use the + // following to increase the buffer size: + //client.setBufferSize(256); + + Serial.println("***************************************"); + Serial.println(topic); + Serial.println("***************************************"); } #define MQTT_PUBLISH_INTERVAL_MS 5000L -void loop() +void loop() { - static unsigned long now; - - if (!client.connected()) - { - reconnect(); - } - - // Sending Data - now = millis(); - - if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) - { - lastMsg = now; - - if (!client.publish(topic.c_str(), pubData)) - { - Serial.println("Message failed to send."); - } - - Serial.print("MQTT Message Send : " + topic + " => "); - Serial.println(data); - } - - client.loop(); + static unsigned long now; + + if (!client.connected()) + { + reconnect(); + } + + // Sending Data + now = millis(); + + if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) + { + lastMsg = now; + + if (!client.publish(topic.c_str(), pubData)) + { + Serial.println("Message failed to send."); + } + + Serial.print("MQTT Message Send : " + topic + " => "); + Serial.println(data); + } + + client.loop(); } diff --git a/examples/Ethernet/MQTT_ThingStream/defines.h b/examples/Ethernet/MQTT_ThingStream/defines.h index b44a787..b9a52b2 100644 --- a/examples/Ethernet/MQTT_ThingStream/defines.h +++ b/examples/Ethernet/MQTT_ThingStream/defines.h @@ -1,12 +1,12 @@ /**************************************************************************************************************************** defines.h - + Dead simple AsyncWebServer for STM32 LAN8720 or built-in LAN8742A Ethernet - + For STM32 with LAN8720 (STM32F4/F7) or built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc) - + AsyncWebServer_STM32 is a library for the STM32 with LAN8720 or built-in LAN8742A Ethernet WebServer - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_STM32 Licensed under GPLv3 license @@ -18,7 +18,7 @@ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -36,26 +36,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); diff --git a/examples/Ethernet/WebClient/WebClient.ino b/examples/Ethernet/WebClient/WebClient.ino index c976b1b..497afb1 100644 --- a/examples/Ethernet/WebClient/WebClient.ino +++ b/examples/Ethernet/WebClient/WebClient.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** WebClient.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -20,87 +20,90 @@ EthernetClient client; void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart WebClient on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; - - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); - - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); - - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } - - Serial.print(F("Using mac index = ")); - Serial.println(index); - - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); - - /////////////////////////////////// - - Serial.println(); - Serial.println(F("Starting connection to server...")); - - // if you get a connection, report back via serial - if (client.connect(server, 80)) - { - Serial.println(F("Connected to server")); - // Make a HTTP request - client.println(F("GET /asciilogo.txt HTTP/1.1")); - client.println(F("Host: arduino.cc")); - client.println(F("Connection: close")); - client.println(); - } + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart WebClient on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// + + Serial.println(); + Serial.println(F("Starting connection to server...")); + + // if you get a connection, report back via serial + if (client.connect(server, 80)) + { + Serial.println(F("Connected to server")); + // Make a HTTP request + client.println(F("GET /asciilogo.txt HTTP/1.1")); + client.println(F("Host: arduino.cc")); + client.println(F("Connection: close")); + client.println(); + } } void printoutData(void) { - // if there are incoming bytes available - // from the server, read them and print them - while (client.available()) - { - char c = client.read(); - Serial.write(c); - } + // if there are incoming bytes available + // from the server, read them and print them + while (client.available()) + { + char c = client.read(); + Serial.write(c); + } } void loop() { - printoutData(); - - // if the server's disconnected, stop the client - if (!client.connected()) - { - Serial.println(); - Serial.println(F("Disconnecting from server...")); - client.stop(); - - // do nothing forevermore - while (true); - } + printoutData(); + + // if the server's disconnected, stop the client + if (!client.connected()) + { + Serial.println(); + Serial.println(F("Disconnecting from server...")); + client.stop(); + + // do nothing forevermore + while (true); + } } diff --git a/examples/Ethernet/WebClient/defines.h b/examples/Ethernet/WebClient/defines.h index 95c153f..6fec2e0 100644 --- a/examples/Ethernet/WebClient/defines.h +++ b/examples/Ethernet/WebClient/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -15,7 +15,7 @@ #define defines_h #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -33,26 +33,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); diff --git a/examples/Ethernet/WebClientRepeating/WebClientRepeating.ino b/examples/Ethernet/WebClientRepeating/WebClientRepeating.ino index c8573a5..d55a709 100644 --- a/examples/Ethernet/WebClientRepeating/WebClientRepeating.ino +++ b/examples/Ethernet/WebClientRepeating/WebClientRepeating.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** WebClientRepeating.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -23,93 +23,96 @@ EthernetClient client; // this method makes a HTTP connection to the server void httpRequest() { - Serial.println(); - - // close any connection before send a new request - // this will free the socket on the WiFi shield - client.stop(); - - // if there's a successful connection - if (client.connect(server, 80)) - { - Serial.println(F("Connecting...")); - - // send the HTTP PUT request - client.println(F("GET /asciilogo.txt HTTP/1.1")); - client.println(F("Host: arduino.cc")); - client.println(F("Connection: close")); - client.println(); - - // note the time that the connection was made - lastConnectionTime = millis(); - } - else - { - // if you couldn't make a connection - Serial.println(F("Connection failed")); - } + Serial.println(); + + // close any connection before send a new request + // this will free the socket on the WiFi shield + client.stop(); + + // if there's a successful connection + if (client.connect(server, 80)) + { + Serial.println(F("Connecting...")); + + // send the HTTP PUT request + client.println(F("GET /asciilogo.txt HTTP/1.1")); + client.println(F("Host: arduino.cc")); + client.println(F("Connection: close")); + client.println(); + + // note the time that the connection was made + lastConnectionTime = millis(); + } + else + { + // if you couldn't make a connection + Serial.println(F("Connection failed")); + } } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart WebClientRepeating on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // start the ethernet connection and the server - // Use random mac - uint16_t index = millis() % NUMBER_OF_MAC; - - // Use Static IP - //Ethernet.begin(mac[index], ip); - // Use DHCP dynamic IP and random mac - Ethernet.begin(mac[index]); - - if (Ethernet.hardwareStatus() == EthernetNoHardware) - { - Serial.println("No Ethernet found. Stay here forever"); - - while (true) - { - delay(1); // do nothing, no point running without Ethernet hardware - } - } - - if (Ethernet.linkStatus() == LinkOFF) - { - Serial.println("Not connected Ethernet cable"); - } - - Serial.print(F("Using mac index = ")); - Serial.println(index); - - Serial.print(F("Connected! IP address: ")); - Serial.println(Ethernet.localIP()); - - /////////////////////////////////// + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart WebClientRepeating on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // start the ethernet connection and the server + // Use random mac + uint16_t index = millis() % NUMBER_OF_MAC; + + // Use Static IP + //Ethernet.begin(mac[index], ip); + // Use DHCP dynamic IP and random mac + Ethernet.begin(mac[index]); + + if (Ethernet.hardwareStatus() == EthernetNoHardware) + { + Serial.println("No Ethernet found. Stay here forever"); + + while (true) + { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + + if (Ethernet.linkStatus() == LinkOFF) + { + Serial.println("Not connected Ethernet cable"); + } + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + + /////////////////////////////////// } void loop() { - // if there's incoming data from the net connection send it out the serial port - // this is for debugging purposes only - while (client.available()) - { - char c = client.read(); - Serial.write(c); - } - - // if 10 seconds have passed since your last connection, - // then connect again and send data - if (millis() - lastConnectionTime > postingInterval) - { - httpRequest(); - } + // if there's incoming data from the net connection send it out the serial port + // this is for debugging purposes only + while (client.available()) + { + char c = client.read(); + Serial.write(c); + } + + // if 10 seconds have passed since your last connection, + // then connect again and send data + if (millis() - lastConnectionTime > postingInterval) + { + httpRequest(); + } } diff --git a/examples/Ethernet/WebClientRepeating/defines.h b/examples/Ethernet/WebClientRepeating/defines.h index 11d76ca..8f8739d 100644 --- a/examples/Ethernet/WebClientRepeating/defines.h +++ b/examples/Ethernet/WebClientRepeating/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -16,7 +16,7 @@ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -34,26 +34,26 @@ byte mac[][NUMBER_OF_MAC] = { - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, - { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 }, }; // Select the IP address according to your local network IPAddress ip(192, 168, 2, 232); diff --git a/examples/WiFi/AsyncWebServer_SendChunked/AsyncWebServer_SendChunked.ino b/examples/WiFi/AsyncWebServer_SendChunked/AsyncWebServer_SendChunked.ino new file mode 100644 index 0000000..c5ce4a1 --- /dev/null +++ b/examples/WiFi/AsyncWebServer_SendChunked/AsyncWebServer_SendChunked.ino @@ -0,0 +1,259 @@ +/**************************************************************************************************************************** + AsyncWebServer_SendChunked.ino + + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi + + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi + + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) + Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer + Licensed under GPLv3 license + *****************************************************************************************************************************/ + +#if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) + #error For Portenta_H7 only +#endif + +#define _PORTENTA_H7_ATCP_LOGLEVEL_ 1 +#define _PORTENTA_H7_AWS_LOGLEVEL_ 4 + +#define USE_WIFI_PORTENTA_H7 true + +#include +#warning Using WiFi for Portenta_H7. + +#include + +int status = WL_IDLE_STATUS; + +// In bytes +#define STRING_SIZE 50000 + +AsyncWebServer server(80); + +char ssid[] = "your_ssid"; // your network SSID (name) +char pass[] = "12345678"; // your network password (use for WPA, or use as key for WEP), length must be 8+ + +int reqCount = 0; // number of requests received + +#define LED_OFF HIGH +#define LED_ON LOW + +#define BUFFER_SIZE 512 +char temp[BUFFER_SIZE]; + +void createPage(String &pageInput) +{ + digitalWrite(LED_BUILTIN, LED_ON); + + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; + + snprintf(temp, BUFFER_SIZE - 1, + "\ +\ +\ +AsyncWebServer-%s\ +\ +\ +\ +

AsyncWebServer_SendChunked_Portenta_H7!

\ +

running WiFi on %s

\ +

Uptime: %d d %02d:%02d:%02d

\ +\ +", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); + + pageInput = temp; + + digitalWrite(LED_BUILTIN, LED_OFF); +} + +void handleNotFound(AsyncWebServerRequest *request) +{ + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + + digitalWrite(LED_BUILTIN, LED_OFF); +} + +String out; + +void handleRoot(AsyncWebServerRequest *request) +{ + // clear the String to start over + out = String(); + + digitalWrite(LED_BUILTIN, LED_ON); + + createPage(out); + + out += "\r\n"; + + for (uint16_t lineIndex = 0; lineIndex < 500; lineIndex++) + { + out += ""; + } + + out += "
INDEXDATA
"; + out += String(lineIndex); + out += ""; + out += "Portenta_H7_AsyncWebServer_SendChunked_ABCDEFGHIJKLMNOPQRSTUVWXYZ
\r\n"; + + AWS_LOGDEBUG1("Total length to send in chunks =", out.length()); + + AsyncWebServerResponse *response = request->beginChunkedResponse("text/html", [](uint8_t *buffer, size_t maxLen, size_t filledLength) -> size_t + { + size_t len = min(maxLen, out.length() - filledLength); + memcpy(buffer, out.c_str() + filledLength, len); + + AWS_LOGDEBUG1("Bytes sent in chunk =", len); + + return len; + }); + + request->send(response); + + digitalWrite(LED_BUILTIN, LED_OFF); +} + +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("Local 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"); +} + +void setup() +{ + out.reserve(STRING_SIZE); + + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart AsyncWebServer_SendChunked on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); + + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + + Serial.print(F("AsyncWebServer is @ IP : ")); + Serial.println(WiFi.localIP()); +} + +void heartBeatPrint() +{ + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } +} + +void check_status() +{ + static unsigned long checkstatus_timeout = 0; + +#define STATUS_CHECK_INTERVAL 10000L + + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } +} + +void loop() +{ + check_status(); +} diff --git a/examples/WiFi/Async_AdvancedWebServer/Async_AdvancedWebServer.ino b/examples/WiFi/Async_AdvancedWebServer/Async_AdvancedWebServer.ino index 348c367..4dc2016 100644 --- a/examples/WiFi/Async_AdvancedWebServer/Async_AdvancedWebServer.ino +++ b/examples/WiFi/Async_AdvancedWebServer/Async_AdvancedWebServer.ino @@ -2,7 +2,7 @@ Async_AdvancedWebServer.ino - Dead simple AsyncWebServer for Portenta_H7 For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) @@ -39,7 +39,7 @@ *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -69,15 +69,15 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); - int sec = millis() / 1000; - int min = sec / 60; - int hr = min / 60; - int day = hr / 24; + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; - snprintf(temp, BUFFER_SIZE - 1, - "\ + snprintf(temp, BUFFER_SIZE - 1, + "\ \ \ AsyncWebServer-%s\ @@ -93,176 +93,181 @@ body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Col \ ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); - request->send(200, "text/html", temp); + request->send(200, "text/html", temp); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - String message = "File Not Found\n\n"; - - message += "URI: "; - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } void drawGraph(AsyncWebServerRequest *request) { - String out; - - out.reserve(4000); - char temp[70]; - - out += "\n"; - out += "\n"; - out += "\n"; - int y = rand() % 130; - - for (int x = 10; x < 300; x += 10) - { - int y2 = rand() % 130; - sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); - out += temp; - y = y2; - } - out += "\n\n"; - - request->send(200, "image/svg+xml", out); + String out; + + out.reserve(4000); + char temp[70]; + + out += "\n"; + out += "\n"; + out += "\n"; + int y = rand() % 130; + + for (int x = 10; x < 300; x += 10) + { + int y2 = rand() % 130; + sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); + out += temp; + y = y2; + } + + out += "\n\n"; + + request->send(200, "image/svg+xml", out); } 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("Local 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"); + // 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("Local 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"); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_AdvancedWebServer on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// - Serial.begin(115200); - while (!Serial && millis() < 5000); + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); - delay(200); + // don't continue + while (true); + } - Serial.print("\nStart Async_AdvancedWebServer on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); - /////////////////////////////////// + status = WiFi.begin(ssid, pass); - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } + delay(1000); - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); - status = WiFi.begin(ssid, pass); + // Connect to WPA/WPA2 network + status = WiFi.status(); + } - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } + printWifiStatus(); - printWifiStatus(); + /////////////////////////////////// - /////////////////////////////////// + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); + server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) + { + drawGraph(request); + }); - server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) - { - drawGraph(request); - }); + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); + server.onNotFound(handleNotFound); - server.onNotFound(handleNotFound); + server.begin(); - server.begin(); - - Serial.print(F("HTTP EthernetWebServer is @ IP : ")); - Serial.println(WiFi.localIP()); + Serial.print(F("HTTP EthernetWebServer is @ IP : ")); + Serial.println(WiFi.localIP()); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/WiFi/Async_AdvancedWebServer_MemoryIssues_Send_CString/Async_AdvancedWebServer_MemoryIssues_Send_CString.ino b/examples/WiFi/Async_AdvancedWebServer_MemoryIssues_Send_CString/Async_AdvancedWebServer_MemoryIssues_Send_CString.ino index cd2347b..6e70def 100644 --- a/examples/WiFi/Async_AdvancedWebServer_MemoryIssues_Send_CString/Async_AdvancedWebServer_MemoryIssues_Send_CString.ino +++ b/examples/WiFi/Async_AdvancedWebServer_MemoryIssues_Send_CString/Async_AdvancedWebServer_MemoryIssues_Send_CString.ino @@ -2,7 +2,7 @@ Async_AdvancedWebServer_MemoryIssues_Send_CString.ino - Dead simple AsyncWebServer for Portenta_H7 For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) @@ -39,7 +39,7 @@ *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_ATCP_LOGLEVEL_ 1 @@ -66,7 +66,7 @@ char *cStr; #define USING_CSTRING_IN_SDRAM true #if USING_CSTRING_IN_SDRAM - #include "SDRAM.h" + #include "SDRAM.h" #endif AsyncWebServer server(80); @@ -81,15 +81,15 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); - int sec = millis() / 1000; - int min = sec / 60; - int hr = min / 60; - int day = hr / 24; + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; - snprintf(temp, BUFFER_SIZE - 1, - "\ + snprintf(temp, BUFFER_SIZE - 1, + "\ \ \ AsyncWebServer-%s\ @@ -105,240 +105,243 @@ body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Col \ ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); - request->send(200, "text/html", temp); + request->send(200, "text/html", temp); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - String message = "File Not Found\n\n"; - - message += "URI: "; - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } void PrintHeapData(String hIn) { - static mbed_stats_heap_t heap_stats; - static uint32_t maxHeapSize = 0; - - mbed_stats_heap_get(&heap_stats); - - // Print and update only when different - if (maxHeapSize != heap_stats.max_size) - { - maxHeapSize = heap_stats.max_size; - - Serial.print("\nHEAP DATA - "); - Serial.print(hIn); - - Serial.print(" Cur heap: "); - Serial.print(heap_stats.current_size); - Serial.print(" Res Size: "); - Serial.print(heap_stats.reserved_size); - Serial.print(" Max heap: "); - Serial.println(heap_stats.max_size); - } + static mbed_stats_heap_t heap_stats; + static uint32_t maxHeapSize = 0; + + mbed_stats_heap_get(&heap_stats); + + // Print and update only when different + if (maxHeapSize != heap_stats.max_size) + { + maxHeapSize = heap_stats.max_size; + + Serial.print("\nHEAP DATA - "); + Serial.print(hIn); + + Serial.print(" Cur heap: "); + Serial.print(heap_stats.current_size); + Serial.print(" Res Size: "); + Serial.print(heap_stats.reserved_size); + Serial.print(" Max heap: "); + Serial.println(heap_stats.max_size); + } } void PrintStringSize(const char* cStr) -{ - Serial.print("\nOut String Length="); - Serial.println(strlen(cStr)); +{ + Serial.print("\nOut String Length="); + Serial.println(strlen(cStr)); } -void drawGraph(AsyncWebServerRequest *request) +void drawGraph(AsyncWebServerRequest *request) { - char temp[80]; + char temp[80]; + + cStr[0] = '\0'; - cStr[0] = '\0'; + strcat(cStr, "\n"); + strcat(cStr, "\n"); + strcat(cStr, "\n"); + int y = rand() % 130; - strcat(cStr, "\n"); - strcat(cStr, "\n"); - strcat(cStr, "\n"); - int y = rand() % 130; + for (int x = 10; x < 5000; x += 10) + { + int y2 = rand() % 130; + sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); + strcat(cStr, temp); + y = y2; + } - for (int x = 10; x < 5000; x += 10) - { - int y2 = rand() % 130; - sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); - strcat(cStr, temp); - y = y2; - } - - strcat(cStr, "\n\n"); + strcat(cStr, "\n\n"); - PrintHeapData("Pre Send"); + PrintHeapData("Pre Send"); - // Print only when cStr length too large and corrupting memory - if ( (strlen(cStr) >= CSTRING_SIZE)) - { - PrintStringSize(cStr); - } + // Print only when cStr length too large and corrupting memory + if ( (strlen(cStr) >= CSTRING_SIZE)) + { + PrintStringSize(cStr); + } - request->send(200, "image/svg+xml", cStr, false); + request->send(200, "image/svg+xml", cStr, false); - PrintHeapData("Post Send"); + PrintHeapData("Post Send"); } 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("Local 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"); + // 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("Local 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"); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); - Serial.begin(115200); - while (!Serial && millis() < 5000); + Serial.begin(115200); - delay(200); + while (!Serial && millis() < 5000); + + delay(200); #if USING_CSTRING_IN_SDRAM - Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString using SDRAM on "); + Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString using SDRAM on "); #else - Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString on "); + Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString on "); #endif - - Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); #if USING_CSTRING_IN_SDRAM - SDRAM.begin(); + SDRAM.begin(); - cStr = (char *) SDRAM.malloc(CSTRING_SIZE); // make a little larger than required + cStr = (char *) SDRAM.malloc(CSTRING_SIZE); // make a little larger than required #else - cStr = (char *) malloc(CSTRING_SIZE); // make a little larger than required + cStr = (char *) malloc(CSTRING_SIZE); // make a little larger than required #endif - if (cStr == NULL) - { - Serial.println("Unable top Allocate RAM"); - - for(;;); - } + if (cStr == NULL) + { + Serial.println("Unable top Allocate RAM"); + + for (;;); + } + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); - /////////////////////////////////// + status = WiFi.begin(ssid, pass); - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } + delay(1000); - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); - status = WiFi.begin(ssid, pass); + // Connect to WPA/WPA2 network + status = WiFi.status(); + } - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } + printWifiStatus(); - printWifiStatus(); + /////////////////////////////////// - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); - server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) - { - drawGraph(request); - }); + server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) + { + drawGraph(request); + }); - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); - server.onNotFound(handleNotFound); + server.onNotFound(handleNotFound); - server.begin(); + server.begin(); - Serial.print(F("HTTP EthernetWebServer is @ IP : ")); - Serial.println(WiFi.localIP()); + Serial.print(F("HTTP EthernetWebServer is @ IP : ")); + Serial.println(WiFi.localIP()); - PrintHeapData("Pre Create Arduino String"); + PrintHeapData("Pre Create Arduino String"); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - //Serial.println(); - PrintStringSize(cStr); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + //Serial.println(); + PrintStringSize(cStr); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/WiFi/Async_AdvancedWebServer_SendChunked/Async_AdvancedWebServer_SendChunked.ino b/examples/WiFi/Async_AdvancedWebServer_SendChunked/Async_AdvancedWebServer_SendChunked.ino new file mode 100644 index 0000000..c28fbe9 --- /dev/null +++ b/examples/WiFi/Async_AdvancedWebServer_SendChunked/Async_AdvancedWebServer_SendChunked.ino @@ -0,0 +1,293 @@ +/**************************************************************************************************************************** + Async_AdvancedWebServer_SendChunked.ino + + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi + + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi + + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) + Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer + Licensed under GPLv3 license + + Copyright (c) 2015, Majenko Technologies + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + Neither the name of Majenko Technologies nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************************************************************/ + +#if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) + #error For Portenta_H7 only +#endif + +#define _PORTENTA_H7_ATCP_LOGLEVEL_ 1 +#define _PORTENTA_H7_AWS_LOGLEVEL_ 4 + +#define USE_WIFI_PORTENTA_H7 true + +#include +#warning Using WiFi for Portenta_H7. + +#include + +int status = WL_IDLE_STATUS; + +// In bytes +#define STRING_SIZE 40000 + +AsyncWebServer server(80); + +char ssid[] = "your_ssid"; // your network SSID (name) +char pass[] = "12345678"; // your network password (use for WPA, or use as key for WEP), length must be 8+ + +int reqCount = 0; // number of requests received + +#define LED_OFF HIGH +#define LED_ON LOW + +#define BUFFER_SIZE 512 +char temp[BUFFER_SIZE]; + +void handleRoot(AsyncWebServerRequest *request) +{ + digitalWrite(LED_BUILTIN, LED_ON); + + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + int day = hr / 24; + + snprintf(temp, BUFFER_SIZE - 1, + "\ +\ +\ +AsyncWebServer-%s\ +\ +\ +\ +

AsyncWebServer_SendChunked_Portenta_H7!

\ +

running WiFi on %s

\ +

Uptime: %d d %02d:%02d:%02d

\ +\ +\ +", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); + + request->send(200, "text/html", temp); + + digitalWrite(LED_BUILTIN, LED_OFF); +} + +void handleNotFound(AsyncWebServerRequest *request) +{ + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); +} + +String out; + +void drawGraph(AsyncWebServerRequest *request) +{ + //out.reserve(STRING_SIZE); + char temp[70]; + + digitalWrite(LED_BUILTIN, LED_ON); + + out = "\n"; + out += "\n"; + out += "\n"; + int y = rand() % 130; + + for (int x = 10; x < 5000; x += 10) + { + int y2 = rand() % 130; + sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); + out += temp; + y = y2; + } + + out += "\n\n"; + + AWS_LOGDEBUG1("Total length to send in chunks =", out.length()); + + AsyncWebServerResponse *response = request->beginChunkedResponse("image/svg+xml", [](uint8_t *buffer, size_t maxLen, size_t filledLength) -> size_t + { + size_t len = min(maxLen, out.length() - filledLength); + memcpy(buffer, out.c_str() + filledLength, len); + + AWS_LOGDEBUG1("Bytes sent in chunk =", len); + + return len; + }); + + request->send(response); + + digitalWrite(LED_BUILTIN, LED_OFF); +} + +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("Local 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"); +} + +void setup() +{ + out.reserve(STRING_SIZE); + + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_AdvancedWebServer_SendChunked on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); + + server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) + { + drawGraph(request); + }); + + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + + Serial.print(F("AsyncWebServer is @ IP : ")); + Serial.println(WiFi.localIP()); +} + +void heartBeatPrint() +{ + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } +} + +void check_status() +{ + static unsigned long checkstatus_timeout = 0; + +#define STATUS_CHECK_INTERVAL 10000L + + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } +} + +void loop() +{ + check_status(); +} diff --git a/examples/WiFi/Async_HelloServer/Async_HelloServer.ino b/examples/WiFi/Async_HelloServer/Async_HelloServer.ino index 34d46bc..da3c4ad 100644 --- a/examples/WiFi/Async_HelloServer/Async_HelloServer.ino +++ b/examples/WiFi/Async_HelloServer/Async_HelloServer.ino @@ -1,17 +1,17 @@ /**************************************************************************************************************************** Async_HelloServer.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define USE_WIFI_PORTENTA_H7 true @@ -36,152 +36,156 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); - snprintf(temp, BUFFER_SIZE - 1, "Hello from Async_HelloServer on %s\n", BOARD_NAME); + snprintf(temp, BUFFER_SIZE - 1, "Hello from Async_HelloServer on %s\n", BOARD_NAME); - request->send(200, "text/plain", temp); - - digitalWrite(LED_BUILTIN, LED_OFF); + request->send(200, "text/plain", temp); + + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - - String message = "File Not Found\n\n"; - - message += "URI: "; - //message += server.uri(); - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + + String message = "File Not Found\n\n"; + + message += "URI: "; + //message += server.uri(); + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } 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("Local 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"); + // 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("Local 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"); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); - - Serial.begin(115200); - while (!Serial && millis() < 5000); - - delay(200); - - Serial.print("\nStart Async_HelloServer on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); - - status = WiFi.begin(ssid, pass); - - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } - - printWifiStatus(); - - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); - - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); - - server.onNotFound(handleNotFound); - - server.begin(); - - Serial.print(F("HTTP EthernetWebServer is @ IP : ")); - Serial.println(WiFi.localIP()); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_HelloServer on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); + + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + + Serial.print(F("HTTP EthernetWebServer is @ IP : ")); + Serial.println(WiFi.localIP()); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/WiFi/Async_HelloServer2/Async_HelloServer2.ino b/examples/WiFi/Async_HelloServer2/Async_HelloServer2.ino index 0897e89..0446afd 100644 --- a/examples/WiFi/Async_HelloServer2/Async_HelloServer2.ino +++ b/examples/WiFi/Async_HelloServer2/Async_HelloServer2.ino @@ -1,17 +1,17 @@ /**************************************************************************************************************************** Async_HelloServer.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define USE_WIFI_PORTENTA_H7 true @@ -36,173 +36,177 @@ char temp[BUFFER_SIZE]; void handleRoot(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); + digitalWrite(LED_BUILTIN, LED_ON); + + snprintf(temp, BUFFER_SIZE - 1, "Hello from Async_HelloServer2 on %s\n", BOARD_NAME); + request->send(200, "text/plain", temp); - snprintf(temp, BUFFER_SIZE - 1, "Hello from Async_HelloServer2 on %s\n", BOARD_NAME); - request->send(200, "text/plain", temp); - - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_OFF); } void handleNotFound(AsyncWebServerRequest *request) { - digitalWrite(LED_BUILTIN, LED_ON); - String message = "File Not Found\n\n"; - - message += "URI: "; - //message += server.uri(); - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - - request->send(404, "text/plain", message); - digitalWrite(LED_BUILTIN, LED_OFF); + digitalWrite(LED_BUILTIN, LED_ON); + String message = "File Not Found\n\n"; + + message += "URI: "; + //message += server.uri(); + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); + digitalWrite(LED_BUILTIN, LED_OFF); } 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("Local 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"); + // 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("Local 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"); } void setup() { - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, LED_OFF); - - Serial.begin(115200); - while (!Serial && millis() < 5000); - - delay(200); - - Serial.print("\nStart Async_HelloServer2 on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); - - status = WiFi.begin(ssid, pass); - - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } - - printWifiStatus(); - - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); - - server.on("/inline", [](AsyncWebServerRequest * request) - { - request->send(200, "text/plain", "This works as well"); - }); - - server.on("/gif", [](AsyncWebServerRequest * request) - { - static const uint8_t gif[] = - { - 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x01, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x19, 0x8c, 0x8f, 0xa9, 0xcb, 0x9d, - 0x00, 0x5f, 0x74, 0xb4, 0x56, 0xb0, 0xb0, 0xd2, 0xf2, 0x35, 0x1e, 0x4c, - 0x0c, 0x24, 0x5a, 0xe6, 0x89, 0xa6, 0x4d, 0x01, 0x00, 0x3b - }; - - char gif_colored[sizeof(gif)]; - - memcpy(gif_colored, gif, sizeof(gif)); - - // Set the background to a random set of colors - gif_colored[16] = millis() % 256; - gif_colored[17] = millis() % 256; - gif_colored[18] = millis() % 256; - - request->send(200, (char *) "image/gif", gif_colored); - }); - - server.onNotFound(handleNotFound); - - server.begin(); - - Serial.print("HTTP Async_HelloServer2 started @ IP : "); - Serial.println(WiFi.localIP()); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LED_OFF); + + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_HelloServer2 on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); + + server.on("/inline", [](AsyncWebServerRequest * request) + { + request->send(200, "text/plain", "This works as well"); + }); + + server.on("/gif", [](AsyncWebServerRequest * request) + { + static const uint8_t gif[] = + { + 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x01, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x19, 0x8c, 0x8f, 0xa9, 0xcb, 0x9d, + 0x00, 0x5f, 0x74, 0xb4, 0x56, 0xb0, 0xb0, 0xd2, 0xf2, 0x35, 0x1e, 0x4c, + 0x0c, 0x24, 0x5a, 0xe6, 0x89, 0xa6, 0x4d, 0x01, 0x00, 0x3b + }; + + char gif_colored[sizeof(gif)]; + + memcpy(gif_colored, gif, sizeof(gif)); + + // Set the background to a random set of colors + gif_colored[16] = millis() % 256; + gif_colored[17] = millis() % 256; + gif_colored[18] = millis() % 256; + + request->send(200, (char *) "image/gif", gif_colored); + }); + + server.onNotFound(handleNotFound); + + server.begin(); + + Serial.print("HTTP Async_HelloServer2 started @ IP : "); + Serial.println(WiFi.localIP()); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/WiFi/Async_HttpBasicAuth/Async_HttpBasicAuth.ino b/examples/WiFi/Async_HttpBasicAuth/Async_HttpBasicAuth.ino index 172300e..12f75bd 100644 --- a/examples/WiFi/Async_HttpBasicAuth/Async_HttpBasicAuth.ino +++ b/examples/WiFi/Async_HttpBasicAuth/Async_HttpBasicAuth.ino @@ -1,17 +1,17 @@ /**************************************************************************************************************************** Async_HttpBasicAuth.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define USE_WIFI_PORTENTA_H7 true @@ -33,121 +33,125 @@ const char* www_password = "portenta"; 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("Local 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"); + // 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("Local 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"); } void setup() { - Serial.begin(115200); - while (!Serial && millis() < 5000); - - delay(200); - - Serial.print("\nStart Async_HTTPBasicAuth on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); - - status = WiFi.begin(ssid, pass); - - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } - - printWifiStatus(); - - /////////////////////////////////// - - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - if (!request->authenticate(www_username, www_password)) - { - return request->requestAuthentication(); - } - - request->send(200, "text/plain", "Login OK"); - }); - - server.begin(); - - Serial.print(F("Async_HttpBasicAuth started @ IP : ")); - Serial.println(WiFi.localIP()); - - Serial.print(F("Open http://")); - Serial.print(WiFi.localIP()); - Serial.println(F("/ in your browser to see it working")); - - Serial.print(F("Login using username = ")); - Serial.print(www_username); - Serial.print(F(" and password = ")); - Serial.println(www_password); + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_HTTPBasicAuth on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + if (!request->authenticate(www_username, www_password)) + { + return request->requestAuthentication(); + } + + request->send(200, "text/plain", "Login OK"); + }); + + server.begin(); + + Serial.print(F("Async_HttpBasicAuth started @ IP : ")); + Serial.println(WiFi.localIP()); + + Serial.print(F("Open http://")); + Serial.print(WiFi.localIP()); + Serial.println(F("/ in your browser to see it working")); + + Serial.print(F("Login using username = ")); + Serial.print(www_username); + Serial.print(F(" and password = ")); + Serial.println(www_password); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/WiFi/Async_PostServer/Async_PostServer.ino b/examples/WiFi/Async_PostServer/Async_PostServer.ino index 1376a0a..3c24507 100644 --- a/examples/WiFi/Async_PostServer/Async_PostServer.ino +++ b/examples/WiFi/Async_PostServer/Async_PostServer.ino @@ -1,17 +1,17 @@ /**************************************************************************************************************************** Async_PostServer.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license *****************************************************************************************************************************/ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 @@ -54,172 +54,180 @@ body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Col void handleRoot(AsyncWebServerRequest *request) { - request->send(200, "text/html", postForms); + request->send(200, "text/html", postForms); } void handlePlain(AsyncWebServerRequest *request) { - if (request->method() != HTTP_POST) - { - request->send(405, "text/plain", "Method Not Allowed"); - } - else - { - request->send(200, "text/plain", "POST body was:\n" + request->arg("plain")); - } + if (request->method() != HTTP_POST) + { + request->send(405, "text/plain", "Method Not Allowed"); + } + else + { + request->send(200, "text/plain", "POST body was:\n" + request->arg("plain")); + } } void handleForm(AsyncWebServerRequest *request) { - if (request->method() != HTTP_POST) - { - request->send(405, "text/plain", "Method Not Allowed"); - } - else - { - String message = "POST form was:\n"; - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - request->send(200, "text/plain", message); - } + if (request->method() != HTTP_POST) + { + request->send(405, "text/plain", "Method Not Allowed"); + } + else + { + String message = "POST form was:\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(200, "text/plain", message); + } } void handleNotFound(AsyncWebServerRequest *request) { - String message = "File Not Found\n\n"; - message += "URI: "; - message += request->url(); - message += "\nMethod: "; - message += (request->method() == HTTP_GET) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - for (uint8_t i = 0; i < request->args(); i++) - { - message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; - } - request->send(404, "text/plain", message); + String message = "File Not Found\n\n"; + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += (request->method() == HTTP_GET) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for (uint8_t i = 0; i < request->args(); i++) + { + message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; + } + + request->send(404, "text/plain", message); } 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("Local 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"); + // 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("Local 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"); } void setup() { - Serial.begin(115200); - while (!Serial && millis() < 5000); + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(200); + + Serial.print("\nStart Async_PostServer on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// - delay(200); + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); - Serial.print("\nStart Async_PostServer on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + // don't continue + while (true); + } - /////////////////////////////////// + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } + status = WiFi.begin(ssid, pass); - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); + delay(1000); - status = WiFi.begin(ssid, pass); + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } + // Connect to WPA/WPA2 network + status = WiFi.status(); + } - printWifiStatus(); + printWifiStatus(); - /////////////////////////////////// + /////////////////////////////////// - server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) - { - handleRoot(request); - }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) + { + handleRoot(request); + }); - //server.on("/postplain/", handlePlain); - server.on("/postplain/", HTTP_POST, [](AsyncWebServerRequest * request) - { - handlePlain(request); - }); + //server.on("/postplain/", handlePlain); + server.on("/postplain/", HTTP_POST, [](AsyncWebServerRequest * request) + { + handlePlain(request); + }); - //server.on("/postform/", handleForm); - server.on("/postform/", HTTP_POST, [](AsyncWebServerRequest * request) - { - handleForm(request); - }); + //server.on("/postform/", handleForm); + server.on("/postform/", HTTP_POST, [](AsyncWebServerRequest * request) + { + handleForm(request); + }); - server.onNotFound(handleNotFound); + server.onNotFound(handleNotFound); - server.begin(); + server.begin(); - Serial.print(F("HTTP Async_PostServer started @ IP : ")); - Serial.println(WiFi.localIP()); + Serial.print(F("HTTP Async_PostServer started @ IP : ")); + Serial.println(WiFi.localIP()); } void heartBeatPrint() { - static int num = 1; - - Serial.print(F(".")); - - if (num == 80) - { - Serial.println(); - num = 1; - } - else if (num++ % 10 == 0) - { - Serial.print(F(" ")); - } + static int num = 1; + + Serial.print(F(".")); + + if (num == 80) + { + Serial.println(); + num = 1; + } + else if (num++ % 10 == 0) + { + Serial.print(F(" ")); + } } void check_status() { - static unsigned long checkstatus_timeout = 0; + static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L - // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. - if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) - { - heartBeatPrint(); - checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; - } + // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. + if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) + { + heartBeatPrint(); + checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; + } } void loop() { - check_status(); + check_status(); } diff --git a/examples/WiFi/MQTTClient_Auth/MQTTClient_Auth.ino b/examples/WiFi/MQTTClient_Auth/MQTTClient_Auth.ino index 938e30e..af7cab5 100644 --- a/examples/WiFi/MQTTClient_Auth/MQTTClient_Auth.ino +++ b/examples/WiFi/MQTTClient_Auth/MQTTClient_Auth.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** MQTTClient_Auth.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -39,18 +39,18 @@ const char *subTopic = "MQTT_Sub"; // Topic to subcribe to //IPAddress mqttServer(172, 16, 0, 2); -void callback(char* topic, byte* payload, unsigned int length) +void callback(char* topic, byte* payload, unsigned int length) { - Serial.print("Message arrived ["); - Serial.print(topic); - Serial.print("] "); - - for (unsigned int i = 0; i < length; i++) - { - Serial.print((char)payload[i]); - } - - Serial.println(); + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + + for (unsigned int i = 0; i < length; i++) + { + Serial.print((char)payload[i]); + } + + Serial.println(); } WiFiClient wifiClient; @@ -61,133 +61,137 @@ const char *pubData = data.c_str(); void reconnect() { - // Loop until we're reconnected - while (!client.connected()) - { - Serial.print("Attempting MQTT connection to "); - Serial.print(mqttServer); - - // Attempt to connect - if (client.connect("arduino", "try", "try")) - { - Serial.println("...connected"); - - // Once connected, publish an announcement... - client.publish(TOPIC, data.c_str()); - - //Serial.println("Published connection message successfully!"); - //Serial.print("Subcribed to: "); - //Serial.println(subTopic); - - client.subscribe(subTopic); - // for loopback testing - client.subscribe(TOPIC); - } - else - { - Serial.print("...failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - - // Wait 5 seconds before retrying - delay(5000); - } - } + // Loop until we're reconnected + while (!client.connected()) + { + Serial.print("Attempting MQTT connection to "); + Serial.print(mqttServer); + + // Attempt to connect + if (client.connect("arduino", "try", "try")) + { + Serial.println("...connected"); + + // Once connected, publish an announcement... + client.publish(TOPIC, data.c_str()); + + //Serial.println("Published connection message successfully!"); + //Serial.print("Subcribed to: "); + //Serial.println(subTopic); + + client.subscribe(subTopic); + // for loopback testing + client.subscribe(TOPIC); + } + else + { + Serial.print("...failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + + // Wait 5 seconds before retrying + delay(5000); + } + } } 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("Local 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"); + // 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("Local 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"); } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart MQTTClient_Auth on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); - - status = WiFi.begin(ssid, pass); - - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } - - printWifiStatus(); - - /////////////////////////////////// - - // Note - the default maximum packet size is 128 bytes. If the - // combined length of clientId, username and password exceed this use the - // following to increase the buffer size: - // client.setBufferSize(255); + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart MQTTClient_Auth on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + // Note - the default maximum packet size is 128 bytes. If the + // combined length of clientId, username and password exceed this use the + // following to increase the buffer size: + // client.setBufferSize(255); } #define MQTT_PUBLISH_INTERVAL_MS 5000L unsigned long lastMsg = 0; -void loop() +void loop() { - static unsigned long now; - - if (!client.connected()) - { - reconnect(); - } - - // Sending Data - now = millis(); - - if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) - { - lastMsg = now; - - if (!client.publish(TOPIC, pubData)) - { - Serial.println("Message failed to send."); - } - - Serial.print("Message Send : " + String(TOPIC) + " => "); - Serial.println(data); - } - - client.loop(); + static unsigned long now; + + if (!client.connected()) + { + reconnect(); + } + + // Sending Data + now = millis(); + + if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) + { + lastMsg = now; + + if (!client.publish(TOPIC, pubData)) + { + Serial.println("Message failed to send."); + } + + Serial.print("Message Send : " + String(TOPIC) + " => "); + Serial.println(data); + } + + client.loop(); } diff --git a/examples/WiFi/MQTTClient_Auth/defines.h b/examples/WiFi/MQTTClient_Auth/defines.h index 2395c95..f5c179b 100644 --- a/examples/WiFi/MQTTClient_Auth/defines.h +++ b/examples/WiFi/MQTTClient_Auth/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -15,7 +15,7 @@ #define defines_h #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 diff --git a/examples/WiFi/MQTTClient_Basic/MQTTClient_Basic.ino b/examples/WiFi/MQTTClient_Basic/MQTTClient_Basic.ino index 973e27a..19d3e3a 100644 --- a/examples/WiFi/MQTTClient_Basic/MQTTClient_Basic.ino +++ b/examples/WiFi/MQTTClient_Basic/MQTTClient_Basic.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** MQTTClient_Basic.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -18,7 +18,7 @@ - publishes "hello world" to the topic "outTopic" - subscribes to the topic "inTopic", printing out any messages it receives. NB - it assumes the received payloads are strings not binary - + It will reconnect to the server if the connection is lost using a blocking reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to achieve the same result without blocking the main loop. @@ -38,18 +38,18 @@ const char *ID = "MQTTClient_SSL-Client"; // Name of our device, must be const char *TOPIC = "MQTT_Pub"; // Topic to subcribe to const char *subTopic = "MQTT_Sub"; // Topic to subcribe to -void callback(char* topic, byte* payload, unsigned int length) +void callback(char* topic, byte* payload, unsigned int length) { - Serial.print("Message arrived ["); - Serial.print(topic); - Serial.print("] "); - - for (unsigned int i = 0; i < length; i++) - { - Serial.print((char)payload[i]); - } - - Serial.println(); + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + + for (unsigned int i = 0; i < length; i++) + { + Serial.print((char)payload[i]); + } + + Serial.println(); } WiFiClient wifiClient; @@ -60,134 +60,138 @@ const char *pubData = data.c_str(); void reconnect() { - // Loop until we're reconnected - while (!client.connected()) - { - Serial.print("Attempting MQTT connection to "); - Serial.print(mqttServer); - - // Attempt to connect - if (client.connect(ID, "try", "try")) - { - Serial.println("...connected"); - - // Once connected, publish an announcement... - client.publish(TOPIC, data.c_str()); - - //Serial.println("Published connection message successfully!"); - //Serial.print("Subcribed to: "); - //Serial.println(subTopic); - - client.subscribe(subTopic); - // for loopback testing - client.subscribe(TOPIC); - } - else - { - Serial.print("...failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - - // Wait 5 seconds before retrying - delay(5000); - } - } + // Loop until we're reconnected + while (!client.connected()) + { + Serial.print("Attempting MQTT connection to "); + Serial.print(mqttServer); + + // Attempt to connect + if (client.connect(ID, "try", "try")) + { + Serial.println("...connected"); + + // Once connected, publish an announcement... + client.publish(TOPIC, data.c_str()); + + //Serial.println("Published connection message successfully!"); + //Serial.print("Subcribed to: "); + //Serial.println(subTopic); + + client.subscribe(subTopic); + // for loopback testing + client.subscribe(TOPIC); + } + else + { + Serial.print("...failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + + // Wait 5 seconds before retrying + delay(5000); + } + } } 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("Local 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"); + // 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("Local 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"); } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart MQTTClient_Basic on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); - - status = WiFi.begin(ssid, pass); - - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } - - printWifiStatus(); - - /////////////////////////////////// - - client.setServer(mqttServer, 1883); - client.setCallback(callback); - - // Allow the hardware to sort itself out - delay(1500); + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart MQTTClient_Basic on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + client.setServer(mqttServer, 1883); + client.setCallback(callback); + + // Allow the hardware to sort itself out + delay(1500); } #define MQTT_PUBLISH_INTERVAL_MS 5000L unsigned long lastMsg = 0; -void loop() +void loop() { - static unsigned long now; - - if (!client.connected()) - { - reconnect(); - } - - // Sending Data - now = millis(); - - if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) - { - lastMsg = now; - - if (!client.publish(TOPIC, pubData)) - { - Serial.println("Message failed to send."); - } - - Serial.print("Message Send : " + String(TOPIC) + " => "); - Serial.println(data); - } - - client.loop(); + static unsigned long now; + + if (!client.connected()) + { + reconnect(); + } + + // Sending Data + now = millis(); + + if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) + { + lastMsg = now; + + if (!client.publish(TOPIC, pubData)) + { + Serial.println("Message failed to send."); + } + + Serial.print("Message Send : " + String(TOPIC) + " => "); + Serial.println(data); + } + + client.loop(); } diff --git a/examples/WiFi/MQTTClient_Basic/defines.h b/examples/WiFi/MQTTClient_Basic/defines.h index 2395c95..f5c179b 100644 --- a/examples/WiFi/MQTTClient_Basic/defines.h +++ b/examples/WiFi/MQTTClient_Basic/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -15,7 +15,7 @@ #define defines_h #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 diff --git a/examples/WiFi/MQTT_ThingStream/MQTT_ThingStream.ino b/examples/WiFi/MQTT_ThingStream/MQTT_ThingStream.ino index 489de6c..7381f43 100644 --- a/examples/WiFi/MQTT_ThingStream/MQTT_ThingStream.ino +++ b/examples/WiFi/MQTT_ThingStream/MQTT_ThingStream.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** MQTT_ThingStream.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -41,28 +41,28 @@ const char my_key[] = "FIXME"; #if USING_THINGSTREAM_IO -const char *MQTT_PREFIX_TOPIC = "esp32-sniffer/"; -const char *MQTT_ANNOUNCE_TOPIC = "/status"; -const char *MQTT_CONTROL_TOPIC = "/control"; -const char *MQTT_BLE_TOPIC = "/ble"; + const char *MQTT_PREFIX_TOPIC = "esp32-sniffer/"; + const char *MQTT_ANNOUNCE_TOPIC = "/status"; + const char *MQTT_CONTROL_TOPIC = "/control"; + const char *MQTT_BLE_TOPIC = "/ble"; -// GOT FROM ThingsStream! -const char *MQTT_SERVER = "mqtt.thingstream.io"; -const char *MQTT_USER = "MQTT_USER"; -const char *MQTT_PASS = "MQTT_PASS"; -const char *MQTT_CLIENT_ID = "MQTT_CLIENT_ID"; + // GOT FROM ThingsStream! + const char *MQTT_SERVER = "mqtt.thingstream.io"; + const char *MQTT_USER = "MQTT_USER"; + const char *MQTT_PASS = "MQTT_PASS"; + const char *MQTT_CLIENT_ID = "MQTT_CLIENT_ID"; -String topic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; -String subTopic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; + String topic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; + String subTopic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; #else -const char* MQTT_SERVER = "broker.emqx.io"; // Broker address + const char* MQTT_SERVER = "broker.emqx.io"; // Broker address -const char* ID = "MQTT_ThingStream"; // Name of our device, must be unique -String topic = "Portenta_H7_Pub"; // Topic to subcribe to -String subTopic = "Portenta_H7_Sub"; // Topic to subcribe to + const char* ID = "MQTT_ThingStream"; // Name of our device, must be unique + String topic = "Portenta_H7_Pub"; // Topic to subcribe to + String subTopic = "Portenta_H7_Sub"; // Topic to subcribe to #endif @@ -85,164 +85,168 @@ const char *pubData = data.c_str(); /* Called whenever a payload is received from a subscribed MQTT topic */ -void mqtt_receive_callback(char* topic, byte* payload, unsigned int length) +void mqtt_receive_callback(char* topic, byte* payload, unsigned int length) { - Serial.print("MQTT Message receive ["); - Serial.print(topic); - Serial.print("] "); - - for (unsigned int i = 0; i < length; i++) - { - Serial.print((char)payload[i]); - } - - Serial.println(); + Serial.print("MQTT Message receive ["); + Serial.print(topic); + Serial.print("] "); + + for (unsigned int i = 0; i < length; i++) + { + Serial.print((char)payload[i]); + } + + Serial.println(); } -void reconnect() +void reconnect() { - // Loop until we're reconnected - while (!client.connected()) - { - Serial.print("Attempting MQTT connection to "); - Serial.println(MQTT_SERVER); + // Loop until we're reconnected + while (!client.connected()) + { + Serial.print("Attempting MQTT connection to "); + Serial.println(MQTT_SERVER); - // Attempt to connect + // Attempt to connect #if USING_THINGSTREAM_IO - int connect_status = client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, topic.c_str(), 2, false, ""); + int connect_status = client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, topic.c_str(), 2, false, ""); #else - int connect_status = client.connect(ID); + int connect_status = client.connect(ID); #endif - if (connect_status) - { - Serial.println("...connected"); - - // Once connected, publish an announcement... - client.publish(topic.c_str(), data.c_str()); - - Serial.println("Published connection message successfully!"); - - Serial.print("Subcribed to: "); - Serial.println(subTopic); - - // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 - //ethClientSSL.flush(); - // ... and resubscribe - client.subscribe(subTopic.c_str()); - // for loopback testing - client.subscribe(topic.c_str()); - // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 - //ethClientSSL.flush(); - } - else - { - Serial.print("failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); - - // Wait 5 seconds before retrying - delay(5000); - } - } + if (connect_status) + { + Serial.println("...connected"); + + // Once connected, publish an announcement... + client.publish(topic.c_str(), data.c_str()); + + Serial.println("Published connection message successfully!"); + + Serial.print("Subcribed to: "); + Serial.println(subTopic); + + // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 + //ethClientSSL.flush(); + // ... and resubscribe + client.subscribe(subTopic.c_str()); + // for loopback testing + client.subscribe(topic.c_str()); + // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 + //ethClientSSL.flush(); + } + else + { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + + // Wait 5 seconds before retrying + delay(5000); + } + } } 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("Local 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"); + // 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("Local 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"); } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart MQTT_ThingStream on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); - - status = WiFi.begin(ssid, pass); - - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } - - printWifiStatus(); - - /////////////////////////////////// - - // Note - the default maximum packet size is 256 bytes. If the - // combined length of clientId, username and password exceed this use the - // following to increase the buffer size: - //client.setBufferSize(256); - - Serial.println("***************************************"); - Serial.println(topic); - Serial.println("***************************************"); + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart MQTT_ThingStream on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + // Note - the default maximum packet size is 256 bytes. If the + // combined length of clientId, username and password exceed this use the + // following to increase the buffer size: + //client.setBufferSize(256); + + Serial.println("***************************************"); + Serial.println(topic); + Serial.println("***************************************"); } #define MQTT_PUBLISH_INTERVAL_MS 5000L -void loop() +void loop() { - static unsigned long now; - - if (!client.connected()) - { - reconnect(); - } - - // Sending Data - now = millis(); - - if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) - { - lastMsg = now; - - if (!client.publish(topic.c_str(), pubData)) - { - Serial.println("Message failed to send."); - } - - Serial.print("MQTT Message Send : " + topic + " => "); - Serial.println(data); - } - - client.loop(); + static unsigned long now; + + if (!client.connected()) + { + reconnect(); + } + + // Sending Data + now = millis(); + + if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) + { + lastMsg = now; + + if (!client.publish(topic.c_str(), pubData)) + { + Serial.println("Message failed to send."); + } + + Serial.print("MQTT Message Send : " + topic + " => "); + Serial.println(data); + } + + client.loop(); } diff --git a/examples/WiFi/MQTT_ThingStream/defines.h b/examples/WiFi/MQTT_ThingStream/defines.h index 2395c95..f5c179b 100644 --- a/examples/WiFi/MQTT_ThingStream/defines.h +++ b/examples/WiFi/MQTT_ThingStream/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -15,7 +15,7 @@ #define defines_h #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 diff --git a/examples/WiFi/WebClient/WebClient.ino b/examples/WiFi/WebClient/WebClient.ino index cc6b205..4d7a8ca 100644 --- a/examples/WiFi/WebClient/WebClient.ino +++ b/examples/WiFi/WebClient/WebClient.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** WebClient.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -20,101 +20,105 @@ WiFiClient client; 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("Local 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"); + // 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("Local 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"); } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart WebClient on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); - - status = WiFi.begin(ssid, pass); - - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } - - printWifiStatus(); - - /////////////////////////////////// - - Serial.println(); - Serial.println(F("Starting connection to server...")); - - // if you get a connection, report back via serial - if (client.connect(server, 80)) - { - Serial.println(F("Connected to server")); - // Make a HTTP request - client.println(F("GET /asciilogo.txt HTTP/1.1")); - client.println(F("Host: arduino.cc")); - client.println(F("Connection: close")); - client.println(); - } + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart WebClient on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// + + Serial.println(); + Serial.println(F("Starting connection to server...")); + + // if you get a connection, report back via serial + if (client.connect(server, 80)) + { + Serial.println(F("Connected to server")); + // Make a HTTP request + client.println(F("GET /asciilogo.txt HTTP/1.1")); + client.println(F("Host: arduino.cc")); + client.println(F("Connection: close")); + client.println(); + } } void printoutData(void) { - // if there are incoming bytes available - // from the server, read them and print them - while (client.available()) - { - char c = client.read(); - Serial.write(c); - } + // if there are incoming bytes available + // from the server, read them and print them + while (client.available()) + { + char c = client.read(); + Serial.write(c); + } } void loop() { - printoutData(); - - // if the server's disconnected, stop the client - if (!client.connected()) - { - Serial.println(); - Serial.println(F("Disconnecting from server...")); - client.stop(); - - // do nothing forevermore - while (true); - } + printoutData(); + + // if the server's disconnected, stop the client + if (!client.connected()) + { + Serial.println(); + Serial.println(F("Disconnecting from server...")); + client.stop(); + + // do nothing forevermore + while (true); + } } diff --git a/examples/WiFi/WebClient/defines.h b/examples/WiFi/WebClient/defines.h index 8c73e1a..6a50cf1 100644 --- a/examples/WiFi/WebClient/defines.h +++ b/examples/WiFi/WebClient/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -16,7 +16,7 @@ #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define USE_WIFI_PORTENTA_H7 true diff --git a/examples/WiFi/WebClientRepeating/WebClientRepeating.ino b/examples/WiFi/WebClientRepeating/WebClientRepeating.ino index b6e1e90..cc0b460 100644 --- a/examples/WiFi/WebClientRepeating/WebClientRepeating.ino +++ b/examples/WiFi/WebClientRepeating/WebClientRepeating.ino @@ -1,10 +1,10 @@ /**************************************************************************************************************************** WebClientRepeating.ino - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -23,107 +23,111 @@ WiFiClient client; // this method makes a HTTP connection to the server void httpRequest() { - Serial.println(); - - // close any connection before send a new request - // this will free the socket on the WiFi shield - client.stop(); - - // if there's a successful connection - if (client.connect(server, 80)) - { - Serial.println(F("Connecting...")); - - // send the HTTP PUT request - client.println(F("GET /asciilogo.txt HTTP/1.1")); - client.println(F("Host: arduino.cc")); - client.println(F("Connection: close")); - client.println(); - - // note the time that the connection was made - lastConnectionTime = millis(); - } - else - { - // if you couldn't make a connection - Serial.println(F("Connection failed")); - } + Serial.println(); + + // close any connection before send a new request + // this will free the socket on the WiFi shield + client.stop(); + + // if there's a successful connection + if (client.connect(server, 80)) + { + Serial.println(F("Connecting...")); + + // send the HTTP PUT request + client.println(F("GET /asciilogo.txt HTTP/1.1")); + client.println(F("Host: arduino.cc")); + client.println(F("Connection: close")); + client.println(); + + // note the time that the connection was made + lastConnectionTime = millis(); + } + else + { + // if you couldn't make a connection + Serial.println(F("Connection failed")); + } } 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("Local 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"); + // 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("Local 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"); } void setup() { - // Open serial communications and wait for port to open: - Serial.begin(115200); - while (!Serial && millis() < 5000); - - Serial.print("\nStart WebClientRepeating on "); Serial.print(BOARD_NAME); - Serial.print(" with "); Serial.println(SHIELD_TYPE); - Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); - Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); - - /////////////////////////////////// - - // check for the WiFi module: - if (WiFi.status() == WL_NO_MODULE) - { - Serial.println("Communication with WiFi module failed!"); - // don't continue - while (true); - } - - Serial.print(F("Connecting to SSID: ")); - Serial.println(ssid); - - status = WiFi.begin(ssid, pass); - - delay(1000); - - // attempt to connect to WiFi network - while ( status != WL_CONNECTED) - { - delay(500); - - // Connect to WPA/WPA2 network - status = WiFi.status(); - } - - printWifiStatus(); - - /////////////////////////////////// + // Open serial communications and wait for port to open: + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + Serial.print("\nStart WebClientRepeating on "); + Serial.print(BOARD_NAME); + Serial.print(" with "); + Serial.println(SHIELD_TYPE); + Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION); + Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION); + + /////////////////////////////////// + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + + // don't continue + while (true); + } + + Serial.print(F("Connecting to SSID: ")); + Serial.println(ssid); + + status = WiFi.begin(ssid, pass); + + delay(1000); + + // attempt to connect to WiFi network + while ( status != WL_CONNECTED) + { + delay(500); + + // Connect to WPA/WPA2 network + status = WiFi.status(); + } + + printWifiStatus(); + + /////////////////////////////////// } void loop() { - // if there's incoming data from the net connection send it out the serial port - // this is for debugging purposes only - while (client.available()) - { - char c = client.read(); - Serial.write(c); - } - - // if 10 seconds have passed since your last connection, - // then connect again and send data - if (millis() - lastConnectionTime > postingInterval) - { - httpRequest(); - } + // if there's incoming data from the net connection send it out the serial port + // this is for debugging purposes only + while (client.available()) + { + char c = client.read(); + Serial.write(c); + } + + // if 10 seconds have passed since your last connection, + // then connect again and send data + if (millis() - lastConnectionTime > postingInterval) + { + httpRequest(); + } } diff --git a/examples/WiFi/WebClientRepeating/defines.h b/examples/WiFi/WebClientRepeating/defines.h index 903a8b0..21af27a 100644 --- a/examples/WiFi/WebClientRepeating/defines.h +++ b/examples/WiFi/WebClientRepeating/defines.h @@ -1,10 +1,10 @@ /**************************************************************************************************************************** defines.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license @@ -15,7 +15,7 @@ #define defines_h #if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) ) - #error For Portenta_H7 only + #error For Portenta_H7 only #endif #define _PORTENTA_H7_AWS_LOGLEVEL_ 1 diff --git a/library.json b/library.json index ff12e82..cb75436 100644 --- a/library.json +++ b/library.json @@ -1,8 +1,8 @@ { "name": "Portenta_H7_AsyncWebServer", - "version": "1.4.1", + "version": "1.4.2", "keywords": "http, async, websocket, webserver, async-webserver, async-tcp, async-udp, async-websocket, async-http, ssl, tls, mbed, mbed-portenta, portenta-h7, portentah7, portenta-h7-m7, portenta-h7-m4, portentah7-m7, portentah7-m4, stm32h7", - "description": "Asynchronous WebServer Library for STM32H7-based Portenta_H7 using mbed_portenta core. This library, which is relied on Portenta_H7_AsyncTCP, is part of a series of advanced Async libraries, such as AsyncTCP, AsyncUDP, AsyncWebSockets, AsyncHTTPRequest, AsyncHTTPSRequest, etc. Now supporting using CString in optional SDRAM to save heap to send very large data", + "description": "Asynchronous WebServer Library for STM32H7-based Portenta_H7 using mbed_portenta core. This library, which is relied on Portenta_H7_AsyncTCP, is part of a series of advanced Async libraries, such as AsyncTCP, AsyncUDP, AsyncWebSockets, AsyncHTTPRequest, AsyncHTTPSRequest, etc. Now supporting using CString in optional SDRAM to save heap to send very large data and examples to demo how to use beginChunkedResponse() to send large html in chunks", "authors": [ { diff --git a/library.properties b/library.properties index 6517206..b3a32d4 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=Portenta_H7_AsyncWebServer -version=1.4.1 +version=1.4.2 author=Hristo Gochkov,Khoi Hoang maintainer=Khoi Hoang sentence=Asynchronous WebServer Library for STM32H7-based Portenta_H7 using mbed_portenta core. -paragraph=This library, which is relied on Portenta_H7_AsyncTCP, is part of a series of advanced Async libraries, such as AsyncTCP, AsyncUDP, AsyncWebSockets, AsyncHTTPRequest, AsyncHTTPSRequest, etc. Now supporting using CString in optional SDRAM to save heap to send very large data +paragraph=This library, which is relied on Portenta_H7_AsyncTCP, is part of a series of advanced Async libraries, such as AsyncTCP, AsyncUDP, AsyncWebSockets, AsyncHTTPRequest, AsyncHTTPSRequest, etc. Now supporting using CString in optional SDRAM to save heap to send very large data and examples to demo how to use beginChunkedResponse() to send large html in chunks category=Communication url=https://github.com/khoih-prog/Portenta_H7_AsyncWebServer architectures=mbed,mbed_portenta,ArduinoCore-mbed diff --git a/pics/AsyncWebServer_SendChunked_Ethernet.png b/pics/AsyncWebServer_SendChunked_Ethernet.png new file mode 100644 index 0000000..af6b0f8 Binary files /dev/null and b/pics/AsyncWebServer_SendChunked_Ethernet.png differ diff --git a/pics/AsyncWebServer_SendChunked_WiFi.png b/pics/AsyncWebServer_SendChunked_WiFi.png new file mode 100644 index 0000000..4fec94e Binary files /dev/null and b/pics/AsyncWebServer_SendChunked_WiFi.png differ diff --git a/src/Crypto/Hash.cpp b/src/Crypto/Hash.cpp index 77a61e6..65257da 100644 --- a/src/Crypto/Hash.cpp +++ b/src/Crypto/Hash.cpp @@ -1,26 +1,26 @@ /** - * @file Hash.cpp - * @date 20.05.2015 - * @author Markus Sattler - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the esp8266 core for Arduino environment. - * - * 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 - * - */ + @file Hash.cpp + @date 20.05.2015 + @author Markus Sattler + + Copyright (c) 2015 Markus Sattler. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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 #include "bearssl_hash.h" @@ -28,81 +28,82 @@ #include "Hash.h" /** - * create a sha1 hash from data - * @param data uint8_t * - * @param size uint32_t - * @param hash uint8_t[HASH_BUFFER_SIZE] - */ -void sha1(const uint8_t* data, uint32_t size, uint8_t hash[HASH_BUFFER_SIZE]) + create a sha1 hash from data + @param data uint8_t + @param size uint32_t + @param hash uint8_t[HASH_BUFFER_SIZE] +*/ +void sha1(const uint8_t* data, uint32_t size, uint8_t hash[HASH_BUFFER_SIZE]) { - br_sha1_context ctx; - - AWS_LOGDEBUG0("DATA:"); - for(uint16_t i = 0; i < size; i++) - { - AWS_LOGDEBUG0(data[i]); - } - - AWS_LOGDEBUG0("\nDATA:"); - - for(uint16_t i = 0; i < size; i++) - { - AWS_LOGDEBUG0((char) data[i]); - - } - - AWS_LOGDEBUG0("\n"); - - br_sha1_init(&ctx); - br_sha1_update(&ctx, data, size); - br_sha1_out(&ctx, hash); - - AWS_LOGDEBUG0("SHA1:"); - - for(uint16_t i = 0; i < HASH_BUFFER_SIZE; i++) - { - AWS_LOGDEBUG0(hash[i]); - } - - AWS_LOGDEBUG0("\n"); + br_sha1_context ctx; + + AWS_LOGDEBUG0("DATA:"); + + for (uint16_t i = 0; i < size; i++) + { + AWS_LOGDEBUG0(data[i]); + } + + AWS_LOGDEBUG0("\nDATA:"); + + for (uint16_t i = 0; i < size; i++) + { + AWS_LOGDEBUG0((char) data[i]); + + } + + AWS_LOGDEBUG0("\n"); + + br_sha1_init(&ctx); + br_sha1_update(&ctx, data, size); + br_sha1_out(&ctx, hash); + + AWS_LOGDEBUG0("SHA1:"); + + for (uint16_t i = 0; i < HASH_BUFFER_SIZE; i++) + { + AWS_LOGDEBUG0(hash[i]); + } + + AWS_LOGDEBUG0("\n"); } -void sha1(const char* data, uint32_t size, uint8_t hash[HASH_BUFFER_SIZE]) +void sha1(const char* data, uint32_t size, uint8_t hash[HASH_BUFFER_SIZE]) { - sha1((const uint8_t *) data, size, hash); + sha1((const uint8_t *) data, size, hash); } -void sha1(const String& data, uint8_t hash[HASH_BUFFER_SIZE]) +void sha1(const String& data, uint8_t hash[HASH_BUFFER_SIZE]) { - sha1(data.c_str(), data.length(), hash); + sha1(data.c_str(), data.length(), hash); } -String sha1(const uint8_t* data, uint32_t size) +String sha1(const uint8_t* data, uint32_t size) { - uint8_t hash[HASH_BUFFER_SIZE]; - - String hashStr((const char*)nullptr); - hashStr.reserve(HASH_BUFFER_SIZE * 2 + 1); + uint8_t hash[HASH_BUFFER_SIZE]; + + String hashStr((const char*)nullptr); + hashStr.reserve(HASH_BUFFER_SIZE * 2 + 1); - sha1(&data[0], size, &hash[0]); + sha1(&data[0], size, &hash[0]); - for(uint16_t i = 0; i < HASH_BUFFER_SIZE; i++) - { - char hex[3]; - snprintf(hex, sizeof(hex), "%02x", hash[i]); - hashStr += hex; - } + for (uint16_t i = 0; i < HASH_BUFFER_SIZE; i++) + { + char hex[3]; + snprintf(hex, sizeof(hex), "%02x", hash[i]); + hashStr += hex; + } - return hashStr; + return hashStr; } -String sha1(const char* data, uint32_t size) +String sha1(const char* data, uint32_t size) { - return sha1((const uint8_t*) data, size); + return sha1((const uint8_t*) data, size); } -String sha1(const String& data) +String sha1(const String& data) { - return sha1(data.c_str(), data.length()); + return sha1(data.c_str(), data.length()); } diff --git a/src/Crypto/Hash.h b/src/Crypto/Hash.h index c097998..80f0b71 100644 --- a/src/Crypto/Hash.h +++ b/src/Crypto/Hash.h @@ -1,26 +1,26 @@ /** - * @file Hash.h - * @date 20.05.2015 - * @author Markus Sattler - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the esp8266 core for Arduino environment. - * - * 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 - * - */ + @file Hash.h + @date 20.05.2015 + @author Markus Sattler + + Copyright (c) 2015 Markus Sattler. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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 + +*/ #pragma once diff --git a/src/Crypto/bearssl_hash.h b/src/Crypto/bearssl_hash.h index dd47fb0..d518678 100644 --- a/src/Crypto/bearssl_hash.h +++ b/src/Crypto/bearssl_hash.h @@ -1,26 +1,26 @@ /* - * Copyright (c) 2016 Thomas Pornin - * - * 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. - */ + Copyright (c) 2016 Thomas Pornin + + 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. +*/ #pragma once @@ -224,7 +224,7 @@ extern "C" { */ typedef struct br_hash_class_ br_hash_class; -struct br_hash_class_ +struct br_hash_class_ { /** \brief Size (in bytes) of the context structure appropriate for @@ -392,7 +392,7 @@ extern const br_hash_class br_md5_vtable; First field is a pointer to the vtable; it is set by the initialisation function. Other fields are not supposed to be accessed by user code. */ -typedef struct +typedef struct { /** \brief Pointer to vtable for this context. @@ -488,7 +488,7 @@ extern const br_hash_class br_sha1_vtable; First field is a pointer to the vtable; it is set by the initialisation function. Other fields are not supposed to be accessed by user code. */ -typedef struct +typedef struct { /** \brief Pointer to vtable for this context. @@ -584,7 +584,7 @@ extern const br_hash_class br_sha224_vtable; First field is a pointer to the vtable; it is set by the initialisation function. Other fields are not supposed to be accessed by user code. */ -typedef struct +typedef struct { /** \brief Pointer to vtable for this context. @@ -675,22 +675,22 @@ void br_sha224_set_state(br_sha224_context *ctx, const void *stb, uint64_t count extern const br_hash_class br_sha256_vtable; #ifdef BR_DOXYGEN_IGNORE +/** + \brief SHA-256 context. + + First field is a pointer to the vtable; it is set by the initialisation + function. Other fields are not supposed to be accessed by user code. +*/ +typedef struct +{ /** - \brief SHA-256 context. - - First field is a pointer to the vtable; it is set by the initialisation - function. Other fields are not supposed to be accessed by user code. + \brief Pointer to vtable for this context. */ - typedef struct - { - /** - \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; - } br_sha256_context; + const br_hash_class *vtable; +} br_sha256_context; #else - typedef br_sha224_context br_sha256_context; +typedef br_sha224_context br_sha256_context; #endif /** @@ -704,20 +704,20 @@ extern const br_hash_class br_sha256_vtable; void br_sha256_init(br_sha256_context *ctx); #ifdef BR_DOXYGEN_IGNORE - /** - \brief Inject some data bytes in a running SHA-256 computation. - - The provided context is updated with some data bytes. If the number - of bytes (`len`) is zero, then the data pointer (`data`) is ignored - and may be `NULL`, and this function does nothing. - - \param ctx pointer to the context structure. - \param data pointer to the injected data. - \param len injected data length (in bytes). - */ - void br_sha256_update(br_sha256_context *ctx, const void *data, size_t len); +/** + \brief Inject some data bytes in a running SHA-256 computation. + + The provided context is updated with some data bytes. If the number + of bytes (`len`) is zero, then the data pointer (`data`) is ignored + and may be `NULL`, and this function does nothing. + + \param ctx pointer to the context structure. + \param data pointer to the injected data. + \param len injected data length (in bytes). +*/ +void br_sha256_update(br_sha256_context *ctx, const void *data, size_t len); #else - #define br_sha256_update br_sha224_update +#define br_sha256_update br_sha224_update #endif /** @@ -735,36 +735,36 @@ void br_sha256_init(br_sha256_context *ctx); void br_sha256_out(const br_sha256_context *ctx, void *out); #ifdef BR_DOXYGEN_IGNORE - /** - \brief Save SHA-256 running state. - - The running state for SHA-256 (output of the last internal block - processing) is written in the buffer pointed to by `out`. The - number of bytes injected since the last initialisation or reset - call is returned. The context is not modified. - - \param ctx pointer to the context structure. - \param out destination buffer for the running state. - \return the injected total byte length. - */ - uint64_t br_sha256_state(const br_sha256_context *ctx, void *out); +/** + \brief Save SHA-256 running state. + + The running state for SHA-256 (output of the last internal block + processing) is written in the buffer pointed to by `out`. The + number of bytes injected since the last initialisation or reset + call is returned. The context is not modified. + + \param ctx pointer to the context structure. + \param out destination buffer for the running state. + \return the injected total byte length. +*/ +uint64_t br_sha256_state(const br_sha256_context *ctx, void *out); #else - #define br_sha256_state br_sha224_state +#define br_sha256_state br_sha224_state #endif #ifdef BR_DOXYGEN_IGNORE - /** - \brief Restore SHA-256 running state. - - The running state for SHA-256 is set to the provided values. - - \param ctx pointer to the context structure. - \param stb source buffer for the running state. - \param count the injected total byte length. - */ - void br_sha256_set_state(br_sha256_context *ctx, const void *stb, uint64_t count); +/** + \brief Restore SHA-256 running state. + + The running state for SHA-256 is set to the provided values. + + \param ctx pointer to the context structure. + \param stb source buffer for the running state. + \param count the injected total byte length. +*/ +void br_sha256_set_state(br_sha256_context *ctx, const void *stb, uint64_t count); #else - #define br_sha256_set_state br_sha224_set_state +#define br_sha256_set_state br_sha224_set_state #endif /** @@ -788,7 +788,7 @@ extern const br_hash_class br_sha384_vtable; First field is a pointer to the vtable; it is set by the initialisation function. Other fields are not supposed to be accessed by user code. */ -typedef struct +typedef struct { /** \brief Pointer to vtable for this context. @@ -880,21 +880,21 @@ void br_sha384_set_state(br_sha384_context *ctx, extern const br_hash_class br_sha512_vtable; #ifdef BR_DOXYGEN_IGNORE +/** + \brief SHA-512 context. + + First field is a pointer to the vtable; it is set by the initialisation + function. Other fields are not supposed to be accessed by user code. +*/ +typedef struct +{ /** - \brief SHA-512 context. - - First field is a pointer to the vtable; it is set by the initialisation - function. Other fields are not supposed to be accessed by user code. + \brief Pointer to vtable for this context. */ - typedef struct - { - /** - \brief Pointer to vtable for this context. - */ - const br_hash_class *vtable; - } br_sha512_context; + const br_hash_class *vtable; +} br_sha512_context; #else - typedef br_sha384_context br_sha512_context; +typedef br_sha384_context br_sha512_context; #endif /** @@ -908,20 +908,20 @@ extern const br_hash_class br_sha512_vtable; void br_sha512_init(br_sha512_context *ctx); #ifdef BR_DOXYGEN_IGNORE - /** - \brief Inject some data bytes in a running SHA-512 computation. - - The provided context is updated with some data bytes. If the number - of bytes (`len`) is zero, then the data pointer (`data`) is ignored - and may be `NULL`, and this function does nothing. - - \param ctx pointer to the context structure. - \param data pointer to the injected data. - \param len injected data length (in bytes). - */ - void br_sha512_update(br_sha512_context *ctx, const void *data, size_t len); +/** + \brief Inject some data bytes in a running SHA-512 computation. + + The provided context is updated with some data bytes. If the number + of bytes (`len`) is zero, then the data pointer (`data`) is ignored + and may be `NULL`, and this function does nothing. + + \param ctx pointer to the context structure. + \param data pointer to the injected data. + \param len injected data length (in bytes). +*/ +void br_sha512_update(br_sha512_context *ctx, const void *data, size_t len); #else - #define br_sha512_update br_sha384_update +#define br_sha512_update br_sha384_update #endif /** @@ -939,36 +939,36 @@ void br_sha512_init(br_sha512_context *ctx); void br_sha512_out(const br_sha512_context *ctx, void *out); #ifdef BR_DOXYGEN_IGNORE - /** - \brief Save SHA-512 running state. - - The running state for SHA-512 (output of the last internal block - processing) is written in the buffer pointed to by `out`. The - number of bytes injected since the last initialisation or reset - call is returned. The context is not modified. - - \param ctx pointer to the context structure. - \param out destination buffer for the running state. - \return the injected total byte length. - */ - uint64_t br_sha512_state(const br_sha512_context *ctx, void *out); +/** + \brief Save SHA-512 running state. + + The running state for SHA-512 (output of the last internal block + processing) is written in the buffer pointed to by `out`. The + number of bytes injected since the last initialisation or reset + call is returned. The context is not modified. + + \param ctx pointer to the context structure. + \param out destination buffer for the running state. + \return the injected total byte length. +*/ +uint64_t br_sha512_state(const br_sha512_context *ctx, void *out); #else - #define br_sha512_state br_sha384_state +#define br_sha512_state br_sha384_state #endif #ifdef BR_DOXYGEN_IGNORE - /** - \brief Restore SHA-512 running state. - - The running state for SHA-512 is set to the provided values. - - \param ctx pointer to the context structure. - \param stb source buffer for the running state. - \param count the injected total byte length. - */ - void br_sha512_set_state(br_sha512_context *ctx, const void *stb, uint64_t count); +/** + \brief Restore SHA-512 running state. + + The running state for SHA-512 is set to the provided values. + + \param ctx pointer to the context structure. + \param stb source buffer for the running state. + \param count the injected total byte length. +*/ +void br_sha512_set_state(br_sha512_context *ctx, const void *stb, uint64_t count); #else - #define br_sha512_set_state br_sha384_set_state +#define br_sha512_set_state br_sha384_set_state #endif /* @@ -1002,7 +1002,7 @@ extern const br_hash_class br_md5sha1_vtable; First field is a pointer to the vtable; it is set by the initialisation function. Other fields are not supposed to be accessed by user code. */ -typedef struct +typedef struct { /** \brief Pointer to vtable for this context. @@ -1085,7 +1085,7 @@ void br_md5sha1_set_state(br_md5sha1_context *ctx, The `br_hash_compat_context` type is a type which is large enough to serve as context for all standard hash functions defined above. */ -typedef union +typedef union { const br_hash_class *vtable; br_md5_context md5; @@ -1116,7 +1116,7 @@ typedef union Instead, it is configured with the vtables of the hash functions it should run. Structure fields are not supposed to be accessed directly. */ -typedef struct +typedef struct { #ifndef BR_DOXYGEN_IGNORE unsigned char buf[128]; diff --git a/src/Crypto/md5.h b/src/Crypto/md5.h index f48098b..f3f3bcd 100644 --- a/src/Crypto/md5.h +++ b/src/Crypto/md5.h @@ -1,37 +1,37 @@ /** - * \file md5.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * + \file md5.h + + Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + + Copyright (C) 2009 Paul Bakker + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #pragma once @@ -41,13 +41,13 @@ #include "Portenta_H7_AsyncWebServer_Debug.h" /** - * \brief MD5 context structure - */ + \brief MD5 context structure +*/ typedef struct { - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ } md5_context; @@ -56,36 +56,36 @@ extern "C" { #endif /** - * \brief MD5 context setup - * - * \param ctx context to be initialized - */ + \brief MD5 context setup + + \param ctx context to be initialized +*/ void md5_starts( md5_context *ctx ); /** - * \brief MD5 process buffer - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - */ + \brief MD5 process buffer + + \param ctx MD5 context + \param input buffer holding the data + \param ilen length of the input data +*/ void md5_update( md5_context *ctx, const unsigned char *input, int ilen ); /** - * \brief MD5 final digest - * - * \param ctx MD5 context - * \param output MD5 checksum result - */ + \brief MD5 final digest + + \param ctx MD5 context + \param output MD5 checksum result +*/ void md5_finish( md5_context *ctx, unsigned char output[16] ); /** - * \brief Output = MD5( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - */ + \brief Output = MD5( input buffer ) + + \param input buffer holding the data + \param ilen length of the input data + \param output MD5 checksum result +*/ void md5( unsigned char *input, int ilen, unsigned char output[16] ); #ifdef __cplusplus diff --git a/src/Crypto/sha1.c b/src/Crypto/sha1.c index 4e470f3..0bd892d 100644 --- a/src/Crypto/sha1.c +++ b/src/Crypto/sha1.c @@ -1,330 +1,330 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#include "sha1.h" - -#include - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_ULONG_BE -#define GET_ULONG_BE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ - | ( (unsigned long) (b)[(i) + 1] << 16 ) \ - | ( (unsigned long) (b)[(i) + 2] << 8 ) \ - | ( (unsigned long) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_ULONG_BE -#define PUT_ULONG_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * SHA-1 context setup - */ -void sha1_starts( sha1_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) -{ - unsigned long temp, W[16], A, B, C, D, E; - - GET_ULONG_BE( W[ 0], data, 0 ); - GET_ULONG_BE( W[ 1], data, 4 ); - GET_ULONG_BE( W[ 2], data, 8 ); - GET_ULONG_BE( W[ 3], data, 12 ); - GET_ULONG_BE( W[ 4], data, 16 ); - GET_ULONG_BE( W[ 5], data, 20 ); - GET_ULONG_BE( W[ 6], data, 24 ); - GET_ULONG_BE( W[ 7], data, 28 ); - GET_ULONG_BE( W[ 8], data, 32 ); - GET_ULONG_BE( W[ 9], data, 36 ); - GET_ULONG_BE( W[10], data, 40 ); - GET_ULONG_BE( W[11], data, 44 ); - GET_ULONG_BE( W[12], data, 48 ); - GET_ULONG_BE( W[13], data, 52 ); - GET_ULONG_BE( W[14], data, 56 ); - GET_ULONG_BE( W[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ - W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -/* - * SHA-1 process buffer - */ -void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - input, fill ); - sha1_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - sha1_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), - input, ilen ); - } -} - -static const unsigned char sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * SHA-1 final digest - */ -void sha1_finish( sha1_context *ctx, unsigned char output[SHA1_BUFFER_SIZE] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_BE( high, msglen, 0 ); - PUT_ULONG_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - sha1_update( ctx, sha1_padding, padn ); - sha1_update( ctx, msglen, 8 ); - - PUT_ULONG_BE( ctx->state[0], output, 0 ); - PUT_ULONG_BE( ctx->state[1], output, 4 ); - PUT_ULONG_BE( ctx->state[2], output, 8 ); - PUT_ULONG_BE( ctx->state[3], output, 12 ); - PUT_ULONG_BE( ctx->state[4], output, 16 ); -} - -/* - * output = SHA-1( input buffer ) - */ -void sha1( unsigned char *input, int ilen, unsigned char output[SHA1_BUFFER_SIZE] ) -{ - sha1_context ctx; - - sha1_starts( &ctx ); - sha1_update( &ctx, input, ilen ); - sha1_finish( &ctx, output ); -} +/* + FIPS-180-1 compliant SHA-1 implementation + + Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + + Copyright (C) 2009 Paul Bakker + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* + The SHA-1 standard was published by NIST in 1993. + + http://www.itl.nist.gov/fipspubs/fip180-1.htm +*/ + +#include "sha1.h" + +#include + +/* + 32-bit integer manipulation macros (big endian) +*/ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + SHA-1 context setup +*/ +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) +{ + unsigned long temp, W[16], A, B, C, D, E; + + GET_ULONG_BE( W[ 0], data, 0 ); + GET_ULONG_BE( W[ 1], data, 4 ); + GET_ULONG_BE( W[ 2], data, 8 ); + GET_ULONG_BE( W[ 3], data, 12 ); + GET_ULONG_BE( W[ 4], data, 16 ); + GET_ULONG_BE( W[ 5], data, 20 ); + GET_ULONG_BE( W[ 6], data, 24 ); + GET_ULONG_BE( W[ 7], data, 28 ); + GET_ULONG_BE( W[ 8], data, 32 ); + GET_ULONG_BE( W[ 9], data, 36 ); + GET_ULONG_BE( W[10], data, 40 ); + GET_ULONG_BE( W[11], data, 44 ); + GET_ULONG_BE( W[12], data, 48 ); + GET_ULONG_BE( W[13], data, 52 ); + GET_ULONG_BE( W[14], data, 56 ); + GET_ULONG_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ + W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* + SHA-1 process buffer +*/ +void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ) +{ + int fill; + unsigned long left; + + if ( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if ( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if ( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + input, fill ); + sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while ( ilen >= 64 ) + { + sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if ( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + input, ilen ); + } +} + +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + SHA-1 final digest +*/ +void sha1_finish( sha1_context *ctx, unsigned char output[SHA1_BUFFER_SIZE] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_BE( high, msglen, 0 ); + PUT_ULONG_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_ULONG_BE( ctx->state[0], output, 0 ); + PUT_ULONG_BE( ctx->state[1], output, 4 ); + PUT_ULONG_BE( ctx->state[2], output, 8 ); + PUT_ULONG_BE( ctx->state[3], output, 12 ); + PUT_ULONG_BE( ctx->state[4], output, 16 ); +} + +/* + output = SHA-1( input buffer ) +*/ +void sha1( unsigned char *input, int ilen, unsigned char output[SHA1_BUFFER_SIZE] ) +{ + sha1_context ctx; + + sha1_starts( &ctx ); + sha1_update( &ctx, input, ilen ); + sha1_finish( &ctx, output ); +} diff --git a/src/Crypto/sha1.h b/src/Crypto/sha1.h index 94080e6..bb8dc0b 100644 --- a/src/Crypto/sha1.h +++ b/src/Crypto/sha1.h @@ -1,101 +1,101 @@ -/** - * \file sha1.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H -#define LWIP_INCLUDED_POLARSSL_SHA1_H - -#include "Portenta_H7_AsyncWebServer_Debug.h" - -#ifdef SHA1_BUFFER_SIZE - #undef SHA1_BUFFER_SIZE -#endif - -#define SHA1_BUFFER_SIZE 20 - -/** - * \brief SHA-1 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[5]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -sha1_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief SHA-1 context setup - * - * \param ctx context to be initialized - */ -void sha1_starts( sha1_context *ctx ); - -/** - * \brief SHA-1 process buffer - * - * \param ctx SHA-1 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ); - -/** - * \brief SHA-1 final digest - * - * \param ctx SHA-1 context - * \param output SHA-1 checksum result - */ -void sha1_finish( sha1_context *ctx, unsigned char output[SHA1_BUFFER_SIZE] ); - -/** - * \brief Output = SHA-1( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-1 checksum result - */ -void sha1( unsigned char *input, int ilen, unsigned char output[SHA1_BUFFER_SIZE] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ +/** + \file sha1.h + + Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + + Copyright (C) 2009 Paul Bakker + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once + +#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H +#define LWIP_INCLUDED_POLARSSL_SHA1_H + +#include "Portenta_H7_AsyncWebServer_Debug.h" + +#ifdef SHA1_BUFFER_SIZE + #undef SHA1_BUFFER_SIZE +#endif + +#define SHA1_BUFFER_SIZE 20 + +/** + \brief SHA-1 context structure +*/ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +sha1_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \brief SHA-1 context setup + + \param ctx context to be initialized +*/ +void sha1_starts( sha1_context *ctx ); + +/** + \brief SHA-1 process buffer + + \param ctx SHA-1 context + \param input buffer holding the data + \param ilen length of the input data +*/ +void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ); + +/** + \brief SHA-1 final digest + + \param ctx SHA-1 context + \param output SHA-1 checksum result +*/ +void sha1_finish( sha1_context *ctx, unsigned char output[SHA1_BUFFER_SIZE] ); + +/** + \brief Output = SHA-1( input buffer ) + + \param input buffer holding the data + \param ilen length of the input data + \param output SHA-1 checksum result +*/ +void sha1( unsigned char *input, int ilen, unsigned char output[SHA1_BUFFER_SIZE] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ diff --git a/src/Portenta_H7_AsyncEventSource.cpp b/src/Portenta_H7_AsyncEventSource.cpp index 9ce39b9..bb42d5a 100644 --- a/src/Portenta_H7_AsyncEventSource.cpp +++ b/src/Portenta_H7_AsyncEventSource.cpp @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncEventSource.cpp - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #if !defined(_PORTENTA_H7_AWS_LOGLEVEL_) @@ -485,7 +486,7 @@ size_t AsyncEventSource::avgPacketsWaiting() const for (const auto &c : _clients) { - if (c->connected()) + if (c->connected()) { aql += c->packetsWaiting(); ++nConnectedClients; diff --git a/src/Portenta_H7_AsyncEventSource.h b/src/Portenta_H7_AsyncEventSource.h index c9c0ffb..f8730a9 100644 --- a/src/Portenta_H7_AsyncEventSource.h +++ b/src/Portenta_H7_AsyncEventSource.h @@ -1,15 +1,15 @@ /************************************************************************************************************* Portenta_H7_AsyncEventSource.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #pragma once diff --git a/src/Portenta_H7_AsyncJson.h b/src/Portenta_H7_AsyncJson.h index d717a05..640f432 100644 --- a/src/Portenta_H7_AsyncJson.h +++ b/src/Portenta_H7_AsyncJson.h @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncJson.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ /* Async Response to use with ArduinoJson and AsyncWebServer @@ -53,7 +54,7 @@ // ... }); server.addHandler(handler); - + */ #pragma once @@ -138,22 +139,23 @@ class AsyncJsonResponse: public AsyncAbstractResponse public: #ifdef ARDUINOJSON_5_COMPATIBILITY - AsyncJsonResponse(bool isArray = false): _isValid {false} + AsyncJsonResponse(bool isArray = false): _isValid {false} { _code = 200; _contentType = JSON_MIMETYPE; - + if (isArray) _root = _jsonBuffer.createArray(); else _root = _jsonBuffer.createObject(); } #else - AsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _jsonBuffer(maxJsonBufferSize), _isValid {false} + AsyncJsonResponse(bool isArray = false, + size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _jsonBuffer(maxJsonBufferSize), _isValid {false} { _code = 200; _contentType = JSON_MIMETYPE; - + if (isArray) _root = _jsonBuffer.createNestedArray(); else @@ -162,18 +164,18 @@ class AsyncJsonResponse: public AsyncAbstractResponse #endif ~AsyncJsonResponse() {} - - JsonVariant & getRoot() + + JsonVariant & getRoot() { return _root; } - - bool _sourceValid() const + + bool _sourceValid() const { return _isValid; } - - size_t setLength() + + size_t setLength() { #ifdef ARDUINOJSON_5_COMPATIBILITY @@ -182,20 +184,20 @@ class AsyncJsonResponse: public AsyncAbstractResponse _contentLength = measureJson(_root); #endif - if (_contentLength) + if (_contentLength) { _isValid = true; } - + return _contentLength; } - size_t getSize() + size_t getSize() { return _jsonBuffer.size(); } - size_t _fillBuffer(uint8_t *data, size_t len) + size_t _fillBuffer(uint8_t *data, size_t len) { ChunkPrint dest(data, _sentLength, len); @@ -210,16 +212,17 @@ class AsyncJsonResponse: public AsyncAbstractResponse ///////////////////////////////////////////////// -class PrettyAsyncJsonResponse: public AsyncJsonResponse +class PrettyAsyncJsonResponse: public AsyncJsonResponse { public: #ifdef ARDUINOJSON_5_COMPATIBILITY PrettyAsyncJsonResponse (bool isArray = false) : AsyncJsonResponse {isArray} {} #else - PrettyAsyncJsonResponse (bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse {isArray, maxJsonBufferSize} {} + PrettyAsyncJsonResponse (bool isArray = false, + size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse {isArray, maxJsonBufferSize} {} #endif - size_t setLength () + size_t setLength () { #ifdef ARDUINOJSON_5_COMPATIBILITY _contentLength = _root.measurePrettyLength (); @@ -227,18 +230,18 @@ class PrettyAsyncJsonResponse: public AsyncJsonResponse _contentLength = measureJsonPretty(_root); #endif - if (_contentLength) + if (_contentLength) { _isValid = true; } - + return _contentLength; } - - size_t _fillBuffer (uint8_t *data, size_t len) + + size_t _fillBuffer (uint8_t *data, size_t len) { ChunkPrint dest (data, _sentLength, len); - + #ifdef ARDUINOJSON_5_COMPATIBILITY _root.prettyPrintTo (dest); #else @@ -253,7 +256,7 @@ class PrettyAsyncJsonResponse: public AsyncJsonResponse typedef std::function ArJsonRequestHandlerFunction; -class AsyncCallbackJsonWebHandler: public AsyncWebHandler +class AsyncCallbackJsonWebHandler: public AsyncWebHandler { private: protected: @@ -261,47 +264,49 @@ class AsyncCallbackJsonWebHandler: public AsyncWebHandler WebRequestMethodComposite _method; ArJsonRequestHandlerFunction _onRequest; size_t _contentLength; - + #ifndef ARDUINOJSON_5_COMPATIBILITY const size_t maxJsonBufferSize; #endif size_t _maxContentLength; - + public: - + #ifdef ARDUINOJSON_5_COMPATIBILITY AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) : _uri(uri), _method(HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #else - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) - : _uri(uri), _method(HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, + size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) + : _uri(uri), _method(HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), + _maxContentLength(16384) {} #endif ///////////////////////////////////////////////// - void setMethod(WebRequestMethodComposite method) + void setMethod(WebRequestMethodComposite method) { _method = method; } ///////////////////////////////////////////////// - - void setMaxContentLength(int maxContentLength) + + void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } ///////////////////////////////////////////////// - - void onRequest(ArJsonRequestHandlerFunction fn) + + void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } ///////////////////////////////////////////////// - virtual bool canHandle(AsyncWebServerRequest *request) override final + virtual bool canHandle(AsyncWebServerRequest *request) override final { if (!_onRequest) return false; @@ -316,68 +321,70 @@ class AsyncCallbackJsonWebHandler: public AsyncWebHandler return false; request->addInterestingHeader("ANY"); - + return true; } ///////////////////////////////////////////////// - virtual void handleRequest(AsyncWebServerRequest *request) override final + virtual void handleRequest(AsyncWebServerRequest *request) override final { - if (_onRequest) + if (_onRequest) { - if (request->_tempObject != NULL) + if (request->_tempObject != NULL) { #ifdef ARDUINOJSON_5_COMPATIBILITY DynamicJsonBuffer jsonBuffer; JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); - - if (json.success()) + + if (json.success()) { #else DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); - - if (!error) + + if (!error) { JsonVariant json = jsonBuffer.as(); #endif _onRequest(request, json); - + return; } } - + request->send(_contentLength > _maxContentLength ? 413 : 400); - } - else + } + else { request->send(500); } } ///////////////////////////////////////////////// - - virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final + + virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, + size_t len, bool final) override final { } ///////////////////////////////////////////////// - - virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final + + virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, + size_t total) override final { - if (_onRequest) + if (_onRequest) { _contentLength = total; - - if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) + + if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { request->_tempObject = malloc(total); } - - if (request->_tempObject != NULL) + + if (request->_tempObject != NULL) { memcpy((uint8_t*)(request->_tempObject) + index, data, len); } @@ -385,14 +392,14 @@ class AsyncCallbackJsonWebHandler: public AsyncWebHandler } ///////////////////////////////////////////////// - - virtual bool isRequestHandlerTrivial() override final + + virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } ///////////////////////////////////////////////// - + }; ///////////////////////////////////////////////// diff --git a/src/Portenta_H7_AsyncWebAuthentication.cpp b/src/Portenta_H7_AsyncWebAuthentication.cpp index 0d09ae7..07d7f81 100644 --- a/src/Portenta_H7_AsyncWebAuthentication.cpp +++ b/src/Portenta_H7_AsyncWebAuthentication.cpp @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebAuthentication.cpp - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #if !defined(_PORTENTA_H7_AWS_LOGLEVEL_) @@ -41,69 +42,69 @@ // Basic Auth hash = base64("username:password") -bool checkBasicAuthentication(const char * hash, const char * username, const char * password) +bool checkBasicAuthentication(const char * hash, const char * username, const char * password) { if (username == NULL || password == NULL || hash == NULL) { AWS_LOGDEBUG("checkBasicAuthentication: Fail: NULL username/password/hash"); - + return false; } size_t toencodeLen = strlen(username) + strlen(password) + 1; size_t encodedLen = base64_encode_expected_len(toencodeLen); - + if (strlen(hash) != encodedLen) { AWS_LOGDEBUG3("checkBasicAuthentication: Fail: strlen(hash) = ", strlen(hash), " != encodedLen = ", encodedLen ); - + return false; } char *toencode = new char[toencodeLen + 1]; - - if (toencode == NULL) + + if (toencode == NULL) { AWS_LOGDEBUG("checkBasicAuthentication: NULL toencode"); - + return false; } - + char *encoded = new char[base64_encode_expected_len(toencodeLen) + 1]; - - if (encoded == NULL) + + if (encoded == NULL) { AWS_LOGDEBUG("checkBasicAuthentication: NULL encoded"); - + delete[] toencode; - + return false; } - + sprintf(toencode, "%s:%s", username, password); - - if (base64_encode_chars(toencode, toencodeLen, encoded) > 0 && memcmp(hash, encoded, encodedLen) == 0) + + if (base64_encode_chars(toencode, toencodeLen, encoded) > 0 && memcmp(hash, encoded, encodedLen) == 0) { AWS_LOGDEBUG("checkBasicAuthentication: OK"); - + delete[] toencode; delete[] encoded; - + return true; } - + AWS_LOGDEBUG("checkBasicAuthentication: Failed"); - + delete[] toencode; delete[] encoded; - + return false; } ///////////////////////////////////////////////// -static bool getMD5(uint8_t * data, uint16_t len, char * output) -{ +static bool getMD5(uint8_t * data, uint16_t len, char * output) +{ //33 bytes or more // For STM32 @@ -111,141 +112,141 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output) uint8_t i; uint8_t * _buf = (uint8_t*) malloc(16); - + if (_buf == NULL) { AWS_LOGDEBUG("getMD5: Can malloc _buf"); - + return false; } - + memset(_buf, 0x00, 16); // For STM32 md5_starts(&_ctx); md5_update(&_ctx, data, len); md5_finish(&_ctx, _buf); - - for (i = 0; i < 16; i++) + + for (i = 0; i < 16; i++) { sprintf(output + (i * 2), "%02x", _buf[i]); } - + free(_buf); - + AWS_LOGDEBUG("getMD5: Success"); - + return true; } ///////////////////////////////////////////////// -static String genRandomMD5() +static String genRandomMD5() { uint32_t r = rand(); char * out = (char*) malloc(33); - + if (out == NULL || !getMD5((uint8_t*)(&r), 4, out)) return ""; - + String res = String(out); free(out); - + AWS_LOGDEBUG1("genRandomMD5: res = ", res); - + return res; } ///////////////////////////////////////////////// -static String stringMD5(const String& in) +static String stringMD5(const String& in) { char * out = (char*) malloc(33); - + if (out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) return ""; - + String res = String(out); free(out); - + AWS_LOGDEBUG1("stringMD5: res = ", res); - + return res; } ///////////////////////////////////////////////// -String generateDigestHash(const char * username, const char * password, const char * realm) +String generateDigestHash(const char * username, const char * password, const char * realm) { - if (username == NULL || password == NULL || realm == NULL) + if (username == NULL || password == NULL || realm == NULL) { return ""; } - + char * out = (char*) malloc(33); String res = String(username); - + res.concat(":"); res.concat(realm); res.concat(":"); - + String in = res; - + in.concat(password); - + if (out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) return ""; - + res.concat(out); free(out); - + AWS_LOGDEBUG1("generateDigestHash: res = ", res); - + return res; } ///////////////////////////////////////////////// -String requestDigestAuthentication(const char * realm) +String requestDigestAuthentication(const char * realm) { String header = "realm=\""; - + if (realm == NULL) header.concat("asyncesp"); else header.concat(realm); - + header.concat( "\", qop=\"auth\", nonce=\""); header.concat(genRandomMD5()); header.concat("\", opaque=\""); header.concat(genRandomMD5()); header.concat("\""); - + AWS_LOGDEBUG1("requestDigestAuthentication: header = ", header); - + return header; } ///////////////////////////////////////////////// -bool checkDigestAuthentication(const char * header, const char * method, const char * username, const char * password, - const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri) +bool checkDigestAuthentication(const char * header, const char * method, const char * username, const char * password, + const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri) { - if (username == NULL || password == NULL || header == NULL || method == NULL) + if (username == NULL || password == NULL || header == NULL || method == NULL) { AWS_LOGDEBUG("AUTH FAIL: missing required fields"); - + return false; } String myHeader = String(header); int nextBreak = myHeader.indexOf(","); - - if (nextBreak < 0) + + if (nextBreak < 0) { AWS_LOGDEBUG("AUTH FAIL: no variables"); - + return false; } @@ -259,98 +260,98 @@ bool checkDigestAuthentication(const char * header, const char * method, const c String myCnonce = String(); myHeader += ", "; - - do + + do { String avLine = myHeader.substring(0, nextBreak); - + avLine.trim(); myHeader = myHeader.substring(nextBreak + 1); nextBreak = myHeader.indexOf(","); int eqSign = avLine.indexOf("="); - - if (eqSign < 0) + + if (eqSign < 0) { AWS_LOGDEBUG("AUTH FAIL: no = sign"); - + return false; } - + String varName = avLine.substring(0, eqSign); avLine = avLine.substring(eqSign + 1); - - if (avLine.startsWith("\"")) + + if (avLine.startsWith("\"")) { avLine = avLine.substring(1, avLine.length() - 1); } - if (varName.equals("username")) + if (varName.equals("username")) { - if (!avLine.equals(username)) + if (!avLine.equals(username)) { AWS_LOGDEBUG("AUTH FAIL: username"); - + return false; } - + myUsername = avLine; - } - else if (varName.equals("realm")) + } + else if (varName.equals("realm")) { - if (realm != NULL && !avLine.equals(realm)) + if (realm != NULL && !avLine.equals(realm)) { AWS_LOGDEBUG("AUTH FAIL: realm"); - + return false; } - + myRealm = avLine; - } - else if (varName.equals("nonce")) + } + else if (varName.equals("nonce")) { - if (nonce != NULL && !avLine.equals(nonce)) + if (nonce != NULL && !avLine.equals(nonce)) { AWS_LOGDEBUG("AUTH FAIL: nonce"); - + return false; } - + myNonce = avLine; - } - else if (varName.equals("opaque")) + } + else if (varName.equals("opaque")) { - if (opaque != NULL && !avLine.equals(opaque)) + if (opaque != NULL && !avLine.equals(opaque)) { AWS_LOGDEBUG("AUTH FAIL: opaque"); - + return false; } - } - else if (varName.equals("uri")) + } + else if (varName.equals("uri")) { - if (uri != NULL && !avLine.equals(uri)) + if (uri != NULL && !avLine.equals(uri)) { AWS_LOGDEBUG("AUTH FAIL: uri"); - + return false; } - + myUri = avLine; - } - else if (varName.equals("response")) + } + else if (varName.equals("response")) { myResponse = avLine; - } - else if (varName.equals("qop")) + } + else if (varName.equals("qop")) { myQop = avLine; - } - else if (varName.equals("nc")) + } + else if (varName.equals("nc")) { myNc = avLine; } - else if (varName.equals("cnonce")) + else if (varName.equals("cnonce")) { myCnonce = avLine; } @@ -360,15 +361,15 @@ bool checkDigestAuthentication(const char * header, const char * method, const c String ha2 = String(method) + ":" + myUri; String response = ha1 + ":" + myNonce + ":" + myNc + ":" + myCnonce + ":" + myQop + ":" + stringMD5(ha2); - if (myResponse.equals(stringMD5(response))) + if (myResponse.equals(stringMD5(response))) { AWS_LOGDEBUG("AUTH SUCCESS"); - + return true; } AWS_LOGDEBUG("AUTH FAIL: password"); - + return false; } diff --git a/src/Portenta_H7_AsyncWebAuthentication.h b/src/Portenta_H7_AsyncWebAuthentication.h index 0554489..d1f767a 100644 --- a/src/Portenta_H7_AsyncWebAuthentication.h +++ b/src/Portenta_H7_AsyncWebAuthentication.h @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebAuthentication.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #pragma once @@ -35,7 +36,8 @@ bool checkBasicAuthentication(const char * header, const char * username, const char * password); String requestDigestAuthentication(const char * realm); -bool checkDigestAuthentication(const char * header, const char * method, const char * username, const char * password, const char * realm, +bool checkDigestAuthentication(const char * header, const char * method, const char * username, const char * password, + const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri); //for storing hashed versions on the device that can be authenticated against diff --git a/src/Portenta_H7_AsyncWebHandlerImpl.h b/src/Portenta_H7_AsyncWebHandlerImpl.h index 0c6ed5a..3d77e28 100644 --- a/src/Portenta_H7_AsyncWebHandlerImpl.h +++ b/src/Portenta_H7_AsyncWebHandlerImpl.h @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebHandlerImpl.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #pragma once @@ -31,7 +32,7 @@ #include #ifdef ASYNCWEBSERVER_REGEX -#include + #include #endif #include "stddef.h" @@ -71,7 +72,7 @@ class AsyncStaticWebHandler: public AsyncWebHandler AsyncStaticWebHandler& setTemplateProcessor(AwsTemplateProcessor newCallback) { _callback = newCallback; - + return *this; } }; @@ -90,7 +91,8 @@ class AsyncCallbackWebHandler: public AsyncWebHandler bool _isRegex; public: - AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {} + AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), + _isRegex(false) {} ///////////////////////////////////////////////// @@ -108,7 +110,7 @@ class AsyncCallbackWebHandler: public AsyncWebHandler } ///////////////////////////////////////////////// - + void onRequest(ArRequestHandlerFunction fn) { _onRequest = fn; @@ -139,6 +141,7 @@ class AsyncCallbackWebHandler: public AsyncWebHandler return false; #ifdef ASYNCWEBSERVER_REGEX + if (_isRegex) { std::regex pattern(_uri.c_str()); @@ -188,7 +191,8 @@ class AsyncCallbackWebHandler: public AsyncWebHandler ///////////////////////////////////////////////// - virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final + virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, + size_t total) override final { if (_onBody) _onBody(request, data, len, index, total); diff --git a/src/Portenta_H7_AsyncWebHandlers.cpp b/src/Portenta_H7_AsyncWebHandlers.cpp index a28beca..fdec269 100644 --- a/src/Portenta_H7_AsyncWebHandlers.cpp +++ b/src/Portenta_H7_AsyncWebHandlers.cpp @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebHandlers.cpp - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #if !defined(_PORTENTA_H7_AWS_LOGLEVEL_) @@ -66,7 +67,7 @@ AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, /*FS& fs,*/ const AsyncStaticWebHandler& AsyncStaticWebHandler::setIsDir(bool isDir) { _isDir = isDir; - + return *this; } diff --git a/src/Portenta_H7_AsyncWebRequest.cpp b/src/Portenta_H7_AsyncWebRequest.cpp index 250aff7..5d50177 100644 --- a/src/Portenta_H7_AsyncWebRequest.cpp +++ b/src/Portenta_H7_AsyncWebRequest.cpp @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebRequest.cpp - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #if !defined(_PORTENTA_H7_AWS_LOGLEVEL_) @@ -256,7 +257,8 @@ void AsyncWebServerRequest::_onData(void *buf, size_t len) if (_handler) _handler->handleRequest(this); - else send(501); + else + send(501); } } @@ -862,7 +864,8 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { if (data == '-' && (_contentLength - _parsedLength - 4) != 0) { - AWS_LOGDEBUG1("ERROR: The parser got to the end of the POST but is expecting more bytes =", (_contentLength - _parsedLength - 4)); + AWS_LOGDEBUG1("ERROR: The parser got to the end of the POST but is expecting more bytes =", + (_contentLength - _parsedLength - 4)); AWS_LOGDEBUG("Drop an issue so we can have more info on the matter!"); _contentLength = _parsedLength + 4;//lets close the request gracefully @@ -1112,28 +1115,32 @@ AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(int code, const St ///////////////////////////////////////////////// -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(int code, const String& contentType, const String& content) +AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(int code, const String& contentType, + const String& content) { return new AsyncBasicResponse(code, contentType, content); } ///////////////////////////////////////////////// -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback) +AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(Stream &stream, const String& contentType, size_t len, + AwsTemplateProcessor callback) { return new AsyncStreamResponse(stream, contentType, len, callback); } ///////////////////////////////////////////////// -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) +AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(const String& contentType, size_t len, + AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { return new AsyncCallbackResponse(contentType, len, callback, templateCallback); } ///////////////////////////////////////////////// -AsyncWebServerResponse * AsyncWebServerRequest::beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) +AsyncWebServerResponse * AsyncWebServerRequest::beginChunkedResponse(const String& contentType, + AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { if (_version) return new AsyncChunkedResponse(contentType, callback, templateCallback); @@ -1178,14 +1185,16 @@ void AsyncWebServerRequest::send(Stream &stream, const String& contentType, size ///////////////////////////////////////////////// -void AsyncWebServerRequest::send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) +void AsyncWebServerRequest::send(const String& contentType, size_t len, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback) { send(beginResponse(contentType, len, callback, templateCallback)); } ///////////////////////////////////////////////// -void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) +void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback) { send(beginChunkedResponse(contentType, callback, templateCallback)); } @@ -1201,7 +1210,8 @@ void AsyncWebServerRequest::redirect(const String& url) ///////////////////////////////////////////////// -bool AsyncWebServerRequest::authenticate(const char * username, const char * password, const char * realm, bool passwordIsHash) +bool AsyncWebServerRequest::authenticate(const char * username, const char * password, const char * realm, + bool passwordIsHash) { AWS_LOGDEBUG1("AsyncWebServerRequest::authenticate: auth-len =", _authorization.length()); @@ -1211,7 +1221,8 @@ bool AsyncWebServerRequest::authenticate(const char * username, const char * pas { AWS_LOGDEBUG("AsyncWebServerRequest::authenticate: _isDigest"); - return checkDigestAuthentication(_authorization.c_str(), methodToString(), username, password, realm, passwordIsHash, NULL, NULL, NULL); + return checkDigestAuthentication(_authorization.c_str(), methodToString(), username, password, realm, passwordIsHash, + NULL, NULL, NULL); } else if (!passwordIsHash) { @@ -1257,7 +1268,8 @@ bool AsyncWebServerRequest::authenticate(const char * hash) String realm = hStr.substring(0, separator); hStr = hStr.substring(separator + 1); - return checkDigestAuthentication(_authorization.c_str(), methodToString(), username.c_str(), hStr.c_str(), realm.c_str(), true, NULL, NULL, NULL); + return checkDigestAuthentication(_authorization.c_str(), methodToString(), username.c_str(), hStr.c_str(), + realm.c_str(), true, NULL, NULL, NULL); } return (_authorization.equals(hash)); @@ -1438,14 +1450,19 @@ const char *AsyncWebServerRequest::requestedConnTypeToString() const { case RCT_NOT_USED: return "RCT_NOT_USED"; + case RCT_DEFAULT: return "RCT_DEFAULT"; + case RCT_HTTP: return "RCT_HTTP"; + case RCT_WS: return "RCT_WS"; + case RCT_EVENT: return "RCT_EVENT"; + default: return "ERROR"; } @@ -1453,7 +1470,8 @@ const char *AsyncWebServerRequest::requestedConnTypeToString() const ///////////////////////////////////////////////// -bool AsyncWebServerRequest::isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2, RequestedConnectionType erct3) +bool AsyncWebServerRequest::isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2, + RequestedConnectionType erct3) { bool res = false; diff --git a/src/Portenta_H7_AsyncWebResponseImpl.h b/src/Portenta_H7_AsyncWebResponseImpl.h index 0d0d7f9..81926a6 100644 --- a/src/Portenta_H7_AsyncWebResponseImpl.h +++ b/src/Portenta_H7_AsyncWebResponseImpl.h @@ -2,14 +2,14 @@ Portenta_H7_AsyncWebResponseImpl.h For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - Version: 1.4.1 + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #pragma once @@ -97,7 +98,7 @@ class AsyncAbstractResponse: public AsyncWebServerResponse ///////////////////////////////////////////////// #ifndef TEMPLATE_PLACEHOLDER -#define TEMPLATE_PLACEHOLDER '%' + #define TEMPLATE_PLACEHOLDER '%' #endif #define TEMPLATE_PARAM_NAME_LENGTH 32 @@ -129,7 +130,8 @@ class AsyncCallbackResponse: public AsyncAbstractResponse size_t _filledLength; public: - AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback = nullptr); bool _sourceValid() const { @@ -148,7 +150,8 @@ class AsyncChunkedResponse: public AsyncAbstractResponse size_t _filledLength; public: - AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback = nullptr); bool _sourceValid() const { diff --git a/src/Portenta_H7_AsyncWebResponses.cpp b/src/Portenta_H7_AsyncWebResponses.cpp index df09018..230de88 100644 --- a/src/Portenta_H7_AsyncWebResponses.cpp +++ b/src/Portenta_H7_AsyncWebResponses.cpp @@ -2,14 +2,14 @@ Portenta_H7_AsyncWebResponses.cpp For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - Version: 1.4.1 + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #if !defined(_PORTENTA_H7_AWS_LOGLEVEL_) @@ -57,47 +58,128 @@ const char* AsyncWebServerResponse::_responseCodeToString(int code) { switch (code) { - case 100: return "Continue"; - case 101: return "Switching Protocols"; - case 200: return "OK"; - case 201: return "Created"; - case 202: return "Accepted"; - case 203: return "Non-Authoritative Information"; - case 204: return "No Content"; - case 205: return "Reset Content"; - case 206: return "Partial Content"; - case 300: return "Multiple Choices"; - case 301: return "Moved Permanently"; - case 302: return "Found"; - case 303: return "See Other"; - case 304: return "Not Modified"; - case 305: return "Use Proxy"; - case 307: return "Temporary Redirect"; - case 400: return "Bad Request"; - case 401: return "Unauthorized"; - case 402: return "Payment Required"; - case 403: return "Forbidden"; - case 404: return "Not Found"; - case 405: return "Method Not Allowed"; - case 406: return "Not Acceptable"; - case 407: return "Proxy Authentication Required"; - case 408: return "Request Time-out"; - case 409: return "Conflict"; - case 410: return "Gone"; - case 411: return "Length Required"; - case 412: return "Precondition Failed"; - case 413: return "Request Entity Too Large"; - case 414: return "Request-URI Too Large"; - case 415: return "Unsupported Media Type"; - case 416: return "Requested range not satisfiable"; - case 417: return "Expectation Failed"; - case 500: return "Internal Server Error"; - case 501: return "Not Implemented"; - case 502: return "Bad Gateway"; - case 503: return "Service Unavailable"; - case 504: return "Gateway Time-out"; - case 505: return "HTTP Version not supported"; - default: return ""; + case 100: + return "Continue"; + + case 101: + return "Switching Protocols"; + + case 200: + return "OK"; + + case 201: + return "Created"; + + case 202: + return "Accepted"; + + case 203: + return "Non-Authoritative Information"; + + case 204: + return "No Content"; + + case 205: + return "Reset Content"; + + case 206: + return "Partial Content"; + + case 300: + return "Multiple Choices"; + + case 301: + return "Moved Permanently"; + + case 302: + return "Found"; + + case 303: + return "See Other"; + + case 304: + return "Not Modified"; + + case 305: + return "Use Proxy"; + + case 307: + return "Temporary Redirect"; + + case 400: + return "Bad Request"; + + case 401: + return "Unauthorized"; + + case 402: + return "Payment Required"; + + case 403: + return "Forbidden"; + + case 404: + return "Not Found"; + + case 405: + return "Method Not Allowed"; + + case 406: + return "Not Acceptable"; + + case 407: + return "Proxy Authentication Required"; + + case 408: + return "Request Time-out"; + + case 409: + return "Conflict"; + + case 410: + return "Gone"; + + case 411: + return "Length Required"; + + case 412: + return "Precondition Failed"; + + case 413: + return "Request Entity Too Large"; + + case 414: + return "Request-URI Too Large"; + + case 415: + return "Unsupported Media Type"; + + case 416: + return "Requested range not satisfiable"; + + case 417: + return "Expectation Failed"; + + case 500: + return "Internal Server Error"; + + case 501: + return "Not Implemented"; + + case 502: + return "Bad Gateway"; + + case 503: + return "Service Unavailable"; + + case 504: + return "Gateway Time-out"; + + case 505: + return "HTTP Version not supported"; + + default: + return ""; } } @@ -169,7 +251,9 @@ String AsyncWebServerResponse::_assembleHead(uint8_t version) } String out = String(); - int bufSize = 300; + +#define bufSize 320 + char buf[bufSize]; snprintf(buf, bufSize, "HTTP/1.%d %d %s\r\n", version, _code, _responseCodeToString(_code)); @@ -324,7 +408,8 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request) if (_contentCstr) { - _content = String(_contentCstr); // short _contentCstr - so just send as Arduino String - not much of a penalty - fall into below + _content = String( + _contentCstr); // short _contentCstr - so just send as Arduino String - not much of a penalty - fall into below } out += _content; @@ -408,7 +493,7 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request) _content = out + _content; _contentLength += outLen; } - + _state = RESPONSE_CONTENT; } @@ -497,7 +582,7 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint s[space] = '\0'; out = String(s); _contentCstr += space; - + free(s); } else @@ -529,7 +614,8 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint } } - AWS_LOGDEBUG3("AsyncBasicResponse::_ack : Post_ack, _contentLength =", _contentLength, ", _contentCstr =", _contentCstr); + AWS_LOGDEBUG3("AsyncBasicResponse::_ack : Post_ack, _contentLength =", _contentLength, ", _contentCstr =", + _contentCstr); return 0; } @@ -681,7 +767,8 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u _writtenLength += request->client()->write((const char*)buf, outLen); } - if (_chunked) { + if (_chunked) + { _sentLength += readLen; } else @@ -747,10 +834,12 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size // Search for template placeholders uint8_t* pTemplateStart = data; - while ((pTemplateStart < &data[len]) && (pTemplateStart = (uint8_t*) memchr(pTemplateStart, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart + 1))) + while ((pTemplateStart < &data[len]) + && (pTemplateStart = (uint8_t*) memchr(pTemplateStart, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart + 1))) { // data[0] ... data[len - 1] - uint8_t* pTemplateEnd = (pTemplateStart < &data[len - 1]) ? (uint8_t*) memchr(pTemplateStart + 1, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart) : nullptr; + uint8_t* pTemplateEnd = (pTemplateStart < &data[len - 1]) ? (uint8_t*) memchr(pTemplateStart + 1, TEMPLATE_PLACEHOLDER, + &data[len - 1] - pTemplateStart) : nullptr; // temporary buffer to hold parameter name uint8_t buf[TEMPLATE_PARAM_NAME_LENGTH + 1]; @@ -781,7 +870,8 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size { // closing placeholder not found, check if it's in the remaining file data memcpy(buf, pTemplateStart + 1, &data[len - 1] - pTemplateStart); - const size_t readFromCacheOrContent = _readDataFromCacheOrContent(buf + (&data[len - 1] - pTemplateStart), TEMPLATE_PARAM_NAME_LENGTH + 2 - (&data[len - 1] - pTemplateStart + 1)); + const size_t readFromCacheOrContent = _readDataFromCacheOrContent(buf + (&data[len - 1] - pTemplateStart), + TEMPLATE_PARAM_NAME_LENGTH + 2 - (&data[len - 1] - pTemplateStart + 1)); if (readFromCacheOrContent) { @@ -799,7 +889,8 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size else // closing placeholder not found in file data, store found percent symbol as is and advance to the next position { // but first, store read file data in cache - _cache.insert(_cache.begin(), buf + (&data[len - 1] - pTemplateStart), buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent); + _cache.insert(_cache.begin(), buf + (&data[len - 1] - pTemplateStart), + buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent); ++pTemplateStart; } } @@ -823,7 +914,8 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size // make room for param value // 1. move extra data to cache if parameter value is longer than placeholder AND if there is no room to store - if ((pTemplateEnd + 1 < pTemplateStart + numBytesCopied) && (originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1) < len)) + if ((pTemplateEnd + 1 < pTemplateStart + numBytesCopied) + && (originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1) < len)) { _cache.insert(_cache.begin(), &data[originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1)], &data[len]); @@ -872,7 +964,8 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size Stream Response * */ -AsyncStreamResponse::AsyncStreamResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback): AsyncAbstractResponse(callback) +AsyncStreamResponse::AsyncStreamResponse(Stream &stream, const String& contentType, size_t len, + AwsTemplateProcessor callback): AsyncAbstractResponse(callback) { _code = 200; _content = &stream; @@ -900,7 +993,8 @@ size_t AsyncStreamResponse::_fillBuffer(uint8_t *data, size_t len) Callback Response * */ -AsyncCallbackResponse::AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) +AsyncCallbackResponse::AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback) : AsyncAbstractResponse(templateCallback) { _code = 200; @@ -934,7 +1028,8 @@ size_t AsyncCallbackResponse::_fillBuffer(uint8_t *data, size_t len) Chunked Response * */ -AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback): AsyncAbstractResponse(processorCallback) +AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, + AwsTemplateProcessor processorCallback): AsyncAbstractResponse(processorCallback) { _code = 200; _content = callback; diff --git a/src/Portenta_H7_AsyncWebServer.cpp b/src/Portenta_H7_AsyncWebServer.cpp index 5101bd0..b37a484 100644 --- a/src/Portenta_H7_AsyncWebServer.cpp +++ b/src/Portenta_H7_AsyncWebServer.cpp @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebServer.cpp - Dead simple AsyncWebServer for STM32 LAN8720 or built-in LAN8742A Ethernet - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #if !defined(_PORTENTA_H7_AWS_LOGLEVEL_) @@ -58,7 +59,7 @@ AsyncWebServer::AsyncWebServer(uint16_t port) //c->setRxTimeout(3); c->setRxTimeout(0); ////// - + AsyncWebServerRequest *r = new AsyncWebServerRequest((AsyncWebServer*)s, c); if (r == NULL) @@ -155,7 +156,7 @@ void AsyncWebServer::beginSecure(const char *cert, const char *key, const char * ///////////////////////////////////////////////// void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest *request) -{ +{ delete request; } @@ -182,20 +183,21 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request) if (h->filter(request) && h->canHandle(request)) { request->setHandler(h); - + return; } } request->addInterestingHeader("ANY"); - + request->setHandler(NULL); } ///////////////////////////////////////////////// -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, - ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody) +AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, + ArRequestHandlerFunction onRequest, + ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody) { AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); @@ -211,7 +213,8 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodCom ///////////////////////////////////////////////// -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload) +AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, + ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload) { AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); @@ -225,7 +228,8 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodCom ///////////////////////////////////////////////// -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest) +AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, + ArRequestHandlerFunction onRequest) { AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); diff --git a/src/Portenta_H7_AsyncWebServer.h b/src/Portenta_H7_AsyncWebServer.h index d82df82..220979f 100644 --- a/src/Portenta_H7_AsyncWebServer.h +++ b/src/Portenta_H7_AsyncWebServer.h @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebServer.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,8 +21,9 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ - + #ifndef _PORTENTA_H7_ASYNC_WEBSERVER_H_ #define _PORTENTA_H7_ASYNC_WEBSERVER_H_ @@ -31,17 +32,17 @@ #else -#error For Portenta_H7 only + #error For Portenta_H7 only #endif -#define PORTENTA_H7_ASYNC_WEBSERVER_VERSION "Portenta_H7_AsyncWebServer v1.4.1" +#define PORTENTA_H7_ASYNC_WEBSERVER_VERSION "Portenta_H7_AsyncWebServer v1.4.2" #define PORTENTA_H7_ASYNC_WEBSERVER_VERSION_MAJOR 1 #define PORTENTA_H7_ASYNC_WEBSERVER_VERSION_MINOR 4 -#define PORTENTA_H7_ASYNC_WEBSERVER_VERSION_PATCH 1 +#define PORTENTA_H7_ASYNC_WEBSERVER_VERSION_PATCH 2 -#define PORTENTA_H7_ASYNC_WEBSERVER_VERSION_INT 1004001 +#define PORTENTA_H7_ASYNC_WEBSERVER_VERSION_INT 1004002 #ifndef PORTENTA_H7_AWS_UNUSED #define PORTENTA_H7_AWS_UNUSED(x) (void)(x) @@ -78,17 +79,17 @@ class AsyncCallbackWebHandler; class AsyncResponseStream; #ifndef WEBSERVER_H - typedef enum - { - HTTP_GET = 0b00000001, - HTTP_POST = 0b00000010, - HTTP_DELETE = 0b00000100, - HTTP_PUT = 0b00001000, - HTTP_PATCH = 0b00010000, - HTTP_HEAD = 0b00100000, - HTTP_OPTIONS = 0b01000000, - HTTP_ANY = 0b01111111, - } WebRequestMethod; +typedef enum +{ + HTTP_GET = 0b00000001, + HTTP_POST = 0b00000010, + HTTP_DELETE = 0b00000100, + HTTP_PUT = 0b00001000, + HTTP_PATCH = 0b00010000, + HTTP_HEAD = 0b00100000, + HTTP_OPTIONS = 0b01000000, + HTTP_ANY = 0b01111111, +} WebRequestMethod; #endif //if this value is returned when asked for data, packet will not be sent and you will be asked for data again @@ -112,7 +113,8 @@ class AsyncWebParameter public: - AsyncWebParameter(const String& name, const String& value, bool form = false, bool file = false, size_t size = 0): _name(name), _value(value), _size(size), _isForm(form), _isFile(file) {} + AsyncWebParameter(const String& name, const String& value, bool form = false, bool file = false, + size_t size = 0): _name(name), _value(value), _size(size), _isForm(form), _isFile(file) {} const String& name() const { @@ -321,7 +323,8 @@ class AsyncWebServerRequest return _reqconntype; } - bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED); + bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, + RequestedConnectionType erct3 = RCT_NOT_USED); void onDisconnect (ArDisconnectHandler fn); //hash is the string representation of: @@ -345,15 +348,20 @@ class AsyncWebServerRequest void send(int code, const String& contentType, const char *content, bool nonDetructiveSend = true); // RSMOD void send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); - void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); - void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + void send(const String& contentType, size_t len, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback = nullptr); + void sendChunked(const String& contentType, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback = nullptr); AsyncWebServerResponse *beginResponse(int code, const String& contentType = String(), const String& content = String()); AsyncWebServerResponse *beginResponse(int code, const String& contentType, const char * content = nullptr); // RSMOD - AsyncWebServerResponse *beginResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse *beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); - AsyncWebServerResponse *beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncWebServerResponse *beginResponse(Stream &stream, const String& contentType, size_t len, + AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse *beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback = nullptr); + AsyncWebServerResponse *beginChunkedResponse(const String& contentType, AwsResponseFiller callback, + AwsTemplateProcessor templateCallback = nullptr); AsyncResponseStream *beginResponseStream(const String& contentType, size_t bufferSize = 1460); size_t headers() const; // get header count @@ -363,7 +371,7 @@ class AsyncWebServerRequest AsyncWebHeader* getHeader(size_t num) const; size_t params() const; // get arguments count - bool hasParam(const String& name, bool post = false , bool file = false) const; + bool hasParam(const String& name, bool post = false, bool file = false) const; AsyncWebParameter* getParam(const String& name, bool post = false, bool file = false) const; AsyncWebParameter* getParam(size_t num) const; @@ -494,8 +502,11 @@ class AsyncWebHandler } virtual void handleRequest(AsyncWebServerRequest *request __attribute__((unused))) {} - virtual void handleUpload(AsyncWebServerRequest *request __attribute__((unused)), const String& filename __attribute__((unused)), size_t index __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))) {} - virtual void handleBody(AsyncWebServerRequest *request __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))) {} + virtual void handleUpload(AsyncWebServerRequest *request __attribute__((unused)), + const String& filename __attribute__((unused)), size_t index __attribute__((unused)), + uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))) {} + virtual void handleBody(AsyncWebServerRequest *request __attribute__((unused)), uint8_t *data __attribute__((unused)), + size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))) {} virtual bool isRequestHandlerTrivial() { @@ -549,8 +560,10 @@ class AsyncWebServerResponse * */ typedef std::function ArRequestHandlerFunction; -typedef std::function ArUploadHandlerFunction; -typedef std::function ArBodyHandlerFunction; +typedef std::function +ArUploadHandlerFunction; +typedef std::function +ArBodyHandlerFunction; class AsyncWebServer { @@ -581,11 +594,14 @@ class AsyncWebServer AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest); AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest); - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload); - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody); + AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, + ArUploadHandlerFunction onUpload); + AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, + ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody); void onNotFound(ArRequestHandlerFunction fn); //called when handler is not assigned - void onRequestBody(ArBodyHandlerFunction fn); //handle posts with plain body content (JSON often transmitted this way as a request) + void onRequestBody(ArBodyHandlerFunction + fn); //handle posts with plain body content (JSON often transmitted this way as a request) void reset(); //remove all writers and handlers, with onNotFound/onFileUpload/onRequestBody diff --git a/src/Portenta_H7_AsyncWebServer_Debug.h b/src/Portenta_H7_AsyncWebServer_Debug.h index edd2c15..a8a40fc 100644 --- a/src/Portenta_H7_AsyncWebServer_Debug.h +++ b/src/Portenta_H7_AsyncWebServer_Debug.h @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebServer_Debug.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #pragma once diff --git a/src/Portenta_H7_AsyncWebSocket.cpp b/src/Portenta_H7_AsyncWebSocket.cpp index 3fe4047..4bca022 100644 --- a/src/Portenta_H7_AsyncWebSocket.cpp +++ b/src/Portenta_H7_AsyncWebSocket.cpp @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebSocket.cpp - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #include "Arduino.h" @@ -125,7 +126,7 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool AWS_LOGDEBUG1("Error adding header, bytes =", headLen); free(buf); - + return 0; } @@ -152,7 +153,7 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool if (!client->send()) { AWS_LOGDEBUG1("Error sending frame: bytes =", headLen + len); - + return 0; } @@ -540,7 +541,7 @@ size_t AsyncWebSocketMultiMessage::send(AsyncClient *client) if (_sent == _len) { _status = WS_MSG_SENT; - + return 0; } @@ -578,6 +579,7 @@ size_t AsyncWebSocketMultiMessage::send(AsyncClient *client) _sent -= (toSend - sent); _ack -= (toSend - sent); } + AWS_LOGDEBUG3("Send OK: _sent = ", _sent, "= sent =", sent); return sent; @@ -596,7 +598,8 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async { delete c; })) -, _messageQueue(LinkedList([](AsyncWebSocketMessage *m) { +, _messageQueue(LinkedList([](AsyncWebSocketMessage *m) +{ delete m; })) , _tempObject(NULL) @@ -613,14 +616,14 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async _client->onError([](void *r, AsyncClient * c, int8_t error) { PORTENTA_H7_AWS_UNUSED(c); - + ((AsyncWebSocketClient*)(r))->_onError(error); }, this); _client->onAck([](void *r, AsyncClient * c, size_t len, uint32_t time) { PORTENTA_H7_AWS_UNUSED(c); - + ((AsyncWebSocketClient*)(r))->_onAck(len, time); }, this); @@ -633,21 +636,21 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async _client->onTimeout([](void *r, AsyncClient * c, uint32_t time) { PORTENTA_H7_AWS_UNUSED(c); - + ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this); _client->onData([](void *r, AsyncClient * c, void *buf, size_t len) { PORTENTA_H7_AWS_UNUSED(c); - + ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); _client->onPoll([](void *r, AsyncClient * c) { PORTENTA_H7_AWS_UNUSED(c); - + ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); @@ -688,6 +691,7 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) return; } + _controlQueue.remove(head); } } @@ -705,10 +709,12 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) void AsyncWebSocketClient::_onPoll() { - if (_client->canSend() && (!_controlQueue.isEmpty() || !_messageQueue.isEmpty())) { + if (_client->canSend() && (!_controlQueue.isEmpty() || !_messageQueue.isEmpty())) + { _runQueue(); } - else if (_keepAlivePeriod > 0 && _controlQueue.isEmpty() && _messageQueue.isEmpty() && (millis() - _lastMessageTime) >= _keepAlivePeriod) + else if (_keepAlivePeriod > 0 && _controlQueue.isEmpty() && _messageQueue.isEmpty() + && (millis() - _lastMessageTime) >= _keepAlivePeriod) { ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); } @@ -881,7 +887,7 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) data += 2; plen -= 2; } - else if (_pinfo.len == 127) + else if (_pinfo.len == 127) { _pinfo.len = fdata[9] | (uint16_t)(fdata[8]) << 8 | (uint32_t)(fdata[7]) << 16 | (uint32_t)(fdata[6]) << 24 | (uint64_t)(fdata[5]) << 32 | (uint64_t)(fdata[4]) << 40 | (uint64_t)(fdata[3]) << 48 | (uint64_t)(fdata[2]) << 56; @@ -912,7 +918,7 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) if (_pinfo.index == 0) { - if (_pinfo.opcode) + if (_pinfo.opcode) { _pinfo.message_opcode = _pinfo.opcode; _pinfo.num = 0; @@ -963,7 +969,8 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) if (datalen != AWSC_PING_PAYLOAD_LEN || memcmp(AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0) _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); } - else if (_pinfo.opcode < 8) { //continuation or text/binary frame + else if (_pinfo.opcode < 8) //continuation or text/binary frame + { _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, data, datalen); } } @@ -996,7 +1003,7 @@ size_t AsyncWebSocketClient::printf(const char *format, ...) if (!temp) { va_end(arg); - + return 0; } @@ -1011,7 +1018,7 @@ size_t AsyncWebSocketClient::printf(const char *format, ...) if (!buffer) { delete[] temp; - + return 0; } @@ -1028,7 +1035,7 @@ size_t AsyncWebSocketClient::printf(const char *format, ...) } delete[] temp; - + return len; } @@ -1166,7 +1173,8 @@ AsyncWebSocket::~AsyncWebSocket() {} ///////////////////////////////////////////////// -void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) +void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, + size_t len) { if (_eventHandler != NULL) { @@ -1441,7 +1449,7 @@ size_t AsyncWebSocket::printfAll(const char *format, ...) va_end(arg); textAll(buffer); - + return len; } @@ -1597,7 +1605,7 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest * request) return; } - if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) { return request->requestAuthentication(); } @@ -1696,7 +1704,7 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String & key, AsyncWebSocke if (hash == NULL) { _state = RESPONSE_FAILED; - + return; } @@ -1706,7 +1714,7 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String & key, AsyncWebSocke { free(hash); _state = RESPONSE_FAILED; - + return; } @@ -1740,7 +1748,7 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest * request) if (_state == RESPONSE_FAILED) { request->client()->close(true); - + return; } diff --git a/src/Portenta_H7_AsyncWebSocket.h b/src/Portenta_H7_AsyncWebSocket.h index d6fb5d3..fc5b475 100644 --- a/src/Portenta_H7_AsyncWebSocket.h +++ b/src/Portenta_H7_AsyncWebSocket.h @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebSocket.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,10 +21,11 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #pragma once - + #ifndef PORTENTA_H7_ASYNCWEBSOCKET_H_ #define PORTENTA_H7_ASYNCWEBSOCKET_H_ @@ -118,7 +119,7 @@ typedef enum ///////////////////////////////////////////////// -class AsyncWebSocketMessageBuffer +class AsyncWebSocketMessageBuffer { private: uint8_t * _data; @@ -135,67 +136,67 @@ class AsyncWebSocketMessageBuffer ~AsyncWebSocketMessageBuffer(); ///////////////////////////////////////////////// - - void operator ++(int i) + + void operator ++(int i) { PORTENTA_H7_AWS_UNUSED(i); _count++; } ///////////////////////////////////////////////// - - void operator --(int i) + + void operator --(int i) { PORTENTA_H7_AWS_UNUSED(i); - - if (_count > 0) + + if (_count > 0) { _count--; } ; } ///////////////////////////////////////////////// - + bool reserve(size_t size); ///////////////////////////////////////////////// - - void lock() + + void lock() { _lock = true; } ///////////////////////////////////////////////// - - void unlock() + + void unlock() { _lock = false; } ///////////////////////////////////////////////// - - uint8_t * get() + + uint8_t * get() { return _data; } ///////////////////////////////////////////////// - - size_t length() + + size_t length() { return _len; } ///////////////////////////////////////////////// - - uint32_t count() + + uint32_t count() { return _count; } ///////////////////////////////////////////////// - - bool canDelete() + + bool canDelete() { return (!_count && !_lock); } @@ -208,35 +209,35 @@ class AsyncWebSocketMessageBuffer ///////////////////////////////////////////////// -class AsyncWebSocketMessage +class AsyncWebSocketMessage { protected: uint8_t _opcode; bool _mask; AwsMessageStatus _status; - + public: AsyncWebSocketMessage(): _opcode(WS_TEXT), _mask(false), _status(WS_MSG_ERROR) {} virtual ~AsyncWebSocketMessage() {} virtual void ack(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))) {} ///////////////////////////////////////////////// - - virtual size_t send(AsyncClient *client __attribute__((unused))) + + virtual size_t send(AsyncClient *client __attribute__((unused))) { return 0; } ///////////////////////////////////////////////// - - virtual bool finished() + + virtual bool finished() { return _status != WS_MSG_SENDING; } ///////////////////////////////////////////////// - - virtual bool betweenFrames() const + + virtual bool betweenFrames() const { return false; } @@ -244,7 +245,7 @@ class AsyncWebSocketMessage ///////////////////////////////////////////////// -class AsyncWebSocketBasicMessage: public AsyncWebSocketMessage +class AsyncWebSocketBasicMessage: public AsyncWebSocketMessage { private: size_t _len; @@ -252,30 +253,30 @@ class AsyncWebSocketBasicMessage: public AsyncWebSocketMessage size_t _ack; size_t _acked; uint8_t * _data; - + public: AsyncWebSocketBasicMessage(const char * data, size_t len, uint8_t opcode = WS_TEXT, bool mask = false); AsyncWebSocketBasicMessage(uint8_t opcode = WS_TEXT, bool mask = false); virtual ~AsyncWebSocketBasicMessage() override; ///////////////////////////////////////////////// - - virtual bool betweenFrames() const override + + virtual bool betweenFrames() const override { return _acked == _ack; } ///////////////////////////////////////////////// - + virtual void ack(size_t len, uint32_t time) override; virtual size_t send(AsyncClient *client) override; - + virtual bool reserve(size_t size); }; ///////////////////////////////////////////////// -class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage +class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage { private: uint8_t * _data; @@ -284,27 +285,27 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage size_t _ack; size_t _acked; AsyncWebSocketMessageBuffer * _WSbuffer; - + public: AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode = WS_TEXT, bool mask = false); virtual ~AsyncWebSocketMultiMessage() override; ///////////////////////////////////////////////// - - virtual bool betweenFrames() const override + + virtual bool betweenFrames() const override { return _acked == _ack; } ///////////////////////////////////////////////// - + virtual void ack(size_t len, uint32_t time) override ; virtual size_t send(AsyncClient *client) override ; }; ///////////////////////////////////////////////// -class AsyncWebSocketClient +class AsyncWebSocketClient { private: AsyncClient *_client; @@ -334,33 +335,33 @@ class AsyncWebSocketClient ///////////////////////////////////////////////// //client id increments for the given server - uint32_t id() + uint32_t id() { return _clientId; } ///////////////////////////////////////////////// - - AwsClientStatus status() + + AwsClientStatus status() { return _status; } - - AsyncClient* client() + + AsyncClient* client() { return _client; } ///////////////////////////////////////////////// - - AsyncWebSocket *server() + + AsyncWebSocket *server() { return _server; } ///////////////////////////////////////////////// - - AwsFrameInfo const &pinfo() const + + AwsFrameInfo const &pinfo() const { return _pinfo; } @@ -377,14 +378,14 @@ class AsyncWebSocketClient ///////////////////////////////////////////////// //set auto-ping period in seconds. disabled if zero (default) - void keepAlivePeriod(uint16_t seconds) + void keepAlivePeriod(uint16_t seconds) { _keepAlivePeriod = seconds * 1000; } ///////////////////////////////////////////////// - - uint16_t keepAlivePeriod() + + uint16_t keepAlivePeriod() { return (uint16_t)(_keepAlivePeriod / 1000); } @@ -392,13 +393,13 @@ class AsyncWebSocketClient ///////////////////////////////////////////////// //data packets - void message(AsyncWebSocketMessage *message) + void message(AsyncWebSocketMessage *message) { _queueMessage(message); } ///////////////////////////////////////////////// - + bool queueIsFull(); size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3))); @@ -419,7 +420,7 @@ class AsyncWebSocketClient ///////////////////////////////////////////////// - bool canSend() + bool canSend() { return _messageQueue.length() < WS_MAX_QUEUED_MESSAGES; } @@ -437,16 +438,17 @@ class AsyncWebSocketClient ///////////////////////////////////////////////// -typedef std::function AwsEventHandler; +typedef std::function +AwsEventHandler; ///////////////////////////////////////////////// //WebServer Handler implementation that plays the role of a socket server -class AsyncWebSocket: public AsyncWebHandler +class AsyncWebSocket: public AsyncWebHandler { public: typedef LinkedList AsyncWebSocketClientLinkedList; - + private: String _url; AsyncWebSocketClientLinkedList _clients; @@ -460,28 +462,28 @@ class AsyncWebSocket: public AsyncWebHandler ~AsyncWebSocket(); ///////////////////////////////////////////////// - - const char * url() const + + const char * url() const { return _url.c_str(); } ///////////////////////////////////////////////// - - void enable(bool e) + + void enable(bool e) { _enabled = e; } ///////////////////////////////////////////////// - - bool enabled() const + + bool enabled() const { return _enabled; } ///////////////////////////////////////////////// - + bool availableForWriteAll(); bool availableForWrite(uint32_t id); @@ -489,8 +491,8 @@ class AsyncWebSocket: public AsyncWebHandler AsyncWebSocketClient * client(uint32_t id); ///////////////////////////////////////////////// - - bool hasClient(uint32_t id) + + bool hasClient(uint32_t id) { return client(id) != NULL; } @@ -539,7 +541,7 @@ class AsyncWebSocket: public AsyncWebHandler ///////////////////////////////////////////////// //event listener - void onEvent(AwsEventHandler handler) + void onEvent(AwsEventHandler handler) { _eventHandler = handler; } @@ -547,13 +549,13 @@ class AsyncWebSocket: public AsyncWebHandler ///////////////////////////////////////////////// //system callbacks (do not call) - uint32_t _getNextId() + uint32_t _getNextId() { return _cNextId++; } ///////////////////////////////////////////////// - + void _addClient(AsyncWebSocketClient * client); void _handleDisconnect(AsyncWebSocketClient * client); void _handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len); @@ -572,20 +574,20 @@ class AsyncWebSocket: public AsyncWebHandler ///////////////////////////////////////////////// //WebServer response to authenticate the socket and detach the tcp client from the web server request -class AsyncWebSocketResponse: public AsyncWebServerResponse +class AsyncWebSocketResponse: public AsyncWebServerResponse { private: String _content; AsyncWebSocket *_server; - + public: AsyncWebSocketResponse(const String& key, AsyncWebSocket *server); void _respond(AsyncWebServerRequest *request); size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); ///////////////////////////////////////////////// - - bool _sourceValid() const + + bool _sourceValid() const { return true; } diff --git a/src/Portenta_H7_AsyncWebSynchronization.h b/src/Portenta_H7_AsyncWebSynchronization.h index ff58f6a..1c33dbb 100644 --- a/src/Portenta_H7_AsyncWebSynchronization.h +++ b/src/Portenta_H7_AsyncWebSynchronization.h @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_AsyncWebSynchronization.h - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #pragma once @@ -41,7 +42,7 @@ class AsyncWebLock ~AsyncWebLock() {} - bool lock() const + bool lock() const { return false; } @@ -57,21 +58,21 @@ class AsyncWebLockGuard const AsyncWebLock *_lock; public: - AsyncWebLockGuard(const AsyncWebLock &l) + AsyncWebLockGuard(const AsyncWebLock &l) { - if (l.lock()) + if (l.lock()) { _lock = &l; - } - else + } + else { _lock = NULL; } } - ~AsyncWebLockGuard() + ~AsyncWebLockGuard() { - if (_lock) + if (_lock) { _lock->unlock(); } diff --git a/src/Portenta_H7_StringArray.h b/src/Portenta_H7_StringArray.h index 8f617d1..dff3251 100644 --- a/src/Portenta_H7_StringArray.h +++ b/src/Portenta_H7_StringArray.h @@ -1,15 +1,15 @@ /**************************************************************************************************************************** Portenta_H7_StringArray.h - Dead simple AsyncWebServer for STM32 LAN8720 or built-in LAN8742A Ethernet - + For Portenta_H7 (STM32H7) with Vision-Shield Ethernet or Murata WiFi - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with Vision-Shield Ethernet or Murata WiFi - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 + + Version: 1.4.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -21,6 +21,7 @@ 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed + 1.4.2 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks *****************************************************************************************************************************/ #pragma once @@ -203,7 +204,7 @@ class LinkedList it = it->next; } - + return i; } @@ -251,7 +252,7 @@ class LinkedList } delete it; - + return true; } @@ -288,7 +289,7 @@ class LinkedList } delete it; - + return true; } diff --git a/src/libb64/cdecode.c b/src/libb64/cdecode.c index f9d9341..0bf7341 100644 --- a/src/libb64/cdecode.c +++ b/src/libb64/cdecode.c @@ -5,25 +5,12 @@ For details, see http://sourceforge.net/projects/libb64 For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 - - Version Modified By Date Comments - ------- ----------- ---------- ----------- - 1.0.0 K Hoang 06/10/2021 Initial coding for Portenta_H7 (STM32H7) with Vision-Shield Ethernet - 1.1.0 K Hoang 08/10/2021 Add support to Portenta_H7 (STM32H7) using Murata WiFi - 1.1.1 K Hoang 12/10/2021 Update `platform.ini` and `library.json` - 1.2.0 K Hoang 07/12/2021 Fix crashing issue - 1.2.1 K Hoang 12/01/2022 Fix authenticate issue caused by libb64 - 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network - 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap - 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed *****************************************************************************************************************************/ #include "cdecode.h" @@ -31,7 +18,8 @@ int base64_decode_value(int value_in) { static const char decoding[] = - { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, -1, 0, 1, 2, + { + 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 @@ -78,8 +66,8 @@ int base64_decode_block(const char* code_in, const int length_in, char* plaintex } while (fragment < 0); *plainchar = (fragment & 0x03f) << 2; - - // fall through + + // fall through case step_b: do @@ -96,8 +84,8 @@ int base64_decode_block(const char* code_in, const int length_in, char* plaintex *plainchar++ |= (fragment & 0x030) >> 4; *plainchar = (fragment & 0x00f) << 4; - - // fall through + + // fall through case step_c: do @@ -114,8 +102,8 @@ int base64_decode_block(const char* code_in, const int length_in, char* plaintex *plainchar++ |= (fragment & 0x03c) >> 2; *plainchar = (fragment & 0x003) << 6; - - // fall through + + // fall through case step_d: do @@ -131,7 +119,7 @@ int base64_decode_block(const char* code_in, const int length_in, char* plaintex } while (fragment < 0); *plainchar++ |= (fragment & 0x03f); - + // fall through } } @@ -140,7 +128,8 @@ int base64_decode_block(const char* code_in, const int length_in, char* plaintex return plainchar - plaintext_out; } -int base64_decode_chars(const char* code_in, const int length_in, char* plaintext_out) { +int base64_decode_chars(const char* code_in, const int length_in, char* plaintext_out) +{ base64_decodestate _state; base64_init_decodestate(&_state); diff --git a/src/libb64/cdecode.h b/src/libb64/cdecode.h index 03addca..3fd23ca 100644 --- a/src/libb64/cdecode.h +++ b/src/libb64/cdecode.h @@ -5,25 +5,12 @@ For details, see http://sourceforge.net/projects/libb64 For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 - - Version Modified By Date Comments - ------- ----------- ---------- ----------- - 1.0.0 K Hoang 06/10/2021 Initial coding for Portenta_H7 (STM32H7) with Vision-Shield Ethernet - 1.1.0 K Hoang 08/10/2021 Add support to Portenta_H7 (STM32H7) using Murata WiFi - 1.1.1 K Hoang 12/10/2021 Update `platform.ini` and `library.json` - 1.2.0 K Hoang 07/12/2021 Fix crashing issue - 1.2.1 K Hoang 12/01/2022 Fix authenticate issue caused by libb64 - 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network - 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap - 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed *****************************************************************************************************************************/ #pragma once @@ -39,12 +26,12 @@ extern "C" { #endif -typedef enum +typedef enum { step_a, step_b, step_c, step_d } base64_decodestep; -typedef struct +typedef struct { base64_decodestep step; char plainchar; diff --git a/src/libb64/cencode.c b/src/libb64/cencode.c index 58c29fb..0f46a76 100644 --- a/src/libb64/cencode.c +++ b/src/libb64/cencode.c @@ -5,25 +5,12 @@ For details, see http://sourceforge.net/projects/libb64 For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 - - Version Modified By Date Comments - ------- ----------- ---------- ----------- - 1.0.0 K Hoang 06/10/2021 Initial coding for Portenta_H7 (STM32H7) with Vision-Shield Ethernet - 1.1.0 K Hoang 08/10/2021 Add support to Portenta_H7 (STM32H7) using Murata WiFi - 1.1.1 K Hoang 12/10/2021 Update `platform.ini` and `library.json` - 1.2.0 K Hoang 07/12/2021 Fix crashing issue - 1.2.1 K Hoang 12/01/2022 Fix authenticate issue caused by libb64 - 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network - 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap - 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed *****************************************************************************************************************************/ #include "cencode.h" @@ -73,8 +60,8 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, result = (fragment & 0x0fc) >> 2; *codechar++ = base64_encode_value(result); result = (fragment & 0x003) << 4; - - // fall through + + // fall through case step_B: if (plainchar == plaintextend) @@ -88,9 +75,9 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, result |= (fragment & 0x0f0) >> 4; *codechar++ = base64_encode_value(result); result = (fragment & 0x00f) << 2; - - // fall through - + + // fall through + case step_C: if (plainchar == plaintextend) { @@ -112,7 +99,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, *codechar++ = '\n'; state_in->stepcount = 0; } - + // fall through } } @@ -132,10 +119,12 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in) *codechar++ = '='; *codechar++ = '='; break; + case step_C: *codechar++ = base64_encode_value(state_in->result); *codechar++ = '='; break; + case step_A: break; } diff --git a/src/libb64/cencode.h b/src/libb64/cencode.h index f098731..3b1fd14 100644 --- a/src/libb64/cencode.h +++ b/src/libb64/cencode.h @@ -5,25 +5,12 @@ For details, see http://sourceforge.net/projects/libb64 For Portenta_H7 (STM32H7) with Vision-Shield Ethernet - + Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet - + Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer Licensed under GPLv3 license - - Version: 1.4.1 - - Version Modified By Date Comments - ------- ----------- ---------- ----------- - 1.0.0 K Hoang 06/10/2021 Initial coding for Portenta_H7 (STM32H7) with Vision-Shield Ethernet - 1.1.0 K Hoang 08/10/2021 Add support to Portenta_H7 (STM32H7) using Murata WiFi - 1.1.1 K Hoang 12/10/2021 Update `platform.ini` and `library.json` - 1.2.0 K Hoang 07/12/2021 Fix crashing issue - 1.2.1 K Hoang 12/01/2022 Fix authenticate issue caused by libb64 - 1.3.0 K Hoang 26/09/2022 Fix issue with slow browsers or network - 1.4.0 K Hoang 02/10/2022 Option to use cString instead og String to save Heap - 1.4.1 K Hoang 04/10/2022 Don't need memmove(), String no longer destroyed *****************************************************************************************************************************/ #pragma once @@ -39,12 +26,12 @@ extern "C" { #endif -typedef enum +typedef enum { step_A, step_B, step_C } base64_encodestep; -typedef struct +typedef struct { base64_encodestep step; char result; diff --git a/utils/astyle_library.conf b/utils/astyle_library.conf new file mode 100644 index 0000000..8a73bc2 --- /dev/null +++ b/utils/astyle_library.conf @@ -0,0 +1,70 @@ +# Code formatting rules for Arduino libraries, modified from for KH libraries: +# +# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf +# + +# astyle --style=allman -s2 -t2 -C -S -xW -Y -M120 -f -p -xg -H -xb -c --xC120 -xL *.h *.cpp *.ino + +--mode=c +--lineend=linux +--style=allman + +# -r or -R +#--recursive + +# -c => Converts tabs into spaces +convert-tabs + +# -s2 => 2 spaces indentation +--indent=spaces=2 + +# -t2 => tab =2 spaces +#--indent=tab=2 + +# -C +--indent-classes + +# -S +--indent-switches + +# -xW +--indent-preproc-block + +# -Y => indent classes, switches (and cases), comments starting at column 1 +--indent-col1-comments + +# -M120 => maximum of 120 spaces to indent a continuation line +--max-continuation-indent=120 + +# -xC120 => max‑code‑length will break a line if the code exceeds # characters +--max-code-length=120 + +# -f => +--break-blocks + +# -p => put a space around operators +--pad-oper + +# -xg => Insert space padding after commas +--pad-comma + +# -H => put a space after if/for/while +pad-header + +# -xb => Break one line headers (e.g. if/for/while) +--break-one-line-headers + +# -c => Converts tabs into spaces +#--convert-tabs + +# if you like one-liners, keep them +#keep-one-line-statements + +# -xV +--attach-closing-while + +#unpad-paren + +# -xp +remove-comment-prefix + diff --git a/utils/restyle.sh b/utils/restyle.sh new file mode 100644 index 0000000..bcd846f --- /dev/null +++ b/utils/restyle.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +for dir in . ; do + find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.ino" \) -exec astyle --suffix=none --options=./utils/astyle_library.conf \{\} \; +done +