├── pics ├── Async_AdvancedWebServer.png ├── AsyncWebServer_SendChunked.png ├── Async_AdvancedWebServer_favicon.png └── Async_AdvancedWebServer_MemoryIssues_Send_CString.png ├── utils ├── restyle.sh └── astyle_library.conf ├── .codespellrc ├── .github ├── workflows │ ├── auto-github-actions.yml │ ├── report-size-deltas.yml │ └── spell-check.yml ├── dependabot.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── stale.yml ├── .gitignore ├── examples ├── Async_WebSocketsServer │ ├── WSClient_Python │ │ └── WSClient.py │ ├── webpage.h │ └── Async_WebSocketsServer.ino ├── WebClient │ ├── defines.h │ └── WebClient.ino ├── MQTTClient_Auth │ ├── defines.h │ └── MQTTClient_Auth.ino ├── MQTTClient_Basic │ ├── defines.h │ └── MQTTClient_Basic.ino ├── MQTT_ThingStream │ ├── defines.h │ └── MQTT_ThingStream.ino ├── WebClientRepeating │ ├── defines.h │ └── WebClientRepeating.ino ├── Async_RegexPatterns │ ├── defines.h │ └── Async_RegexPatterns.ino ├── Async_HttpBasicAuth │ └── Async_HttpBasicAuth.ino ├── Async_HelloServer │ └── Async_HelloServer.ino ├── Async_SimpleWebServer │ └── Async_SimpleWebServer.ino ├── Async_AdvancedWebServer_favicon │ ├── favicon.h │ └── Async_AdvancedWebServer_favicon.ino ├── Async_HelloServer2 │ └── Async_HelloServer2.ino ├── Async_PostServer │ └── Async_PostServer.ino ├── AsyncMultiWebServer │ └── AsyncMultiWebServer.ino ├── AsyncWebServer_SendChunked │ └── AsyncWebServer_SendChunked.ino └── Async_AdvancedWebServer │ └── Async_AdvancedWebServer.ino ├── library.properties ├── src ├── Crypto │ ├── Hash.h │ ├── Hash.cpp │ ├── md5.h │ └── sha1.h ├── libb64 │ ├── cdecode.h │ ├── cencode.h │ ├── cencode.c │ └── cdecode.c ├── AsyncWebServer_Teensy41.h ├── AsyncWebAuthentication_Teensy41.h ├── AsyncWebSynchronization_Teensy41.h ├── AsyncWebHandlers_Teensy41.cpp ├── AsyncWebServer_Teensy41_Debug.h ├── AsyncEventSource_Teensy41.h ├── AsyncWebHandlerImpl_Teensy41.h └── AsyncWebResponseImpl_Teensy41.h ├── travis └── common.sh ├── library.json ├── platformio └── platformio.ini ├── CONTRIBUTING.md ├── changelog.md └── Packages_Patches └── hardware └── teensy └── avr └── cores ├── teensy └── Stream.h ├── teensy3 └── Stream.h └── teensy4 └── Stream.h /pics/Async_AdvancedWebServer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/AsyncWebServer_Teensy41/HEAD/pics/Async_AdvancedWebServer.png -------------------------------------------------------------------------------- /pics/AsyncWebServer_SendChunked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/AsyncWebServer_Teensy41/HEAD/pics/AsyncWebServer_SendChunked.png -------------------------------------------------------------------------------- /pics/Async_AdvancedWebServer_favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/AsyncWebServer_Teensy41/HEAD/pics/Async_AdvancedWebServer_favicon.png -------------------------------------------------------------------------------- /pics/Async_AdvancedWebServer_MemoryIssues_Send_CString.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/AsyncWebServer_Teensy41/HEAD/pics/Async_AdvancedWebServer_MemoryIssues_Send_CString.png -------------------------------------------------------------------------------- /utils/restyle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for dir in . ; do 4 | find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.ino" \) -exec astyle --suffix=none --options=./utils/astyle_library.conf \{\} \; 5 | done 6 | 7 | -------------------------------------------------------------------------------- /.codespellrc: -------------------------------------------------------------------------------- 1 | # See: https://github.com/codespell-project/codespell#using-a-config-file 2 | [codespell] 3 | # In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here: 4 | ignore-words-list = , 5 | check-filenames = 6 | check-hidden = 7 | skip = ./.git,./src,./examples,./Packages_Patches,./LibraryPatches 8 | -------------------------------------------------------------------------------- /.github/workflows/auto-github-actions.yml: -------------------------------------------------------------------------------- 1 | name: auto-github-actions 2 | on: [push] 3 | jobs: 4 | check-bats-version: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - uses: actions/setup-node@v4 9 | with: 10 | node-version: '14' 11 | - run: npm install -g bats 12 | - run: bats -v 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /.github/workflows/report-size-deltas.yml: -------------------------------------------------------------------------------- 1 | name: Report Size Deltas 2 | 3 | on: 4 | schedule: 5 | - cron: '*/5 * * * *' 6 | 7 | jobs: 8 | report: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Comment size deltas reports to PRs 13 | uses: arduino/report-size-deltas@v1 14 | with: 15 | # The name of the workflow artifact created by the "Compile Examples" workflow 16 | sketches-reports-source: sketches-reports 17 | -------------------------------------------------------------------------------- /examples/Async_WebSocketsServer/WSClient_Python/WSClient.py: -------------------------------------------------------------------------------- 1 | # Run by $ python3.8 WSClient.py 2 | # From websocket-client package. Install by $ pip3 install websocket-client 3 | import websocket 4 | import time 5 | 6 | ws = websocket.WebSocket() 7 | #ws.connect("ws://192.168.2.98/ws") 8 | ws.connect("ws://192.168.2.77/ws") 9 | #ws.connect("ws://192.168.2.103/ws") 10 | 11 | while True: 12 | ws.send("Hello, Server") 13 | result = ws.recv() 14 | print(result) 15 | time.sleep(10) 16 | 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#about-the-dependabotyml-file 2 | version: 2 3 | 4 | updates: 5 | # Configure check for outdated GitHub Actions actions in workflows. 6 | # See: https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot 7 | - package-ecosystem: github-actions 8 | directory: / # Check the repository's workflows under /.github/workflows/ 9 | schedule: 10 | interval: daily 11 | -------------------------------------------------------------------------------- /.github/workflows/spell-check.yml: -------------------------------------------------------------------------------- 1 | name: Spell Check 2 | 3 | on: 4 | pull_request: 5 | push: 6 | schedule: 7 | # run every Tuesday at 3 AM UTC 8 | - cron: "0 3 * * 2" 9 | workflow_dispatch: 10 | repository_dispatch: 11 | 12 | jobs: 13 | spellcheck: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | 20 | # See: https://github.com/codespell-project/actions-codespell/blob/master/README.md 21 | - name: Spell check 22 | uses: codespell-project/actions-codespell@master 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /examples/Async_WebSocketsServer/webpage.h: -------------------------------------------------------------------------------- 1 | //===================== 2 | //HTML code for webpage 3 | //===================== 4 | 5 | const char webpageCont[] PROGMEM = 6 | R"=====( 7 | 8 | 9 | Teensy4_1 AsyncSocketServer 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 | 22 | 23 |

Teensy4_1 AsyncSocketServer

24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | )====="; 41 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=AsyncWebServer_Teensy41 2 | version=1.7.0 3 | author=Hristo Gochkov, Khoi Hoang 4 | maintainer=Khoi Hoang 5 | sentence=Asynchronous HTTP and WebSocket Server Library for Teensy 4.1 using QNEthernet 6 | paragraph=This library is one of the current or future Async libraries to support Teensy 4.1 using QNEthernet, such as AsyncHTTPRequest_Generic, AsyncHTTPSRequest_Generic, AsyncMQTT_Generic, Teensy41_AsyncWebServer, Teensy41_AsyncUDP, Teensy41_AsyncDNSServer, AsyncWebServer_Teensy41_SSL, etc. Now supporting using CString to save heap to send very large data and examples to demo how to use beginChunkedResponse() to send large html in chunks 7 | category=Communication 8 | url=https://github.com/khoih-prog/AsyncWebServer_Teensy41 9 | license=LGPLv3 10 | architectures=teensy, avr 11 | depends=Teensy41_AsyncTCP 12 | includes=AsyncWebServer_Teensy41.h, AsyncWebServer_Teensy41.hpp 13 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | daysUntilStale: 60 4 | daysUntilClose: 14 5 | limitPerRun: 30 6 | staleLabel: stale 7 | exemptLabels: 8 | - pinned 9 | - security 10 | - "to be implemented" 11 | - "for reference" 12 | - "move to PR" 13 | - "enhancement" 14 | 15 | only: issues 16 | onlyLabels: [] 17 | exemptProjects: false 18 | exemptMilestones: false 19 | exemptAssignees: false 20 | 21 | markComment: > 22 | [STALE_SET] This issue has been automatically marked as stale because it has not had 23 | recent activity. It will be closed in 14 days if no further activity occurs. Thank you 24 | for your contributions. 25 | 26 | unmarkComment: > 27 | [STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it opening the future. 28 | 29 | closeComment: > 30 | [STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions. 31 | 32 | -------------------------------------------------------------------------------- /utils/astyle_library.conf: -------------------------------------------------------------------------------- 1 | # Code formatting rules for Arduino libraries, modified from for KH libraries: 2 | # 3 | # https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf 4 | # 5 | 6 | # astyle --style=allman -s2 -t2 -C -S -xW -Y -M120 -f -p -xg -H -xb -c --xC120 -xL *.h *.cpp *.ino 7 | 8 | --mode=c 9 | --lineend=linux 10 | --style=allman 11 | 12 | # -r or -R 13 | #--recursive 14 | 15 | # -c => Converts tabs into spaces 16 | convert-tabs 17 | 18 | # -s2 => 2 spaces indentation 19 | --indent=spaces=2 20 | 21 | # -t2 => tab =2 spaces 22 | #--indent=tab=2 23 | 24 | # -C 25 | --indent-classes 26 | 27 | # -S 28 | --indent-switches 29 | 30 | # -xW 31 | --indent-preproc-block 32 | 33 | # -Y => indent classes, switches (and cases), comments starting at column 1 34 | --indent-col1-comments 35 | 36 | # -M120 => maximum of 120 spaces to indent a continuation line 37 | --max-continuation-indent=120 38 | 39 | # -xC120 => max‑code‑length will break a line if the code exceeds # characters 40 | --max-code-length=120 41 | 42 | # -f => 43 | --break-blocks 44 | 45 | # -p => put a space around operators 46 | --pad-oper 47 | 48 | # -xg => Insert space padding after commas 49 | --pad-comma 50 | 51 | # -H => put a space after if/for/while 52 | pad-header 53 | 54 | # -xb => Break one line headers (e.g. if/for/while) 55 | --break-one-line-headers 56 | 57 | # -c => Converts tabs into spaces 58 | #--convert-tabs 59 | 60 | # if you like one-liners, keep them 61 | #keep-one-line-statements 62 | 63 | # -xV 64 | --attach-closing-while 65 | 66 | #unpad-paren 67 | 68 | # -xp 69 | remove-comment-prefix 70 | 71 | -------------------------------------------------------------------------------- /src/Crypto/Hash.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file Hash.h 3 | @date 20.05.2015 4 | @author Markus Sattler 5 | 6 | Copyright (c) 2015 Markus Sattler. All rights reserved. 7 | This file is part of the esp8266 core for Arduino environment. 8 | 9 | This library is free software; you can redistribute it and/or 10 | modify it under the terms of the GNU Lesser General Public 11 | License as published by the Free Software Foundation; either 12 | version 2.1 of the License, or (at your option) any later version. 13 | 14 | This library is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | Lesser General Public License for more details. 18 | 19 | You should have received a copy of the GNU Lesser General Public 20 | License along with this library; if not, write to the Free Software 21 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | */ 24 | 25 | #pragma once 26 | 27 | #ifndef HASH_H_ 28 | #define HASH_H_ 29 | 30 | #include "AsyncWebServer_Teensy41_Debug.h" 31 | 32 | #ifdef HASH_BUFFER_SIZE 33 | #undef HASH_BUFFER_SIZE 34 | #endif 35 | 36 | #define HASH_BUFFER_SIZE 20 37 | 38 | void sha1(const uint8_t* data, uint32_t size, uint8_t hash[HASH_BUFFER_SIZE]); 39 | void sha1(const char* data, uint32_t size, uint8_t hash[HASH_BUFFER_SIZE]); 40 | void sha1(const String& data, uint8_t hash[HASH_BUFFER_SIZE]); 41 | 42 | String sha1(const uint8_t* data, uint32_t size); 43 | String sha1(const char* data, uint32_t size); 44 | String sha1(const String& data); 45 | 46 | #endif /* HASH_H_ */ 47 | -------------------------------------------------------------------------------- /travis/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function build_examples() 4 | { 5 | # track the exit code for this platform 6 | local exit_code=0 7 | # loop through results and add them to the array 8 | examples=($(find $PWD/examples/ -name "*.pde" -o -name "*.ino")) 9 | 10 | # get the last example in the array 11 | local last="${examples[@]:(-1)}" 12 | 13 | # loop through example sketches 14 | for example in "${examples[@]}"; do 15 | 16 | # store the full path to the example's sketch directory 17 | local example_dir=$(dirname $example) 18 | 19 | # store the filename for the example without the path 20 | local example_file=$(basename $example) 21 | 22 | echo "$example_file: " 23 | local sketch="$example_dir/$example_file" 24 | echo "$sketch" 25 | #arduino -v --verbose-build --verify $sketch 26 | 27 | # verify the example, and save stdout & stderr to a variable 28 | # we have to avoid reading the exit code of local: 29 | # "when declaring a local variable in a function, the local acts as a command in its own right" 30 | local build_stdout 31 | build_stdout=$(arduino --verify $sketch 2>&1) 32 | 33 | # echo output if the build failed 34 | if [ $? -ne 0 ]; then 35 | # heavy X 36 | echo -e "\xe2\x9c\x96" 37 | echo -e "----------------------------- DEBUG OUTPUT -----------------------------\n" 38 | echo "$build_stdout" 39 | echo -e "\n------------------------------------------------------------------------\n" 40 | 41 | # mark as fail 42 | exit_code=1 43 | 44 | else 45 | # heavy checkmark 46 | echo -e "\xe2\x9c\x93" 47 | fi 48 | done 49 | 50 | return $exit_code 51 | } 52 | -------------------------------------------------------------------------------- /examples/WebClient/defines.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | defines.h 3 | 4 | Dead simple AsyncWebServer for Teensy41 QNEthernet 5 | 6 | For Teensy41 with QNEthernet 7 | 8 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 9 | 10 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 11 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 12 | Licensed under GPLv3 license 13 | *****************************************************************************************************************************/ 14 | 15 | #ifndef defines_h 16 | #define defines_h 17 | 18 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 19 | #error Only Teensy 4.1 supported 20 | #endif 21 | 22 | // Debug Level from 0 to 4 23 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 24 | #define _AWS_TEENSY41_LOGLEVEL_ 1 25 | 26 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 27 | 28 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 29 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 30 | #endif 31 | 32 | #define USING_DHCP true 33 | //#define USING_DHCP false 34 | 35 | #if !USING_DHCP 36 | // Set the static IP address to use if the DHCP fails to assign 37 | IPAddress myIP(192, 168, 2, 222); 38 | IPAddress myNetmask(255, 255, 255, 0); 39 | IPAddress myGW(192, 168, 2, 1); 40 | //IPAddress mydnsServer(192, 168, 2, 1); 41 | IPAddress mydnsServer(8, 8, 8, 8); 42 | #endif 43 | 44 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 45 | using namespace qindesign::network; 46 | 47 | #include 48 | 49 | #endif //defines_h 50 | -------------------------------------------------------------------------------- /examples/MQTTClient_Auth/defines.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | defines.h 3 | 4 | Dead simple AsyncWebServer for Teensy41 QNEthernet 5 | 6 | For Teensy41 with QNEthernet 7 | 8 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 9 | 10 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 11 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 12 | Licensed under GPLv3 license 13 | *****************************************************************************************************************************/ 14 | 15 | #ifndef defines_h 16 | #define defines_h 17 | 18 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 19 | #error Only Teensy 4.1 supported 20 | #endif 21 | 22 | // Debug Level from 0 to 4 23 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 24 | #define _AWS_TEENSY41_LOGLEVEL_ 1 25 | 26 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 27 | 28 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 29 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 30 | #endif 31 | 32 | #define USING_DHCP true 33 | //#define USING_DHCP false 34 | 35 | #if !USING_DHCP 36 | // Set the static IP address to use if the DHCP fails to assign 37 | IPAddress myIP(192, 168, 2, 222); 38 | IPAddress myNetmask(255, 255, 255, 0); 39 | IPAddress myGW(192, 168, 2, 1); 40 | //IPAddress mydnsServer(192, 168, 2, 1); 41 | IPAddress mydnsServer(8, 8, 8, 8); 42 | #endif 43 | 44 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 45 | using namespace qindesign::network; 46 | 47 | #include 48 | 49 | #endif //defines_h 50 | -------------------------------------------------------------------------------- /examples/MQTTClient_Basic/defines.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | defines.h 3 | 4 | Dead simple AsyncWebServer for Teensy41 QNEthernet 5 | 6 | For Teensy41 with QNEthernet 7 | 8 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 9 | 10 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 11 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 12 | Licensed under GPLv3 license 13 | *****************************************************************************************************************************/ 14 | 15 | #ifndef defines_h 16 | #define defines_h 17 | 18 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 19 | #error Only Teensy 4.1 supported 20 | #endif 21 | 22 | // Debug Level from 0 to 4 23 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 24 | #define _AWS_TEENSY41_LOGLEVEL_ 1 25 | 26 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 27 | 28 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 29 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 30 | #endif 31 | 32 | #define USING_DHCP true 33 | //#define USING_DHCP false 34 | 35 | #if !USING_DHCP 36 | // Set the static IP address to use if the DHCP fails to assign 37 | IPAddress myIP(192, 168, 2, 222); 38 | IPAddress myNetmask(255, 255, 255, 0); 39 | IPAddress myGW(192, 168, 2, 1); 40 | //IPAddress mydnsServer(192, 168, 2, 1); 41 | IPAddress mydnsServer(8, 8, 8, 8); 42 | #endif 43 | 44 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 45 | using namespace qindesign::network; 46 | 47 | #include 48 | 49 | #endif //defines_h 50 | -------------------------------------------------------------------------------- /examples/MQTT_ThingStream/defines.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | defines.h 3 | 4 | Dead simple AsyncWebServer for Teensy41 QNEthernet 5 | 6 | For Teensy41 with QNEthernet 7 | 8 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 9 | 10 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 11 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 12 | Licensed under GPLv3 license 13 | *****************************************************************************************************************************/ 14 | 15 | #ifndef defines_h 16 | #define defines_h 17 | 18 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 19 | #error Only Teensy 4.1 supported 20 | #endif 21 | 22 | // Debug Level from 0 to 4 23 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 24 | #define _AWS_TEENSY41_LOGLEVEL_ 1 25 | 26 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 27 | 28 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 29 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 30 | #endif 31 | 32 | #define USING_DHCP true 33 | //#define USING_DHCP false 34 | 35 | #if !USING_DHCP 36 | // Set the static IP address to use if the DHCP fails to assign 37 | IPAddress myIP(192, 168, 2, 222); 38 | IPAddress myNetmask(255, 255, 255, 0); 39 | IPAddress myGW(192, 168, 2, 1); 40 | //IPAddress mydnsServer(192, 168, 2, 1); 41 | IPAddress mydnsServer(8, 8, 8, 8); 42 | #endif 43 | 44 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 45 | using namespace qindesign::network; 46 | 47 | #include 48 | 49 | #endif //defines_h 50 | -------------------------------------------------------------------------------- /examples/WebClientRepeating/defines.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | defines.h 3 | 4 | Dead simple AsyncWebServer for Teensy41 QNEthernet 5 | 6 | For Teensy41 with QNEthernet 7 | 8 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 9 | 10 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 11 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 12 | Licensed under GPLv3 license 13 | *****************************************************************************************************************************/ 14 | 15 | 16 | #ifndef defines_h 17 | #define defines_h 18 | 19 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 20 | #error Only Teensy 4.1 supported 21 | #endif 22 | 23 | // Debug Level from 0 to 4 24 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 25 | #define _AWS_TEENSY41_LOGLEVEL_ 1 26 | 27 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 28 | 29 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 30 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 31 | #endif 32 | 33 | #define USING_DHCP true 34 | //#define USING_DHCP false 35 | 36 | #if !USING_DHCP 37 | // Set the static IP address to use if the DHCP fails to assign 38 | IPAddress myIP(192, 168, 2, 222); 39 | IPAddress myNetmask(255, 255, 255, 0); 40 | IPAddress myGW(192, 168, 2, 1); 41 | //IPAddress mydnsServer(192, 168, 2, 1); 42 | IPAddress mydnsServer(8, 8, 8, 8); 43 | #endif 44 | 45 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 46 | using namespace qindesign::network; 47 | 48 | #include 49 | 50 | #endif //defines_h 51 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"AsyncWebServer_Teensy41", 3 | "version": "1.7.0", 4 | "description":"Asynchronous HTTP and WebSocket Server Library for Teensy 4.1 using QNEthernet. This library is one of the current or future Async libraries to support Teensy 4.1 using QNEthernet, such as AsyncHTTPRequest_Generic, AsyncHTTPSRequest_Generic, AsyncMQTT_Generic, Teensy41_AsyncWebServer, Teensy41_AsyncUDP, Teensy41_AsyncDNSServer, AsyncWebServer_Teensy41_SSL, etc. Now supporting using CString to save heap to send very large data and examples to demo how to use beginChunkedResponse() to send large html in chunks", 5 | "keywords":"async, tcp, http, websocket, webserver, async-tcp, async-http, async-webserver, async-websocket, teensy, teensy41, teensy-41, qnethernet, lwip", 6 | "authors": 7 | [ 8 | { 9 | "name": "Hristo Gochkov", 10 | "url": "https://github.com/me-no-dev" 11 | }, 12 | { 13 | "name": "Khoi Hoang", 14 | "url": "https://github.com/khoih-prog", 15 | "email": "khoih-dot-prog@gmail.com", 16 | "maintainer": true 17 | } 18 | ], 19 | "repository": 20 | { 21 | "type": "git", 22 | "url": "https://github.com/khoih-prog/AsyncWebServer_Teensy41.git" 23 | }, 24 | "dependencies": 25 | [ 26 | { 27 | "owner": "khoih-prog", 28 | "name": "Teensy41_AsyncTCP", 29 | "version": ">=1.1.0", 30 | "platforms": ["teensy", "avr"] 31 | }, 32 | { 33 | "owner": "ssilverman", 34 | "name": "QNEthernet", 35 | "version": ">=0.26.0", 36 | "platforms": ["teensy"] 37 | } 38 | ], 39 | "homepage": "https://github.com/khoih-prog/AsyncWebServer_Teensy41", 40 | "export": { 41 | "exclude": [ 42 | "linux", 43 | "extras", 44 | "tests" 45 | ] 46 | }, 47 | "license": "GPL-3.0", 48 | "frameworks": "*", 49 | "platforms": ["teensy", "avr"], 50 | "examples": "examples/*/*/*.ino", 51 | "headers": ["AsyncWebServer_Teensy41.h", "AsyncWebServer_Teensy41.hpp"] 52 | } 53 | -------------------------------------------------------------------------------- /platformio/platformio.ini: -------------------------------------------------------------------------------- 1 | ;PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; ============================================================ 13 | ; chose environment: 14 | ; teensy 15 | 16 | ; ============================================================ 17 | default_envs = teensy 18 | 19 | [env] 20 | ; ============================================================ 21 | ; Serial configuration 22 | ; choose upload speed, serial-monitor speed 23 | ; ============================================================ 24 | upload_speed = 921600 25 | ;upload_port = COM11 26 | ;monitor_speed = 9600 27 | ;monitor_port = COM11 28 | 29 | ; ============================================================ 30 | ; Checks for the compatibility with frameworks and dev/platforms 31 | ; Adjust as necessary 32 | lib_compat_mode = strict 33 | lib_ldf_mode = chain+ 34 | ;lib_ldf_mode = deep+ 35 | 36 | ; ============================================================ 37 | lib_deps = 38 | ; PlatformIO 4.x 39 | ; Teensy41_AsyncTCP@>=1.1.0 40 | ; QNEthernet@>=0.17.0 41 | ; 42 | ; PlatformIO 5.x 43 | khoih-prog/Teensy41_AsyncTCP@>=1.1.0 44 | ssilverman/QNEthernet@>=0.26.0 45 | 46 | ; ============================================================ 47 | build_flags = 48 | ; set your build_flags 49 | 50 | ; ============================================================ 51 | [env:teensy] 52 | platform = teensy 53 | framework = arduino 54 | 55 | ; ============================================================ 56 | ; Choose your board by uncommenting one of the following lines 57 | ; ============================================================ 58 | 59 | ; ============================================================ 60 | ; Board configuration Many more Boards to be filled 61 | ; ============================================================ 62 | 63 | 64 | -------------------------------------------------------------------------------- /examples/Async_RegexPatterns/defines.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | defines.h 3 | 4 | For ESP8266 using W5x00/ENC8266 Ethernet 5 | 6 | AsyncWebServer_Ethernet is a library for the Ethernet with lwIP_5100, lwIP_5500 or lwIP_enc28j60 library 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Ethernet 10 | Licensed under GPLv3 license 11 | ***************************************************************************************************************************************/ 12 | 13 | #ifndef defines_h 14 | #define defines_h 15 | 16 | #if defined(ESP8266) 17 | #define LED_ON LOW 18 | #define LED_OFF HIGH 19 | #else 20 | #error Only ESP8266 21 | #endif 22 | 23 | #define _AWS_ETHERNET_LOGLEVEL_ 1 24 | 25 | ////////////////////////////////////////////////////////// 26 | 27 | #define USING_W5500 true 28 | #define USING_W5100 false 29 | #define USING_ENC28J60 false 30 | 31 | #include 32 | 33 | #define CSPIN 16 // 5 34 | 35 | #if USING_W5500 36 | #include "W5500lwIP.h" 37 | #define SHIELD_TYPE "ESP8266_W5500 Ethernet" 38 | 39 | Wiznet5500lwIP eth(CSPIN); 40 | 41 | #elif USING_W5100 42 | #include 43 | #define SHIELD_TYPE "ESP8266_W5100 Ethernet" 44 | 45 | Wiznet5100lwIP eth(CSPIN); 46 | 47 | #elif USING_ENC28J60 48 | #include 49 | #define SHIELD_TYPE "ESP8266_ENC28J60 Ethernet" 50 | 51 | ENC28J60lwIP eth(CSPIN); 52 | #else 53 | // default if none selected 54 | #include "W5500lwIP.h" 55 | 56 | Wiznet5500lwIP eth(CSPIN); 57 | #endif 58 | 59 | #include // WiFiClient (-> TCPClient) 60 | 61 | using TCPClient = WiFiClient; 62 | 63 | ////////////////////////////////////////////////////////// 64 | 65 | #define USING_DHCP true 66 | 67 | #if !USING_DHCP 68 | IPAddress localIP(192, 168, 2, 222); 69 | IPAddress gateway(192, 168, 2, 1); 70 | IPAddress netMask(255, 255, 255, 0); 71 | #endif 72 | 73 | #endif //defines_h 74 | -------------------------------------------------------------------------------- /src/libb64/cdecode.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | cdecode.h - c header for a base64 decoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | 7 | For Teensy41 with QNEthernet 8 | 9 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 10 | 11 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 12 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 13 | 14 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 15 | This file is part of the esp8266 core for Arduino environment. 16 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 17 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 18 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 20 | You should have received a copy of the GNU General Public License along with this program. 21 | If not, see . 22 | *****************************************************************************************************************************/ 23 | 24 | #pragma once 25 | 26 | // Reintroduce to prevent duplication compile error if other lib/core already has LIB64 27 | // pragma once can't prevent that 28 | #ifndef BASE64_CDECODE_H 29 | #define BASE64_CDECODE_H 30 | 31 | #define base64_decode_expected_len(n) ((n * 3) / 4) 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | typedef enum 38 | { 39 | step_a, step_b, step_c, step_d 40 | } base64_decodestep; 41 | 42 | typedef struct 43 | { 44 | base64_decodestep step; 45 | char plainchar; 46 | } base64_decodestate; 47 | 48 | void base64_init_decodestate(base64_decodestate* state_in); 49 | 50 | int base64_decode_value(int value_in); 51 | 52 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); 53 | 54 | int base64_decode_chars(const char* code_in, const int length_in, char* plaintext_out); 55 | 56 | #ifdef __cplusplus 57 | } // extern "C" 58 | #endif 59 | 60 | #endif /* BASE64_CDECODE_H */ 61 | -------------------------------------------------------------------------------- /src/libb64/cencode.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | cencode.h - c header for a base64 encoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | 7 | For Teensy41 with QNEthernet 8 | 9 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 10 | 11 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 12 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 13 | 14 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 15 | This file is part of the esp8266 core for Arduino environment. 16 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 17 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 18 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 20 | You should have received a copy of the GNU General Public License along with this program. 21 | If not, see . 22 | *****************************************************************************************************************************/ 23 | 24 | #pragma once 25 | 26 | // Reintroduce to prevent duplication compile error if other lib/core already has LIB64 27 | // pragma once can't prevent that 28 | #ifndef BASE64_CENCODE_H 29 | #define BASE64_CENCODE_H 30 | 31 | #define base64_encode_expected_len(n) ((((4 * n) / 3) + 3) & ~3) 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | typedef enum 38 | { 39 | step_A, step_B, step_C 40 | } base64_encodestep; 41 | 42 | typedef struct 43 | { 44 | base64_encodestep step; 45 | char result; 46 | int stepcount; 47 | } base64_encodestate; 48 | 49 | void base64_init_encodestate(base64_encodestate* state_in); 50 | 51 | char base64_encode_value(char value_in); 52 | 53 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); 54 | 55 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in); 56 | 57 | int base64_encode_chars(const char* plaintext_in, int length_in, char* code_out); 58 | 59 | #ifdef __cplusplus 60 | } // extern "C" 61 | #endif 62 | 63 | #endif /* BASE64_CENCODE_H */ 64 | -------------------------------------------------------------------------------- /src/AsyncWebServer_Teensy41.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncWebServer_Teensy41.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | 11 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 12 | This file is part of the esp8266 core for Arduino environment. 13 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 14 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 | You should have received a copy of the GNU General Public License along with this program. 18 | If not, see . 19 | 20 | Version: 1.7.0 21 | 22 | Version Modified By Date Comments 23 | ------- ----------- ---------- ----------- 24 | 1.4.1 K Hoang 18/03/2022 Initial coding for Teensy 4.1 using built-in QNEthernet. 25 | Bump up version to v1.4.1 to sync with AsyncWebServer_STM32 v1.4.1 26 | 1.5.0 K Hoang 01/10/2022 Fix issue with slow browsers or network. Add function and example to support favicon.ico 27 | 1.6.0 K Hoang 06/10/2022 Option to use non-destroyed cString instead of String to save Heap 28 | 1.6.1 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks 29 | 1.6.2 K Hoang 16/01/2023 Add examples Async_WebSocketsServer 30 | 1.7.0 K Hoang 29/01/2024 Fix file upload handler by adjusting function signatures 31 | *****************************************************************************************************************************/ 32 | 33 | #ifndef _ASYNC_WEBSERVER_TEENSY41_H_ 34 | #define _ASYNC_WEBSERVER_TEENSY41_H_ 35 | 36 | ///////////////////////////////////////////////// 37 | 38 | #include 39 | 40 | #include "AsyncWebServer_Teensy41.hpp" 41 | 42 | #include "AsyncWebResponseImpl_Teensy41.h" 43 | #include "AsyncWebHandlerImpl_Teensy41.h" 44 | #include "AsyncWebSocket_Teensy41.h" 45 | #include "AsyncEventSource_Teensy41.h" 46 | 47 | ///////////////////////////////////////////////// 48 | 49 | #endif /* _ASYNC_WEBSERVER_TEENSY41_H_ */ 50 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to AsyncWebServer_Teensy41 2 | 3 | ### Reporting Bugs 4 | 5 | Please report bugs in AsyncWebServer_Teensy41 if you find them. 6 | 7 | However, before reporting a bug please check through the following: 8 | 9 | * [Existing Open Issues](https://github.com/khoih-prog/AsyncWebServer_Teensy41/issues) - someone might have already encountered this. 10 | 11 | If you don't find anything, please [open a new issue](https://github.com/khoih-prog/AsyncWebServer_Teensy41/issues/new). 12 | 13 | --- 14 | 15 | ### How to submit a bug report 16 | 17 | Please ensure to specify the following: 18 | 19 | * Arduino IDE version (e.g. 1.8.19) or Platform.io version 20 | * `Teensyduino` Core Version (e.g. `Teensyduino core v1.57`) 21 | * `QNEthernet` library version (e.g. `QNEthernet v0.26.0`) 22 | * Board type and relevant info 23 | * Contextual information (e.g. what you were trying to achieve) 24 | * Simplest possible steps to reproduce 25 | * Anything that might be relevant in your opinion, such as: 26 | * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` 27 | * Network configuration 28 | 29 | Please be educated, civilized and constructive as you've always been. Disrespective posts against [GitHub Code of Conduct](https://docs.github.com/en/site-policy/github-terms/github-event-code-of-conduct) will be ignored and deleted. 30 | 31 | --- 32 | 33 | ### Example 34 | 35 | ``` 36 | Arduino IDE version: 1.8.19 37 | Teensyduino core v1.57 38 | Teensy 4.1 using QNEthernet v0.26.0 39 | OS: Ubuntu 20.04 LTS 40 | Linux xy-Inspiron-3593 5.15.0-92-generic #102~20.04.1-Ubuntu SMP Mon Jan 15 13:09:14 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux 41 | 42 | Context: 43 | I encountered a crash while using this library 44 | Steps to reproduce: 45 | 1. ... 46 | 2. ... 47 | 3. ... 48 | 4. ... 49 | ``` 50 | 51 | ### Additional context 52 | 53 | Add any other context about the problem here. 54 | 55 | --- 56 | 57 | ### Sending Feature Requests 58 | 59 | Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. 60 | 61 | There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/AsyncWebServer_Teensy41/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 62 | 63 | --- 64 | 65 | ### Sending Pull Requests 66 | 67 | Pull Requests with changes and fixes are also welcome! 68 | 69 | Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) 70 | 71 | 1. Change directory to the library GitHub 72 | 73 | ``` 74 | xy@xy-Inspiron-3593:~$ cd Arduino/xy/AsyncWebServer_Teensy41_GitHub/ 75 | xy@xy-Inspiron-3593:~/Arduino/xy/AsyncWebServer_Teensy41_GitHub$ 76 | ``` 77 | 78 | 2. Issue astyle command 79 | 80 | ``` 81 | xy@xy-Inspiron-3593:~/Arduino/xy/AsyncWebServer_Teensy41_GitHub$ bash utils/restyle.sh 82 | ``` 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/Crypto/Hash.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | @file Hash.cpp 3 | @date 20.05.2015 4 | @author Markus Sattler 5 | 6 | Copyright (c) 2015 Markus Sattler. All rights reserved. 7 | This file is part of the esp8266 core for Arduino environment. 8 | 9 | This library is free software; you can redistribute it and/or 10 | modify it under the terms of the GNU Lesser General Public 11 | License as published by the Free Software Foundation; either 12 | version 2.1 of the License, or (at your option) any later version. 13 | 14 | This library is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | Lesser General Public License for more details. 18 | 19 | You should have received a copy of the GNU Lesser General Public 20 | License along with this library; if not, write to the Free Software 21 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | */ 24 | 25 | #include 26 | #include "bearssl_hash.h" 27 | 28 | #include "Hash.h" 29 | 30 | /** 31 | create a sha1 hash from data 32 | @param data uint8_t 33 | @param size uint32_t 34 | @param hash uint8_t[HASH_BUFFER_SIZE] 35 | */ 36 | void sha1(const uint8_t* data, uint32_t size, uint8_t hash[HASH_BUFFER_SIZE]) 37 | { 38 | br_sha1_context ctx; 39 | 40 | LOGDEBUG0("DATA:"); 41 | 42 | for (uint16_t i = 0; i < size; i++) 43 | { 44 | LOGDEBUG0(data[i]); 45 | } 46 | 47 | LOGDEBUG0("\nDATA:"); 48 | 49 | for (uint16_t i = 0; i < size; i++) 50 | { 51 | LOGDEBUG0((char) data[i]); 52 | 53 | } 54 | 55 | LOGDEBUG0("\n"); 56 | 57 | br_sha1_init(&ctx); 58 | br_sha1_update(&ctx, data, size); 59 | br_sha1_out(&ctx, hash); 60 | 61 | LOGDEBUG0("SHA1:"); 62 | 63 | for (uint16_t i = 0; i < HASH_BUFFER_SIZE; i++) 64 | { 65 | LOGDEBUG0(hash[i]); 66 | } 67 | 68 | LOGDEBUG0("\n"); 69 | } 70 | 71 | void sha1(const char* data, uint32_t size, uint8_t hash[HASH_BUFFER_SIZE]) 72 | { 73 | sha1((const uint8_t *) data, size, hash); 74 | } 75 | 76 | void sha1(const String& data, uint8_t hash[HASH_BUFFER_SIZE]) 77 | { 78 | sha1(data.c_str(), data.length(), hash); 79 | } 80 | 81 | String sha1(const uint8_t* data, uint32_t size) 82 | { 83 | uint8_t hash[HASH_BUFFER_SIZE]; 84 | 85 | String hashStr((const char*)nullptr); 86 | hashStr.reserve(HASH_BUFFER_SIZE * 2 + 1); 87 | 88 | sha1(&data[0], size, &hash[0]); 89 | 90 | for (uint16_t i = 0; i < HASH_BUFFER_SIZE; i++) 91 | { 92 | char hex[3]; 93 | snprintf(hex, sizeof(hex), "%02x", hash[i]); 94 | hashStr += hex; 95 | } 96 | 97 | return hashStr; 98 | } 99 | 100 | String sha1(const char* data, uint32_t size) 101 | { 102 | return sha1((const uint8_t*) data, size); 103 | } 104 | 105 | String sha1(const String& data) 106 | { 107 | return sha1(data.c_str(), data.length()); 108 | } 109 | 110 | -------------------------------------------------------------------------------- /src/AsyncWebAuthentication_Teensy41.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncWebAuthentication_Teensy41.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | 11 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 12 | This file is part of the esp8266 core for Arduino environment. 13 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 14 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 | You should have received a copy of the GNU General Public License along with this program. 18 | If not, see . 19 | 20 | Version: 1.7.0 21 | 22 | Version Modified By Date Comments 23 | ------- ----------- ---------- ----------- 24 | 1.4.1 K Hoang 18/03/2022 Initial coding for Teensy 4.1 using built-in QNEthernet. 25 | Bump up version to v1.4.1 to sync with AsyncWebServer_STM32 v1.4.1 26 | 1.5.0 K Hoang 01/10/2022 Fix issue with slow browsers or network. Add function and example to support favicon.ico 27 | 1.6.0 K Hoang 06/10/2022 Option to use non-destroyed cString instead of String to save Heap 28 | 1.6.1 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks 29 | 1.6.2 K Hoang 16/01/2023 Add examples Async_WebSocketsServer 30 | 1.7.0 K Hoang 29/01/2024 Fix file upload handler by adjusting function signatures 31 | *****************************************************************************************************************************/ 32 | 33 | #pragma once 34 | 35 | #ifndef ASYNCWEB_AUTHENTICATION_TEENSY41_H_ 36 | #define ASYNCWEB_AUTHENTICATION_TEENSY41_H_ 37 | 38 | #include "Arduino.h" 39 | #include "AsyncWebServer_Teensy41_Debug.h" 40 | 41 | ///////////////////////////////////////////////// 42 | 43 | bool checkBasicAuthentication(const char * header, const char * username, const char * password); 44 | 45 | String requestDigestAuthentication(const char * realm); 46 | 47 | bool checkDigestAuthentication(const char * header, const char * method, const char * username, const char * password, 48 | const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri); 49 | 50 | //for storing hashed versions on the device that can be authenticated against 51 | String generateDigestHash(const char * username, const char * password, const char * realm); 52 | 53 | ///////////////////////////////////////////////// 54 | 55 | #endif // ASYNCWEB_AUTHENTICATION_TEENSY41_H_ 56 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Describe the bug 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | ### Steps to Reproduce 15 | 16 | Steps to reproduce the behavior. Including the [MRE](https://stackoverflow.com/help/minimal-reproducible-example) sketches 17 | 18 | ### Expected behavior 19 | 20 | A clear and concise description of what you expected to happen. 21 | 22 | ### Actual behavior 23 | 24 | A clear and concise description of what you expected to happen. 25 | 26 | ### Debug and AT-command log (if applicable) 27 | 28 | A clear and concise description of what you expected to happen. 29 | 30 | ### Screenshots 31 | 32 | If applicable, add screenshots to help explain your problem. 33 | 34 | --- 35 | 36 | ### Information 37 | 38 | Please ensure to specify the following: 39 | 40 | * Arduino IDE version (e.g. 1.8.19) or Platform.io version 41 | * `Teensyduino` Core Version (e.g. `Teensyduino core v1.57`) 42 | * `QNEthernet` library version (e.g. `QNEthernet v0.17.0`) 43 | * Board type and relevant info 44 | * Contextual information (e.g. what you were trying to achieve) 45 | * Simplest possible steps to reproduce 46 | * Anything that might be relevant in your opinion, such as: 47 | * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` 48 | * Network configuration 49 | 50 | Please be educated, civilized and constructive as you've always been. Disrespective posts against [GitHub Code of Conduct](https://docs.github.com/en/site-policy/github-terms/github-event-code-of-conduct) will be ignored and deleted. 51 | 52 | --- 53 | 54 | ### Example 55 | 56 | ``` 57 | Arduino IDE version: 1.8.19 58 | Teensyduino core v1.57 59 | Teensy 4.1 using QNEthernet v0.17.0 60 | OS: Ubuntu 20.04 LTS 61 | Linux xy-Inspiron-3593 5.15.0-58-generic #64~20.04.1-Ubuntu SMP Fri Jan 6 16:42:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux 62 | 63 | Context: 64 | I encountered a crash while using this library 65 | Steps to reproduce: 66 | 1. ... 67 | 2. ... 68 | 3. ... 69 | 4. ... 70 | ``` 71 | 72 | ### Additional context 73 | 74 | Add any other context about the problem here. 75 | 76 | --- 77 | 78 | ### Sending Feature Requests 79 | 80 | Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. 81 | 82 | There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/AsyncWebServer_Teensy41/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 83 | 84 | --- 85 | 86 | ### Sending Pull Requests 87 | 88 | Pull Requests with changes and fixes are also welcome! 89 | 90 | Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) 91 | 92 | 1. Change directory to the library GitHub 93 | 94 | ``` 95 | xy@xy-Inspiron-3593:~$ cd Arduino/xy/AsyncWebServer_Teensy41_GitHub/ 96 | xy@xy-Inspiron-3593:~/Arduino/xy/AsyncWebServer_Teensy41_GitHub$ 97 | ``` 98 | 99 | 2. Issue astyle command 100 | 101 | ``` 102 | xy@xy-Inspiron-3593:~/Arduino/xy/AsyncWebServer_Teensy41_GitHub$ bash utils/restyle.sh 103 | ``` 104 | 105 | -------------------------------------------------------------------------------- /examples/WebClient/WebClient.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | WebClient.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | #include "defines.h" 14 | 15 | char server[] = "arduino.cc"; 16 | 17 | // Initialize the Web client object 18 | EthernetClient client; 19 | 20 | void setup() 21 | { 22 | // Open serial communications and wait for port to open: 23 | Serial.begin(115200); 24 | 25 | while (!Serial && millis() < 5000); 26 | 27 | Serial.print("\nStart WebClient on "); 28 | Serial.print(BOARD_NAME); 29 | Serial.print(" with "); 30 | Serial.println(SHIELD_TYPE); 31 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 32 | 33 | delay(500); 34 | 35 | #if USING_DHCP 36 | // Start the Ethernet connection, using DHCP 37 | Serial.print("Initialize Ethernet using DHCP => "); 38 | Ethernet.begin(); 39 | #else 40 | // Start the Ethernet connection, using static IP 41 | Serial.print("Initialize Ethernet using static IP => "); 42 | Ethernet.begin(myIP, myNetmask, myGW); 43 | Ethernet.setDNSServerIP(mydnsServer); 44 | #endif 45 | 46 | if (!Ethernet.waitForLocalIP(5000)) 47 | { 48 | Serial.println(F("Failed to configure Ethernet")); 49 | 50 | if (!Ethernet.linkStatus()) 51 | { 52 | Serial.println(F("Ethernet cable is not connected.")); 53 | } 54 | 55 | // Stay here forever 56 | while (true) 57 | { 58 | delay(1); 59 | } 60 | } 61 | else 62 | { 63 | Serial.print(F("Connected! IP address:")); 64 | Serial.println(Ethernet.localIP()); 65 | } 66 | 67 | #if USING_DHCP 68 | delay(1000); 69 | #else 70 | delay(2000); 71 | #endif 72 | 73 | Serial.println(); 74 | Serial.println(F("Starting connection to server...")); 75 | 76 | // if you get a connection, report back via serial 77 | if (client.connect(server, 80)) 78 | { 79 | Serial.println(F("Connected to server")); 80 | // Make a HTTP request 81 | client.println(F("GET /asciilogo.txt HTTP/1.1")); 82 | client.println(F("Host: arduino.cc")); 83 | client.println(F("Connection: close")); 84 | client.println(); 85 | } 86 | } 87 | 88 | void printoutData(void) 89 | { 90 | // if there are incoming bytes available 91 | // from the server, read them and print them 92 | while (client.available()) 93 | { 94 | char c = client.read(); 95 | Serial.write(c); 96 | } 97 | } 98 | 99 | void loop() 100 | { 101 | printoutData(); 102 | 103 | // if the server's disconnected, stop the client 104 | if (!client.connected()) 105 | { 106 | Serial.println(); 107 | Serial.println(F("Disconnecting from server...")); 108 | client.stop(); 109 | 110 | // do nothing forevermore 111 | while (true); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/Crypto/md5.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file md5.h 3 | 4 | Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 5 | 6 | Copyright (C) 2009 Paul Bakker 7 | 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | * * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 20 | may be used to endorse or promote products derived from this software 21 | without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #pragma once 37 | 38 | #ifndef LWIP_INCLUDED_POLARSSL_MD5_H 39 | #define LWIP_INCLUDED_POLARSSL_MD5_H 40 | 41 | #include "AsyncWebServer_Teensy41_Debug.h" 42 | 43 | /** 44 | \brief MD5 context structure 45 | */ 46 | typedef struct 47 | { 48 | unsigned long total[2]; /*!< number of bytes processed */ 49 | unsigned long state[4]; /*!< intermediate digest state */ 50 | unsigned char buffer[64]; /*!< data block being processed */ 51 | } 52 | md5_context; 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | /** 59 | \brief MD5 context setup 60 | 61 | \param ctx context to be initialized 62 | */ 63 | void md5_starts( md5_context *ctx ); 64 | 65 | /** 66 | \brief MD5 process buffer 67 | 68 | \param ctx MD5 context 69 | \param input buffer holding the data 70 | \param ilen length of the input data 71 | */ 72 | void md5_update( md5_context *ctx, const unsigned char *input, int ilen ); 73 | 74 | /** 75 | \brief MD5 final digest 76 | 77 | \param ctx MD5 context 78 | \param output MD5 checksum result 79 | */ 80 | void md5_finish( md5_context *ctx, unsigned char output[16] ); 81 | 82 | /** 83 | \brief Output = MD5( input buffer ) 84 | 85 | \param input buffer holding the data 86 | \param ilen length of the input data 87 | \param output MD5 checksum result 88 | */ 89 | void md5( unsigned char *input, int ilen, unsigned char output[16] ); 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | 95 | #endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ 96 | -------------------------------------------------------------------------------- /src/Crypto/sha1.h: -------------------------------------------------------------------------------- 1 | /** 2 | \file sha1.h 3 | 4 | Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 5 | 6 | Copyright (C) 2009 Paul Bakker 7 | 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | * * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 20 | may be used to endorse or promote products derived from this software 21 | without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #pragma once 37 | 38 | #ifndef LWIP_INCLUDED_POLARSSL_SHA1_H 39 | #define LWIP_INCLUDED_POLARSSL_SHA1_H 40 | 41 | #include "AsyncWebServer_Teensy41_Debug.h" 42 | 43 | #ifdef SHA1_BUFFER_SIZE 44 | #undef SHA1_BUFFER_SIZE 45 | #endif 46 | 47 | #define SHA1_BUFFER_SIZE 20 48 | 49 | /** 50 | \brief SHA-1 context structure 51 | */ 52 | typedef struct 53 | { 54 | unsigned long total[2]; /*!< number of bytes processed */ 55 | unsigned long state[5]; /*!< intermediate digest state */ 56 | unsigned char buffer[64]; /*!< data block being processed */ 57 | } 58 | sha1_context; 59 | 60 | #ifdef __cplusplus 61 | extern "C" { 62 | #endif 63 | 64 | /** 65 | \brief SHA-1 context setup 66 | 67 | \param ctx context to be initialized 68 | */ 69 | void sha1_starts( sha1_context *ctx ); 70 | 71 | /** 72 | \brief SHA-1 process buffer 73 | 74 | \param ctx SHA-1 context 75 | \param input buffer holding the data 76 | \param ilen length of the input data 77 | */ 78 | void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ); 79 | 80 | /** 81 | \brief SHA-1 final digest 82 | 83 | \param ctx SHA-1 context 84 | \param output SHA-1 checksum result 85 | */ 86 | void sha1_finish( sha1_context *ctx, unsigned char output[SHA1_BUFFER_SIZE] ); 87 | 88 | /** 89 | \brief Output = SHA-1( input buffer ) 90 | 91 | \param input buffer holding the data 92 | \param ilen length of the input data 93 | \param output SHA-1 checksum result 94 | */ 95 | void sha1( unsigned char *input, int ilen, unsigned char output[SHA1_BUFFER_SIZE] ); 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | #endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ 102 | -------------------------------------------------------------------------------- /src/AsyncWebSynchronization_Teensy41.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncWebSynchronization_Teensy41.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | 11 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 12 | This file is part of the esp8266 core for Arduino environment. 13 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 14 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 | You should have received a copy of the GNU General Public License along with this program. 18 | If not, see . 19 | 20 | Version: 1.7.0 21 | 22 | Version Modified By Date Comments 23 | ------- ----------- ---------- ----------- 24 | 1.4.1 K Hoang 18/03/2022 Initial coding for Teensy 4.1 using built-in QNEthernet. 25 | Bump up version to v1.4.1 to sync with AsyncWebServer_STM32 v1.4.1 26 | 1.5.0 K Hoang 01/10/2022 Fix issue with slow browsers or network. Add function and example to support favicon.ico 27 | 1.6.0 K Hoang 06/10/2022 Option to use non-destroyed cString instead of String to save Heap 28 | 1.6.1 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks 29 | 1.6.2 K Hoang 16/01/2023 Add examples Async_WebSocketsServer 30 | 1.7.0 K Hoang 29/01/2024 Fix file upload handler by adjusting function signatures 31 | *****************************************************************************************************************************/ 32 | 33 | #pragma once 34 | 35 | #ifndef ASYNCWEBSYNCHRONIZATION_TEENSY41_H_ 36 | #define ASYNCWEBSYNCHRONIZATION_TEENSY41_H_ 37 | 38 | // Synchronisation is only available on ESP32, as the ESP8266 isn't using FreeRTOS by default 39 | 40 | #include 41 | 42 | ///////////////////////////////////////////////// 43 | 44 | // This is the Teensy41 version of the Sync Lock which is currently unimplemented 45 | class AsyncWebLock 46 | { 47 | 48 | public: 49 | AsyncWebLock() {} 50 | 51 | ~AsyncWebLock() {} 52 | 53 | ///////////////////////////////////////////////// 54 | 55 | inline bool lock() const 56 | { 57 | return false; 58 | } 59 | 60 | ///////////////////////////////////////////////// 61 | 62 | inline void unlock() const {} 63 | }; 64 | 65 | class AsyncWebLockGuard 66 | { 67 | private: 68 | const AsyncWebLock *_lock; 69 | 70 | public: 71 | 72 | ///////////////////////////////////////////////// 73 | 74 | AsyncWebLockGuard(const AsyncWebLock &l) 75 | { 76 | if (l.lock()) 77 | { 78 | _lock = &l; 79 | } 80 | else 81 | { 82 | _lock = NULL; 83 | } 84 | } 85 | 86 | ///////////////////////////////////////////////// 87 | 88 | ~AsyncWebLockGuard() 89 | { 90 | if (_lock) 91 | { 92 | _lock->unlock(); 93 | } 94 | } 95 | }; 96 | 97 | #endif // ASYNCWEBSYNCHRONIZATION_TEENSY41_H_ 98 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # AsyncWebServer_Teensy41 Library 2 | 3 | [![arduino-library-badge](https://www.ardu-badge.com/badge/AsyncWebServer_Teensy41.svg?)](https://www.ardu-badge.com/AsyncWebServer_Teensy41) 4 | [![GitHub release](https://img.shields.io/github/release/khoih-prog/AsyncWebServer_Teensy41.svg)](https://github.com/khoih-prog/AsyncWebServer_Teensy41/releases) 5 | [![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/khoih-prog/AsyncWebServer_Teensy41/blob/master/LICENSE) 6 | [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) 7 | [![GitHub issues](https://img.shields.io/github/issues/khoih-prog/AsyncWebServer_Teensy41.svg)](http://github.com/khoih-prog/AsyncWebServer_Teensy41/issues) 8 | 9 | Donate to my libraries using BuyMeACoffee 10 | 11 | 12 | 13 | --- 14 | --- 15 | 16 | ## Table of contents 17 | 18 | * [Table of contents](#table-of-contents) 19 | * [Changelog](#changelog) 20 | * [Releases v1.7.0](#releases-v170) 21 | * [Releases v1.6.2](#releases-v162) 22 | * [Releases v1.6.1](#releases-v161) 23 | * [Releases v1.6.0](#releases-v160) 24 | * [Releases v1.5.0](#releases-v150) 25 | * [Releases v1.4.1](#releases-v141) 26 | 27 | --- 28 | --- 29 | 30 | ## Changelog 31 | 32 | ### Releases v1.7.0 33 | 34 | 1. Fix file upload to Teensy 4.1 board based on suggestions made on the PJRC forum. Align signatures of file upload handlers. 35 | For more details, please see this post: [AsyncWebServer_Teensy41 bug onUpload](https://forum.pjrc.com/index.php?threads/asyncwebserver_teensy41-bug-onupload.72220). 36 | 37 | ### Releases v1.6.2 38 | 39 | 1. Add examples [Async_WebSocketsServer](https://github.com/khoih-prog/AsyncWebServer_Teensy41/tree/main/examples/Async_WebSocketsServer) to demo how to use `Async_WebSockets` 40 | 41 | ### Releases v1.6.1 42 | 43 | 1. Add examples [Async_AdvancedWebServer_SendChunked](https://github.com/khoih-prog/AsyncWebServer_Teensy41/tree/main/examples/Async_AdvancedWebServer_SendChunked) and [AsyncWebServer_SendChunked](https://github.com/khoih-prog/AsyncWebServer_Teensy41/tree/main/examples/AsyncWebServer_SendChunked) to demo how to use `beginChunkedResponse()` to send large `html` in chunks 44 | 2. Use `allman astyle` and add `utils` 45 | 46 | 47 | ### Releases v1.6.0 48 | 49 | 1. Support using `CString` to save heap to send `very large data`. Check [request->send(200, textPlainStr, jsonChartDataCharStr); - Without using String Class - to save heap #8](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/pull/8) and [All memmove() removed - string no longer destroyed #11](https://github.com/khoih-prog/Portenta_H7_AsyncWebServer/pull/11) 50 | 2. Add multiple examples to demo the new feature 51 | 52 | ### Releases v1.5.0 53 | 54 | 1. Fix issue with slow browsers or network. Check [Target stops responding after variable time when using Firefox on Windows 10 #3](https://github.com/khoih-prog/AsyncWebServer_RP2040W/issues/3) 55 | 2. Add functions and example `Async_AdvancedWebServer_favicon` to support `favicon.ico` 56 | 57 | ### Releases v1.4.1 58 | 59 | 1. Initial porting and coding for **Teensy 4.1 using built-in QNEthernet** 60 | 2. Bump up version to v1.4.1 to sync with [AsyncWebServer_STM32](https://github.com/khoih-prog/AsyncWebServer_STM32) v1.4.1 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /examples/WebClientRepeating/WebClientRepeating.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | WebClientRepeating.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | #include "defines.h" 14 | 15 | char server[] = "arduino.cc"; 16 | 17 | unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds 18 | const unsigned long postingInterval = 10000L; // delay between updates, in milliseconds 19 | 20 | // Initialize the Web client object 21 | EthernetClient client; 22 | 23 | // this method makes a HTTP connection to the server 24 | void httpRequest() 25 | { 26 | Serial.println(); 27 | 28 | // close any connection before send a new request 29 | // this will free the socket on the WiFi shield 30 | client.stop(); 31 | 32 | // if there's a successful connection 33 | if (client.connect(server, 80)) 34 | { 35 | Serial.println(F("Connecting...")); 36 | 37 | // send the HTTP PUT request 38 | client.println(F("GET /asciilogo.txt HTTP/1.1")); 39 | client.println(F("Host: arduino.cc")); 40 | client.println(F("Connection: close")); 41 | client.println(); 42 | 43 | // note the time that the connection was made 44 | lastConnectionTime = millis(); 45 | } 46 | else 47 | { 48 | // if you couldn't make a connection 49 | Serial.println(F("Connection failed")); 50 | } 51 | } 52 | 53 | void setup() 54 | { 55 | // Open serial communications and wait for port to open: 56 | Serial.begin(115200); 57 | 58 | while (!Serial && millis() < 5000); 59 | 60 | Serial.print("\nStart WebClientRepeating on "); 61 | Serial.print(BOARD_NAME); 62 | Serial.print(" with "); 63 | Serial.println(SHIELD_TYPE); 64 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 65 | 66 | delay(500); 67 | 68 | #if USING_DHCP 69 | // Start the Ethernet connection, using DHCP 70 | Serial.print("Initialize Ethernet using DHCP => "); 71 | Ethernet.begin(); 72 | #else 73 | // Start the Ethernet connection, using static IP 74 | Serial.print("Initialize Ethernet using static IP => "); 75 | Ethernet.begin(myIP, myNetmask, myGW); 76 | Ethernet.setDNSServerIP(mydnsServer); 77 | #endif 78 | 79 | if (!Ethernet.waitForLocalIP(5000)) 80 | { 81 | Serial.println(F("Failed to configure Ethernet")); 82 | 83 | if (!Ethernet.linkStatus()) 84 | { 85 | Serial.println(F("Ethernet cable is not connected.")); 86 | } 87 | 88 | // Stay here forever 89 | while (true) 90 | { 91 | delay(1); 92 | } 93 | } 94 | else 95 | { 96 | Serial.print(F("Connected! IP address:")); 97 | Serial.println(Ethernet.localIP()); 98 | } 99 | 100 | #if USING_DHCP 101 | delay(1000); 102 | #else 103 | delay(2000); 104 | #endif 105 | } 106 | 107 | void loop() 108 | { 109 | // if there's incoming data from the net connection send it out the serial port 110 | // this is for debugging purposes only 111 | while (client.available()) 112 | { 113 | char c = client.read(); 114 | Serial.write(c); 115 | } 116 | 117 | // if 10 seconds have passed since your last connection, 118 | // then connect again and send data 119 | if (millis() - lastConnectionTime > postingInterval) 120 | { 121 | httpRequest(); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /examples/Async_HttpBasicAuth/Async_HttpBasicAuth.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_HttpBasicAuth.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 14 | #error Only Teensy 4.1 supported 15 | #endif 16 | 17 | // Debug Level from 0 to 4 18 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 19 | #define _AWS_TEENSY41_LOGLEVEL_ 1 20 | 21 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 22 | 23 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 24 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 25 | #endif 26 | 27 | #define USING_DHCP true 28 | //#define USING_DHCP false 29 | 30 | #if !USING_DHCP 31 | // Set the static IP address to use if the DHCP fails to assign 32 | IPAddress myIP(192, 168, 2, 222); 33 | IPAddress myNetmask(255, 255, 255, 0); 34 | IPAddress myGW(192, 168, 2, 1); 35 | //IPAddress mydnsServer(192, 168, 2, 1); 36 | IPAddress mydnsServer(8, 8, 8, 8); 37 | #endif 38 | 39 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 40 | using namespace qindesign::network; 41 | 42 | #include 43 | 44 | AsyncWebServer server(80); 45 | 46 | const char* www_username = "admin"; 47 | const char* www_password = "ethernet"; 48 | 49 | void setup() 50 | { 51 | Serial.begin(115200); 52 | 53 | while (!Serial && millis() < 5000); 54 | 55 | delay(200); 56 | 57 | Serial.print("\nStart Async_HTTPBasicAuth on "); 58 | Serial.print(BOARD_NAME); 59 | Serial.print(" with "); 60 | Serial.println(SHIELD_TYPE); 61 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 62 | 63 | delay(500); 64 | 65 | #if USING_DHCP 66 | // Start the Ethernet connection, using DHCP 67 | Serial.print("Initialize Ethernet using DHCP => "); 68 | Ethernet.begin(); 69 | #else 70 | // Start the Ethernet connection, using static IP 71 | Serial.print("Initialize Ethernet using static IP => "); 72 | Ethernet.begin(myIP, myNetmask, myGW); 73 | Ethernet.setDNSServerIP(mydnsServer); 74 | #endif 75 | 76 | if (!Ethernet.waitForLocalIP(5000)) 77 | { 78 | Serial.println(F("Failed to configure Ethernet")); 79 | 80 | if (!Ethernet.linkStatus()) 81 | { 82 | Serial.println(F("Ethernet cable is not connected.")); 83 | } 84 | 85 | // Stay here forever 86 | while (true) 87 | { 88 | delay(1); 89 | } 90 | } 91 | else 92 | { 93 | Serial.print(F("Connected! IP address:")); 94 | Serial.println(Ethernet.localIP()); 95 | } 96 | 97 | #if USING_DHCP 98 | delay(1000); 99 | #else 100 | delay(2000); 101 | #endif 102 | 103 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 104 | { 105 | if (!request->authenticate(www_username, www_password)) 106 | { 107 | return request->requestAuthentication(); 108 | } 109 | 110 | request->send(200, "text/plain", "Login OK"); 111 | }); 112 | 113 | 114 | server.begin(); 115 | 116 | Serial.print(F("Async_HttpBasicAuth started @ IP : ")); 117 | Serial.println(Ethernet.localIP()); 118 | 119 | Serial.print(F("Open http://")); 120 | Serial.print(Ethernet.localIP()); 121 | Serial.println(F("/ in your browser to see it working")); 122 | 123 | Serial.print(F("Login using username = ")); 124 | Serial.print(www_username); 125 | Serial.print(F(" and password = ")); 126 | Serial.println(www_password); 127 | } 128 | 129 | void loop() 130 | { 131 | } 132 | -------------------------------------------------------------------------------- /examples/Async_HelloServer/Async_HelloServer.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_HelloServer.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 14 | #error Only Teensy 4.1 supported 15 | #endif 16 | 17 | // Debug Level from 0 to 4 18 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 19 | #define _AWS_TEENSY41_LOGLEVEL_ 1 20 | 21 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 22 | 23 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 24 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 25 | #endif 26 | 27 | #define USING_DHCP true 28 | //#define USING_DHCP false 29 | 30 | #if !USING_DHCP 31 | // Set the static IP address to use if the DHCP fails to assign 32 | IPAddress myIP(192, 168, 2, 222); 33 | IPAddress myNetmask(255, 255, 255, 0); 34 | IPAddress myGW(192, 168, 2, 1); 35 | //IPAddress mydnsServer(192, 168, 2, 1); 36 | IPAddress mydnsServer(8, 8, 8, 8); 37 | #endif 38 | 39 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 40 | using namespace qindesign::network; 41 | 42 | #include 43 | 44 | AsyncWebServer server(80); 45 | 46 | const int led = 13; 47 | 48 | void handleRoot(AsyncWebServerRequest *request) 49 | { 50 | digitalWrite(led, 1); 51 | request->send(200, "text/plain", String("Hello from AsyncWebServer_Teensy41 on ") + BOARD_NAME ); 52 | digitalWrite(led, 0); 53 | } 54 | 55 | void handleNotFound(AsyncWebServerRequest *request) 56 | { 57 | digitalWrite(led, 1); 58 | String message = "File Not Found\n\n"; 59 | 60 | message += "URI: "; 61 | //message += server.uri(); 62 | message += request->url(); 63 | message += "\nMethod: "; 64 | message += (request->method() == HTTP_GET) ? "GET" : "POST"; 65 | message += "\nArguments: "; 66 | message += request->args(); 67 | message += "\n"; 68 | 69 | for (uint8_t i = 0; i < request->args(); i++) 70 | { 71 | message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; 72 | } 73 | 74 | request->send(404, "text/plain", message); 75 | digitalWrite(led, 0); 76 | } 77 | 78 | void setup() 79 | { 80 | pinMode(led, OUTPUT); 81 | digitalWrite(led, 0); 82 | 83 | Serial.begin(115200); 84 | 85 | while (!Serial && millis() < 5000); 86 | 87 | delay(200); 88 | 89 | Serial.print("\nStart Async_HelloServer on "); 90 | Serial.print(BOARD_NAME); 91 | Serial.print(" with "); 92 | Serial.println(SHIELD_TYPE); 93 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 94 | 95 | delay(500); 96 | 97 | #if USING_DHCP 98 | // Start the Ethernet connection, using DHCP 99 | Serial.print("Initialize Ethernet using DHCP => "); 100 | Ethernet.begin(); 101 | #else 102 | // Start the Ethernet connection, using static IP 103 | Serial.print("Initialize Ethernet using static IP => "); 104 | Ethernet.begin(myIP, myNetmask, myGW); 105 | Ethernet.setDNSServerIP(mydnsServer); 106 | #endif 107 | 108 | if (!Ethernet.waitForLocalIP(5000)) 109 | { 110 | Serial.println(F("Failed to configure Ethernet")); 111 | 112 | if (!Ethernet.linkStatus()) 113 | { 114 | Serial.println(F("Ethernet cable is not connected.")); 115 | } 116 | 117 | // Stay here forever 118 | while (true) 119 | { 120 | delay(1); 121 | } 122 | } 123 | else 124 | { 125 | Serial.print(F("Connected! IP address:")); 126 | Serial.println(Ethernet.localIP()); 127 | } 128 | 129 | #if USING_DHCP 130 | delay(1000); 131 | #else 132 | delay(2000); 133 | #endif 134 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 135 | { 136 | handleRoot(request); 137 | }); 138 | 139 | server.on("/inline", [](AsyncWebServerRequest * request) 140 | { 141 | request->send(200, "text/plain", "This works as well"); 142 | }); 143 | 144 | server.onNotFound(handleNotFound); 145 | 146 | server.begin(); 147 | 148 | Serial.print(F("HTTP EthernetWebServer is @ IP : ")); 149 | Serial.println(Ethernet.localIP()); 150 | } 151 | 152 | void loop() 153 | { 154 | } 155 | -------------------------------------------------------------------------------- /Packages_Patches/hardware/teensy/avr/cores/teensy/Stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.h - base class for character-based streams. 3 | Copyright (c) 2010 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Stream_h 21 | #define Stream_h 22 | 23 | #include 24 | #include "Print.h" 25 | 26 | class Stream : public Print 27 | { 28 | public: 29 | constexpr Stream() : _timeout(1000), read_error(0) {} 30 | virtual int available() = 0; 31 | virtual int read() = 0; 32 | virtual int peek() = 0; 33 | 34 | void setTimeout(unsigned long timeout); 35 | bool find(const char *target); 36 | 37 | bool find(const uint8_t *target) 38 | { 39 | return find ((const char *)target); 40 | } 41 | 42 | bool find(const String &target) 43 | { 44 | return find(target.c_str()); 45 | } 46 | 47 | bool find(const char *target, size_t length); 48 | 49 | bool find(const uint8_t *target, size_t length) 50 | { 51 | return find ((const char *)target, length); 52 | } 53 | 54 | bool find(const String &target, size_t length) 55 | { 56 | return find(target.c_str(), length); 57 | } 58 | 59 | bool findUntil(const char *target, const char *terminator); 60 | 61 | bool findUntil(const uint8_t *target, const char *terminator) 62 | { 63 | return findUntil((const char *)target, terminator); 64 | } 65 | 66 | bool findUntil(const String &target, const char *terminator) 67 | { 68 | return findUntil(target.c_str(), terminator); 69 | } 70 | 71 | bool findUntil(const char *target, const String &terminator) 72 | { 73 | return findUntil(target, terminator.c_str()); 74 | } 75 | 76 | bool findUntil(const String &target, const String &terminator) 77 | { 78 | return findUntil(target.c_str(), terminator.c_str()); 79 | } 80 | 81 | bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen); 82 | 83 | bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen) 84 | { 85 | return findUntil((const char *)target, targetLen, terminate, termLen); 86 | } 87 | 88 | bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen); 89 | bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen); 90 | bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen); 91 | 92 | long parseInt(); 93 | long parseInt(char skipChar); 94 | 95 | float parseFloat(); 96 | float parseFloat(char skipChar); 97 | 98 | size_t readBytes(char *buffer, size_t length); 99 | 100 | size_t readBytes(uint8_t *buffer, size_t length) 101 | { 102 | return readBytes((char *)buffer, length); 103 | } 104 | 105 | size_t readBytesUntil(char terminator, char *buffer, size_t length); 106 | 107 | size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length) 108 | { 109 | return readBytesUntil(terminator, (char *)buffer, length); 110 | } 111 | 112 | //////////////////////////////////////////////////////////// 113 | String readString(size_t max = 512); 114 | String readStringUntil(char terminator, size_t max = 512); 115 | 116 | // KH, to not use String 117 | char* readCharsUntil(char terminator, size_t max = 512); 118 | //////////////////////////////////////////////////////////// 119 | 120 | int getReadError() 121 | { 122 | return read_error; 123 | } 124 | 125 | void clearReadError() 126 | { 127 | setReadError(0); 128 | } 129 | 130 | protected: 131 | void setReadError(int err = 1) 132 | { 133 | read_error = err; 134 | } 135 | 136 | unsigned long _timeout; 137 | 138 | // KH 139 | int timedRead(); 140 | int timedPeek(); 141 | int peekNextDigit(); 142 | ////// 143 | 144 | private: 145 | char read_error; 146 | }; 147 | 148 | #endif 149 | 150 | -------------------------------------------------------------------------------- /Packages_Patches/hardware/teensy/avr/cores/teensy3/Stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.h - base class for character-based streams. 3 | Copyright (c) 2010 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Stream_h 21 | #define Stream_h 22 | 23 | #include 24 | #include "Print.h" 25 | 26 | class Stream : public Print 27 | { 28 | public: 29 | constexpr Stream() : _timeout(1000), read_error(0) {} 30 | virtual int available() = 0; 31 | virtual int read() = 0; 32 | virtual int peek() = 0; 33 | 34 | void setTimeout(unsigned long timeout); 35 | bool find(const char *target); 36 | 37 | bool find(const uint8_t *target) 38 | { 39 | return find ((const char *)target); 40 | } 41 | 42 | bool find(const String &target) 43 | { 44 | return find(target.c_str()); 45 | } 46 | 47 | bool find(const char *target, size_t length); 48 | 49 | bool find(const uint8_t *target, size_t length) 50 | { 51 | return find ((const char *)target, length); 52 | } 53 | 54 | bool find(const String &target, size_t length) 55 | { 56 | return find(target.c_str(), length); 57 | } 58 | 59 | bool findUntil(const char *target, const char *terminator); 60 | 61 | bool findUntil(const uint8_t *target, const char *terminator) 62 | { 63 | return findUntil((const char *)target, terminator); 64 | } 65 | 66 | bool findUntil(const String &target, const char *terminator) 67 | { 68 | return findUntil(target.c_str(), terminator); 69 | } 70 | 71 | bool findUntil(const char *target, const String &terminator) 72 | { 73 | return findUntil(target, terminator.c_str()); 74 | } 75 | 76 | bool findUntil(const String &target, const String &terminator) 77 | { 78 | return findUntil(target.c_str(), terminator.c_str()); 79 | } 80 | 81 | bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen); 82 | 83 | bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen) 84 | { 85 | return findUntil((const char *)target, targetLen, terminate, termLen); 86 | } 87 | 88 | bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen); 89 | bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen); 90 | bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen); 91 | 92 | long parseInt(); 93 | long parseInt(char skipChar); 94 | 95 | float parseFloat(); 96 | float parseFloat(char skipChar); 97 | 98 | size_t readBytes(char *buffer, size_t length); 99 | 100 | size_t readBytes(uint8_t *buffer, size_t length) 101 | { 102 | return readBytes((char *)buffer, length); 103 | } 104 | 105 | size_t readBytesUntil(char terminator, char *buffer, size_t length); 106 | 107 | size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length) 108 | { 109 | return readBytesUntil(terminator, (char *)buffer, length); 110 | } 111 | 112 | //////////////////////////////////////////////////////////// 113 | String readString(size_t max = 512); 114 | String readStringUntil(char terminator, size_t max = 512); 115 | 116 | // KH, to not use String 117 | char* readCharsUntil(char terminator, size_t max = 512); 118 | //////////////////////////////////////////////////////////// 119 | 120 | int getReadError() 121 | { 122 | return read_error; 123 | } 124 | 125 | void clearReadError() 126 | { 127 | setReadError(0); 128 | } 129 | 130 | protected: 131 | void setReadError(int err = 1) 132 | { 133 | read_error = err; 134 | } 135 | 136 | unsigned long _timeout; 137 | 138 | // KH 139 | int timedRead(); 140 | int timedPeek(); 141 | int peekNextDigit(); 142 | ////// 143 | 144 | private: 145 | char read_error; 146 | }; 147 | 148 | #endif 149 | 150 | -------------------------------------------------------------------------------- /Packages_Patches/hardware/teensy/avr/cores/teensy4/Stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.h - base class for character-based streams. 3 | Copyright (c) 2010 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Stream_h 21 | #define Stream_h 22 | 23 | #include 24 | #include "Print.h" 25 | 26 | class Stream : public Print 27 | { 28 | public: 29 | constexpr Stream() : _timeout(1000), read_error(0) {} 30 | virtual int available() = 0; 31 | virtual int read() = 0; 32 | virtual int peek() = 0; 33 | 34 | void setTimeout(unsigned long timeout); 35 | bool find(const char *target); 36 | 37 | bool find(const uint8_t *target) 38 | { 39 | return find ((const char *)target); 40 | } 41 | 42 | bool find(const String &target) 43 | { 44 | return find(target.c_str()); 45 | } 46 | 47 | bool find(const char *target, size_t length); 48 | 49 | bool find(const uint8_t *target, size_t length) 50 | { 51 | return find ((const char *)target, length); 52 | } 53 | 54 | bool find(const String &target, size_t length) 55 | { 56 | return find(target.c_str(), length); 57 | } 58 | 59 | bool findUntil(const char *target, const char *terminator); 60 | 61 | bool findUntil(const uint8_t *target, const char *terminator) 62 | { 63 | return findUntil((const char *)target, terminator); 64 | } 65 | 66 | bool findUntil(const String &target, const char *terminator) 67 | { 68 | return findUntil(target.c_str(), terminator); 69 | } 70 | 71 | bool findUntil(const char *target, const String &terminator) 72 | { 73 | return findUntil(target, terminator.c_str()); 74 | } 75 | 76 | bool findUntil(const String &target, const String &terminator) 77 | { 78 | return findUntil(target.c_str(), terminator.c_str()); 79 | } 80 | 81 | bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen); 82 | 83 | bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen) 84 | { 85 | return findUntil((const char *)target, targetLen, terminate, termLen); 86 | } 87 | 88 | bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen); 89 | bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen); 90 | bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen); 91 | 92 | long parseInt(); 93 | long parseInt(char skipChar); 94 | 95 | float parseFloat(); 96 | float parseFloat(char skipChar); 97 | 98 | size_t readBytes(char *buffer, size_t length); 99 | 100 | size_t readBytes(uint8_t *buffer, size_t length) 101 | { 102 | return readBytes((char *)buffer, length); 103 | } 104 | 105 | size_t readBytesUntil(char terminator, char *buffer, size_t length); 106 | 107 | size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length) 108 | { 109 | return readBytesUntil(terminator, (char *)buffer, length); 110 | } 111 | 112 | //////////////////////////////////////////////////////////// 113 | String readString(size_t max = 512); 114 | String readStringUntil(char terminator, size_t max = 512); 115 | 116 | // KH, to not use String 117 | char* readCharsUntil(char terminator, size_t max = 512); 118 | //////////////////////////////////////////////////////////// 119 | 120 | int getReadError() 121 | { 122 | return read_error; 123 | } 124 | 125 | void clearReadError() 126 | { 127 | setReadError(0); 128 | } 129 | 130 | protected: 131 | void setReadError(int err = 1) 132 | { 133 | read_error = err; 134 | } 135 | 136 | unsigned long _timeout; 137 | 138 | // KH 139 | int timedRead(); 140 | int timedPeek(); 141 | int peekNextDigit(); 142 | ////// 143 | 144 | private: 145 | char read_error; 146 | }; 147 | 148 | #endif 149 | 150 | -------------------------------------------------------------------------------- /examples/Async_SimpleWebServer/Async_SimpleWebServer.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_SimpleWebServer.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | // 14 | // A simple server implementation showing how to: 15 | // * serve static messages 16 | // * read GET and POST parameters 17 | // * handle missing pages / 404s 18 | // 19 | 20 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 21 | #error Only Teensy 4.1 supported 22 | #endif 23 | 24 | // Debug Level from 0 to 4 25 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 26 | #define _AWS_TEENSY41_LOGLEVEL_ 1 27 | 28 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 29 | 30 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 31 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 32 | #endif 33 | 34 | #define USING_DHCP true 35 | //#define USING_DHCP false 36 | 37 | #if !USING_DHCP 38 | // Set the static IP address to use if the DHCP fails to assign 39 | IPAddress myIP(192, 168, 2, 222); 40 | IPAddress myNetmask(255, 255, 255, 0); 41 | IPAddress myGW(192, 168, 2, 1); 42 | //IPAddress mydnsServer(192, 168, 2, 1); 43 | IPAddress mydnsServer(8, 8, 8, 8); 44 | #endif 45 | 46 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 47 | using namespace qindesign::network; 48 | 49 | #include 50 | 51 | AsyncWebServer server(80); 52 | 53 | const char* PARAM_MESSAGE = "message"; 54 | 55 | void notFound(AsyncWebServerRequest *request) 56 | { 57 | request->send(404, "text/plain", "Not found"); 58 | } 59 | 60 | void setup() 61 | { 62 | Serial.begin(115200); 63 | 64 | while (!Serial && millis() < 5000); 65 | 66 | Serial.print("\nStart Async_SimpleWebServer on "); 67 | Serial.print(BOARD_NAME); 68 | Serial.print(" with "); 69 | Serial.println(SHIELD_TYPE); 70 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 71 | 72 | delay(500); 73 | 74 | #if USING_DHCP 75 | // Start the Ethernet connection, using DHCP 76 | Serial.print("Initialize Ethernet using DHCP => "); 77 | Ethernet.begin(); 78 | #else 79 | // Start the Ethernet connection, using static IP 80 | Serial.print("Initialize Ethernet using static IP => "); 81 | Ethernet.begin(myIP, myNetmask, myGW); 82 | Ethernet.setDNSServerIP(mydnsServer); 83 | #endif 84 | 85 | if (!Ethernet.waitForLocalIP(5000)) 86 | { 87 | Serial.println(F("Failed to configure Ethernet")); 88 | 89 | if (!Ethernet.linkStatus()) 90 | { 91 | Serial.println(F("Ethernet cable is not connected.")); 92 | } 93 | 94 | // Stay here forever 95 | while (true) 96 | { 97 | delay(1); 98 | } 99 | } 100 | else 101 | { 102 | Serial.print(F("Connected! IP address:")); 103 | Serial.println(Ethernet.localIP()); 104 | } 105 | 106 | #if USING_DHCP 107 | delay(1000); 108 | #else 109 | delay(2000); 110 | #endif 111 | 112 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 113 | { 114 | request->send(200, "text/plain", "Hello, world from Teensy 4.1 and QNEthernet"); 115 | }); 116 | 117 | // Send a GET request to /get?message= 118 | server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) 119 | { 120 | String message; 121 | 122 | if (request->hasParam(PARAM_MESSAGE)) 123 | { 124 | message = request->getParam(PARAM_MESSAGE)->value(); 125 | } 126 | else 127 | { 128 | message = "No message sent"; 129 | } 130 | 131 | request->send(200, "text/plain", "Hello, GET: " + message); 132 | }); 133 | 134 | // Send a POST request to /post with a form field message set to 135 | server.on("/post", HTTP_POST, [](AsyncWebServerRequest * request) 136 | { 137 | String message; 138 | 139 | if (request->hasParam(PARAM_MESSAGE, true)) 140 | { 141 | message = request->getParam(PARAM_MESSAGE, true)->value(); 142 | } 143 | else 144 | { 145 | message = "No message sent"; 146 | } 147 | 148 | request->send(200, "text/plain", "Hello, POST: " + message); 149 | }); 150 | 151 | server.onNotFound(notFound); 152 | 153 | server.begin(); 154 | 155 | Serial.print("Server started @ "); 156 | Serial.println(Ethernet.localIP()); 157 | } 158 | 159 | void loop() 160 | { 161 | } 162 | -------------------------------------------------------------------------------- /examples/Async_RegexPatterns/Async_RegexPatterns.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_RegexPatterns.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | // 14 | // A simple server implementation with regex routes: 15 | // * serve static messages 16 | // * read GET and POST parameters 17 | // * handle missing pages / 404s 18 | // 19 | // Add buildflag ASYNCWEBSERVER_REGEX to enable the regex support 20 | // 21 | // For platformio: platformio.ini: 22 | // build_flags = 23 | // -DASYNCWEBSERVER_REGEX 24 | // 25 | // For arduino IDE: create/update platform.local.txt 26 | // Windows: C:\Users\(username)\AppData\Local\Arduino15\packages\espxxxx\hardware\espxxxx\{version}\platform.local.txt 27 | // Linux: ~/.arduino15/packages/espxxxx/hardware/espxxxx/{version}/platform.local.txt 28 | // 29 | // compiler.cpp.extra_flags=-DASYNCWEBSERVER_REGEX=1 30 | 31 | #define ASYNCWEBSERVER_REGEX true 32 | 33 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 34 | #error Only Teensy 4.1 supported 35 | #endif 36 | 37 | // Debug Level from 0 to 4 38 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 39 | #define _AWS_TEENSY41_LOGLEVEL_ 1 40 | 41 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 42 | 43 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 44 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 45 | #endif 46 | 47 | #define USING_DHCP true 48 | //#define USING_DHCP false 49 | 50 | #if !USING_DHCP 51 | // Set the static IP address to use if the DHCP fails to assign 52 | IPAddress myIP(192, 168, 2, 222); 53 | IPAddress myNetmask(255, 255, 255, 0); 54 | IPAddress myGW(192, 168, 2, 1); 55 | //IPAddress mydnsServer(192, 168, 2, 1); 56 | IPAddress mydnsServer(8, 8, 8, 8); 57 | #endif 58 | 59 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 60 | using namespace qindesign::network; 61 | 62 | #include 63 | 64 | AsyncWebServer server(80); 65 | 66 | const char* PARAM_MESSAGE = "message"; 67 | 68 | void notFound(AsyncWebServerRequest *request) 69 | { 70 | request->send(404, "text/plain", "Not found"); 71 | } 72 | 73 | void setup() 74 | { 75 | Serial.begin(115200); 76 | 77 | while (!Serial && millis() < 5000); 78 | 79 | Serial.print("\nStart Async_RegexPatterns on "); 80 | Serial.print(BOARD_NAME); 81 | Serial.print(" with "); 82 | Serial.println(SHIELD_TYPE); 83 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 84 | 85 | delay(500); 86 | 87 | #if USING_DHCP 88 | // Start the Ethernet connection, using DHCP 89 | Serial.print("Initialize Ethernet using DHCP => "); 90 | Ethernet.begin(); 91 | #else 92 | // Start the Ethernet connection, using static IP 93 | Serial.print("Initialize Ethernet using static IP => "); 94 | Ethernet.begin(myIP, myNetmask, myGW); 95 | Ethernet.setDNSServerIP(mydnsServer); 96 | #endif 97 | 98 | if (!Ethernet.waitForLocalIP(5000)) 99 | { 100 | Serial.println(F("Failed to configure Ethernet")); 101 | 102 | if (!Ethernet.linkStatus()) 103 | { 104 | Serial.println(F("Ethernet cable is not connected.")); 105 | } 106 | 107 | // Stay here forever 108 | while (true) 109 | { 110 | delay(1); 111 | } 112 | } 113 | else 114 | { 115 | Serial.print(F("Connected! IP address:")); 116 | Serial.println(Ethernet.localIP()); 117 | } 118 | 119 | #if USING_DHCP 120 | delay(1000); 121 | #else 122 | delay(2000); 123 | #endif 124 | 125 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 126 | { 127 | request->send(200, "text/plain", "Hello, world from Async_RegexPatterns on " + String(BOARD_NAME)); 128 | }); 129 | 130 | // Send a GET request to /sensor/ 131 | server.on("^\\/sensor\\/([0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest * request) 132 | { 133 | String sensorNumber = request->pathArg(0); 134 | request->send(200, "text/plain", "Hello, sensor: " + sensorNumber); 135 | }); 136 | 137 | // Send a GET request to /sensor//action/ 138 | server.on("^\\/sensor\\/([0-9]+)\\/action\\/([a-zA-Z0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest * request) 139 | { 140 | String sensorNumber = request->pathArg(0); 141 | String action = request->pathArg(1); 142 | request->send(200, "text/plain", "Hello, sensor: " + sensorNumber + ", with action: " + action); 143 | }); 144 | 145 | server.onNotFound(notFound); 146 | 147 | server.begin(); 148 | 149 | Serial.print("Server started @ "); 150 | Serial.println(Ethernet.localIP()); 151 | } 152 | 153 | void loop() 154 | { 155 | } 156 | -------------------------------------------------------------------------------- /src/libb64/cencode.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | cencode.c - c source to a base64 encoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | 7 | For Teensy41 with QNEthernet 8 | 9 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 10 | 11 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 12 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 13 | 14 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 15 | This file is part of the esp8266 core for Arduino environment. 16 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 17 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 18 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 20 | You should have received a copy of the GNU General Public License along with this program. 21 | If not, see . 22 | *****************************************************************************************************************************/ 23 | 24 | #include "cencode.h" 25 | 26 | const int CHARS_PER_LINE = 72; 27 | 28 | void base64_init_encodestate(base64_encodestate* state_in) 29 | { 30 | state_in->step = step_A; 31 | state_in->result = 0; 32 | state_in->stepcount = 0; 33 | } 34 | 35 | char base64_encode_value(char value_in) 36 | { 37 | static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 38 | 39 | if (value_in > 63) 40 | return '='; 41 | 42 | return encoding[(unsigned int)value_in]; 43 | } 44 | 45 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) 46 | { 47 | const char* plainchar = plaintext_in; 48 | const char* const plaintextend = plaintext_in + length_in; 49 | char* codechar = code_out; 50 | char result; 51 | char fragment; 52 | 53 | result = state_in->result; 54 | 55 | switch (state_in->step) 56 | { 57 | while (1) 58 | { 59 | case step_A: 60 | if (plainchar == plaintextend) 61 | { 62 | state_in->result = result; 63 | state_in->step = step_A; 64 | return codechar - code_out; 65 | } 66 | 67 | fragment = *plainchar++; 68 | result = (fragment & 0x0fc) >> 2; 69 | *codechar++ = base64_encode_value(result); 70 | result = (fragment & 0x003) << 4; 71 | 72 | // fall through 73 | 74 | case step_B: 75 | if (plainchar == plaintextend) 76 | { 77 | state_in->result = result; 78 | state_in->step = step_B; 79 | return codechar - code_out; 80 | } 81 | 82 | fragment = *plainchar++; 83 | result |= (fragment & 0x0f0) >> 4; 84 | *codechar++ = base64_encode_value(result); 85 | result = (fragment & 0x00f) << 2; 86 | 87 | // fall through 88 | 89 | case step_C: 90 | if (plainchar == plaintextend) 91 | { 92 | state_in->result = result; 93 | state_in->step = step_C; 94 | return codechar - code_out; 95 | } 96 | 97 | fragment = *plainchar++; 98 | result |= (fragment & 0x0c0) >> 6; 99 | *codechar++ = base64_encode_value(result); 100 | result = (fragment & 0x03f) >> 0; 101 | *codechar++ = base64_encode_value(result); 102 | 103 | ++(state_in->stepcount); 104 | 105 | if (state_in->stepcount == CHARS_PER_LINE / 4) 106 | { 107 | *codechar++ = '\n'; 108 | state_in->stepcount = 0; 109 | } 110 | 111 | // fall through 112 | } 113 | } 114 | 115 | /* control should not reach here */ 116 | return codechar - code_out; 117 | } 118 | 119 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in) 120 | { 121 | char* codechar = code_out; 122 | 123 | switch (state_in->step) 124 | { 125 | case step_B: 126 | *codechar++ = base64_encode_value(state_in->result); 127 | *codechar++ = '='; 128 | *codechar++ = '='; 129 | break; 130 | 131 | case step_C: 132 | *codechar++ = base64_encode_value(state_in->result); 133 | *codechar++ = '='; 134 | break; 135 | 136 | case step_A: 137 | break; 138 | } 139 | 140 | *codechar = 0x00; 141 | 142 | return codechar - code_out; 143 | } 144 | 145 | int base64_encode_chars(const char* plaintext_in, int length_in, char* code_out) 146 | { 147 | base64_encodestate _state; 148 | base64_init_encodestate(&_state); 149 | int len = base64_encode_block(plaintext_in, length_in, code_out, &_state); 150 | 151 | return len + base64_encode_blockend((code_out + len), &_state); 152 | } 153 | -------------------------------------------------------------------------------- /src/libb64/cdecode.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | cdecode.c - c source to a base64 decoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | 7 | For Teensy41 with QNEthernet 8 | 9 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 10 | 11 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 12 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 13 | 14 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 15 | This file is part of the esp8266 core for Arduino environment. 16 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 17 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 18 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 20 | You should have received a copy of the GNU General Public License along with this program. 21 | If not, see . 22 | *****************************************************************************************************************************/ 23 | 24 | #include "cdecode.h" 25 | 26 | int base64_decode_value(int value_in) 27 | { 28 | static const char decoding[] = 29 | { 30 | 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, 31 | 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, 32 | -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 33 | 47, 48, 49, 50, 51 34 | }; 35 | 36 | static const char decoding_size = sizeof(decoding); 37 | value_in -= 43; 38 | 39 | if (value_in < 0 || value_in > decoding_size) 40 | return -1; 41 | 42 | return decoding[(int)value_in]; 43 | } 44 | 45 | void base64_init_decodestate(base64_decodestate* state_in) 46 | { 47 | state_in->step = step_a; 48 | state_in->plainchar = 0; 49 | } 50 | 51 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in) 52 | { 53 | const char* codechar = code_in; 54 | char* plainchar = plaintext_out; 55 | int fragment; 56 | 57 | *plainchar = state_in->plainchar; 58 | 59 | switch (state_in->step) 60 | { 61 | while (1) 62 | { 63 | case step_a: 64 | do 65 | { 66 | if (codechar == code_in + length_in) 67 | { 68 | state_in->step = step_a; 69 | state_in->plainchar = *plainchar; 70 | return plainchar - plaintext_out; 71 | } 72 | 73 | fragment = base64_decode_value(*codechar++); 74 | } while (fragment < 0); 75 | 76 | *plainchar = (fragment & 0x03f) << 2; 77 | 78 | // fall through 79 | 80 | case step_b: 81 | do 82 | { 83 | if (codechar == code_in + length_in) 84 | { 85 | state_in->step = step_b; 86 | state_in->plainchar = *plainchar; 87 | return plainchar - plaintext_out; 88 | } 89 | 90 | fragment = base64_decode_value(*codechar++); 91 | } while (fragment < 0); 92 | 93 | *plainchar++ |= (fragment & 0x030) >> 4; 94 | *plainchar = (fragment & 0x00f) << 4; 95 | 96 | // fall through 97 | 98 | case step_c: 99 | do 100 | { 101 | if (codechar == code_in + length_in) 102 | { 103 | state_in->step = step_c; 104 | state_in->plainchar = *plainchar; 105 | return plainchar - plaintext_out; 106 | } 107 | 108 | fragment = base64_decode_value(*codechar++); 109 | } while (fragment < 0); 110 | 111 | *plainchar++ |= (fragment & 0x03c) >> 2; 112 | *plainchar = (fragment & 0x003) << 6; 113 | 114 | // fall through 115 | 116 | case step_d: 117 | do 118 | { 119 | if (codechar == code_in + length_in) 120 | { 121 | state_in->step = step_d; 122 | state_in->plainchar = *plainchar; 123 | return plainchar - plaintext_out; 124 | } 125 | 126 | fragment = base64_decode_value(*codechar++); 127 | } while (fragment < 0); 128 | 129 | *plainchar++ |= (fragment & 0x03f); 130 | 131 | // fall through 132 | } 133 | } 134 | 135 | /* control should not reach here */ 136 | return plainchar - plaintext_out; 137 | } 138 | 139 | int base64_decode_chars(const char* code_in, const int length_in, char* plaintext_out) 140 | { 141 | 142 | base64_decodestate _state; 143 | base64_init_decodestate(&_state); 144 | int len = base64_decode_block(code_in, length_in, plaintext_out, &_state); 145 | 146 | if (len > 0) 147 | plaintext_out[len] = 0; 148 | 149 | return len; 150 | } 151 | -------------------------------------------------------------------------------- /examples/Async_AdvancedWebServer_favicon/favicon.h: -------------------------------------------------------------------------------- 1 | /*! \file 2 | \brief Favicon stored in progmem. 3 | 4 | `#include "favicon.h"` then 5 | @code 6 | // Serve favicon from PROGMEM: #include 7 | HTTP.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest * request) { 8 | AsyncWebServerResponse *response = request->beginResponse_P(200, "image/x-icon", favicon_ico_gz, favicon_ico_gz_len); 9 | response->addHeader("Content-Encoding", "gzip"); 10 | request->send(response); 11 | }); 12 | @endcode 13 | */ 14 | 15 | #pragma once 16 | 17 | /* 18 | 19 | Provided from me-no-dev Async WebServer for ESP8266 20 | https://github.com/me-no-dev/ESPAsyncWebServer 21 | 22 | */ 23 | 24 | //File: favicon.ico.gz, Size: 726 25 | #define favicon_ico_gz_len 726 26 | const uint8_t favicon_ico_gz[] /*PROGMEM*/ = 27 | { 28 | 0x1F, 0x8B, 0x08, 0x08, 0x0B, 0x87, 0x90, 0x57, 0x00, 0x03, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6F, 29 | 0x6E, 0x2E, 0x69, 0x63, 0x6F, 0x00, 0xCD, 0x53, 0x5F, 0x48, 0x9A, 0x51, 0x14, 0xBF, 0x62, 0x6D, 30 | 0x86, 0x96, 0xA9, 0x64, 0xD3, 0xFE, 0xA8, 0x99, 0x65, 0x1A, 0xB4, 0x8A, 0xA8, 0x51, 0x54, 0x23, 31 | 0xA8, 0x11, 0x49, 0x51, 0x8A, 0x34, 0x62, 0x93, 0x85, 0x31, 0x58, 0x44, 0x12, 0x45, 0x2D, 0x58, 32 | 0xF5, 0x52, 0x41, 0x10, 0x23, 0x82, 0xA0, 0x20, 0x98, 0x2F, 0xC1, 0x26, 0xED, 0xA1, 0x20, 0x89, 33 | 0x04, 0xD7, 0x83, 0x58, 0x20, 0x28, 0x04, 0xAB, 0xD1, 0x9B, 0x8C, 0xE5, 0xC3, 0x60, 0x32, 0x64, 34 | 0x0E, 0x56, 0xBF, 0x9D, 0xEF, 0xF6, 0x30, 0x82, 0xED, 0xAD, 0x87, 0xDD, 0x8F, 0xF3, 0xDD, 0x8F, 35 | 0x73, 0xCF, 0xEF, 0x9C, 0xDF, 0x39, 0xBF, 0xFB, 0x31, 0x26, 0xA2, 0x27, 0x37, 0x97, 0xD1, 0x5B, 36 | 0xCF, 0x9E, 0x67, 0x30, 0xA6, 0x66, 0x8C, 0x99, 0xC9, 0xC8, 0x45, 0x9E, 0x6B, 0x3F, 0x5F, 0x74, 37 | 0xA6, 0x94, 0x5E, 0xDB, 0xFF, 0xB2, 0xE6, 0xE7, 0xE7, 0xF9, 0xDE, 0xD6, 0xD6, 0x96, 0xDB, 0xD8, 38 | 0xD8, 0x78, 0xBF, 0xA1, 0xA1, 0xC1, 0xDA, 0xDC, 0xDC, 0x2C, 0xEB, 0xED, 0xED, 0x15, 0x9B, 0xCD, 39 | 0xE6, 0x4A, 0x83, 0xC1, 0xE0, 0x2E, 0x29, 0x29, 0x99, 0xD6, 0x6A, 0xB5, 0x4F, 0x75, 0x3A, 0x9D, 40 | 0x61, 0x75, 0x75, 0x95, 0xB5, 0xB7, 0xB7, 0xDF, 0xC8, 0xD1, 0xD4, 0xD4, 0xF4, 0xB0, 0xBA, 0xBA, 41 | 0xFA, 0x83, 0xD5, 0x6A, 0xFD, 0x5A, 0x5E, 0x5E, 0x9E, 0x28, 0x2D, 0x2D, 0x0D, 0x10, 0xC6, 0x4B, 42 | 0x98, 0x78, 0x5E, 0x5E, 0xDE, 0x95, 0x42, 0xA1, 0x40, 0x4E, 0x4E, 0xCE, 0x65, 0x76, 0x76, 0xF6, 43 | 0x47, 0xB5, 0x5A, 0x6D, 0x4F, 0x26, 0x93, 0xA2, 0xD6, 0xD6, 0x56, 0x8E, 0x6D, 0x69, 0x69, 0xD1, 44 | 0x11, 0x36, 0x62, 0xB1, 0x58, 0x60, 0x32, 0x99, 0xA0, 0xD7, 0xEB, 0x51, 0x58, 0x58, 0x88, 0xFC, 45 | 0xFC, 0x7C, 0x10, 0x16, 0x02, 0x56, 0x2E, 0x97, 0x43, 0x2A, 0x95, 0x42, 0x2C, 0x16, 0x23, 0x33, 46 | 0x33, 0x33, 0xAE, 0x52, 0xA9, 0x1E, 0x64, 0x65, 0x65, 0x71, 0x7C, 0x7D, 0x7D, 0xBD, 0x93, 0xEA, 47 | 0xFE, 0x30, 0x1A, 0x8D, 0xE8, 0xEC, 0xEC, 0xC4, 0xE2, 0xE2, 0x22, 0x6A, 0x6A, 0x6A, 0x40, 0x39, 48 | 0x41, 0xB5, 0x38, 0x4E, 0xC8, 0x33, 0x3C, 0x3C, 0x0C, 0x87, 0xC3, 0xC1, 0x6B, 0x54, 0x54, 0x54, 49 | 0xBC, 0xE9, 0xEB, 0xEB, 0x93, 0x5F, 0x5C, 0x5C, 0x30, 0x8A, 0x9D, 0x2E, 0x2B, 0x2B, 0xBB, 0xA2, 50 | 0x3E, 0x41, 0xBD, 0x21, 0x1E, 0x8F, 0x63, 0x6A, 0x6A, 0x0A, 0x81, 0x40, 0x00, 0x94, 0x1B, 0x3D, 51 | 0x3D, 0x3D, 0x42, 0x3C, 0x96, 0x96, 0x96, 0x70, 0x7E, 0x7E, 0x8E, 0xE3, 0xE3, 0x63, 0xF8, 0xFD, 52 | 0xFE, 0xB4, 0xD7, 0xEB, 0xF5, 0x8F, 0x8F, 0x8F, 0x5B, 0x68, 0x5E, 0x6F, 0x05, 0xCE, 0xB4, 0xE3, 53 | 0xE8, 0xE8, 0x08, 0x27, 0x27, 0x27, 0xD8, 0xDF, 0xDF, 0xC7, 0xD9, 0xD9, 0x19, 0x6C, 0x36, 0x1B, 54 | 0x36, 0x36, 0x36, 0x38, 0x9F, 0x85, 0x85, 0x05, 0xAC, 0xAF, 0xAF, 0x23, 0x1A, 0x8D, 0x22, 0x91, 55 | 0x48, 0x20, 0x16, 0x8B, 0xFD, 0xDA, 0xDA, 0xDA, 0x7A, 0x41, 0x33, 0x7E, 0x57, 0x50, 0x50, 0x80, 56 | 0x89, 0x89, 0x09, 0x84, 0xC3, 0x61, 0x6C, 0x6F, 0x6F, 0x23, 0x12, 0x89, 0xE0, 0xE0, 0xE0, 0x00, 57 | 0x43, 0x43, 0x43, 0x58, 0x5E, 0x5E, 0xE6, 0x9C, 0x7D, 0x3E, 0x1F, 0x46, 0x47, 0x47, 0x79, 0xBE, 58 | 0xBD, 0xBD, 0x3D, 0xE1, 0x3C, 0x1D, 0x0C, 0x06, 0x9F, 0x10, 0xB7, 0xC7, 0x84, 0x4F, 0xF6, 0xF7, 59 | 0xF7, 0x63, 0x60, 0x60, 0x00, 0x83, 0x83, 0x83, 0x18, 0x19, 0x19, 0xC1, 0xDC, 0xDC, 0x1C, 0x8F, 60 | 0x17, 0x7C, 0xA4, 0x27, 0xE7, 0x34, 0x39, 0x39, 0x89, 0x9D, 0x9D, 0x1D, 0x6E, 0x54, 0xE3, 0x13, 61 | 0xE5, 0x34, 0x11, 0x37, 0x49, 0x51, 0x51, 0xD1, 0x4B, 0xA5, 0x52, 0xF9, 0x45, 0x26, 0x93, 0x5D, 62 | 0x0A, 0xF3, 0x92, 0x48, 0x24, 0xA0, 0x6F, 0x14, 0x17, 0x17, 0xA3, 0xB6, 0xB6, 0x16, 0x5D, 0x5D, 63 | 0x5D, 0x7C, 0x1E, 0xBB, 0xBB, 0xBB, 0x9C, 0xD7, 0xE1, 0xE1, 0x21, 0x42, 0xA1, 0xD0, 0x6B, 0xD2, 64 | 0x45, 0x4C, 0x33, 0x12, 0x34, 0xCC, 0xA0, 0x19, 0x54, 0x92, 0x56, 0x0E, 0xD2, 0xD9, 0x43, 0xF8, 65 | 0xCF, 0x82, 0x56, 0xC2, 0xDC, 0xEB, 0xEA, 0xEA, 0x38, 0x7E, 0x6C, 0x6C, 0x4C, 0xE0, 0xFE, 0x9D, 66 | 0xB8, 0xBF, 0xA7, 0xFA, 0xAF, 0x56, 0x56, 0x56, 0xEE, 0x6D, 0x6E, 0x6E, 0xDE, 0xB8, 0x47, 0x55, 67 | 0x55, 0x55, 0x6C, 0x66, 0x66, 0x46, 0x44, 0xDA, 0x3B, 0x34, 0x1A, 0x4D, 0x94, 0xB0, 0x3F, 0x09, 68 | 0x7B, 0x45, 0xBD, 0xA5, 0x5D, 0x2E, 0x57, 0x8C, 0x7A, 0x73, 0xD9, 0xED, 0xF6, 0x3B, 0x84, 0xFF, 69 | 0xE7, 0x7D, 0xA6, 0x3A, 0x2C, 0x95, 0x4A, 0xB1, 0x8E, 0x8E, 0x0E, 0x6D, 0x77, 0x77, 0xB7, 0xCD, 70 | 0xE9, 0x74, 0x3E, 0x73, 0xBB, 0xDD, 0x8F, 0x3C, 0x1E, 0x8F, 0xE6, 0xF4, 0xF4, 0x94, 0xAD, 0xAD, 71 | 0xAD, 0xDD, 0xDE, 0xCF, 0x73, 0x0B, 0x0B, 0xB8, 0xB6, 0xE0, 0x5D, 0xC6, 0x66, 0xC5, 0xE4, 0x10, 72 | 0x4C, 0xF4, 0xF7, 0xD8, 0x59, 0xF2, 0x7F, 0xA3, 0xB8, 0xB4, 0xFC, 0x0F, 0xEE, 0x37, 0x70, 0xEC, 73 | 0x16, 0x4A, 0x7E, 0x04, 0x00, 0x00 74 | }; 75 | -------------------------------------------------------------------------------- /examples/Async_HelloServer2/Async_HelloServer2.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_HelloServer.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 13 | #error Only Teensy 4.1 supported 14 | #endif 15 | 16 | // Debug Level from 0 to 4 17 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 18 | #define _AWS_TEENSY41_LOGLEVEL_ 1 19 | 20 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 21 | 22 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 23 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 24 | #endif 25 | 26 | #define USING_DHCP true 27 | //#define USING_DHCP false 28 | 29 | #if !USING_DHCP 30 | // Set the static IP address to use if the DHCP fails to assign 31 | IPAddress myIP(192, 168, 2, 222); 32 | IPAddress myNetmask(255, 255, 255, 0); 33 | IPAddress myGW(192, 168, 2, 1); 34 | //IPAddress mydnsServer(192, 168, 2, 1); 35 | IPAddress mydnsServer(8, 8, 8, 8); 36 | #endif 37 | 38 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 39 | using namespace qindesign::network; 40 | 41 | #include 42 | 43 | AsyncWebServer server(80); 44 | 45 | const int led = 13; 46 | 47 | void handleRoot(AsyncWebServerRequest *request) 48 | { 49 | digitalWrite(led, 1); 50 | request->send(200, "text/plain", String("Hello from AsyncWebServer_Teensy41 on ") + BOARD_NAME ); 51 | digitalWrite(led, 0); 52 | } 53 | 54 | void handleNotFound(AsyncWebServerRequest *request) 55 | { 56 | digitalWrite(led, 1); 57 | String message = "File Not Found\n\n"; 58 | 59 | message += "URI: "; 60 | //message += server.uri(); 61 | message += request->url(); 62 | message += "\nMethod: "; 63 | message += (request->method() == HTTP_GET) ? "GET" : "POST"; 64 | message += "\nArguments: "; 65 | message += request->args(); 66 | message += "\n"; 67 | 68 | for (uint8_t i = 0; i < request->args(); i++) 69 | { 70 | message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; 71 | } 72 | 73 | request->send(404, "text/plain", message); 74 | digitalWrite(led, 0); 75 | } 76 | 77 | void setup() 78 | { 79 | pinMode(led, OUTPUT); 80 | digitalWrite(led, 0); 81 | 82 | Serial.begin(115200); 83 | 84 | while (!Serial && millis() < 5000); 85 | 86 | delay(200); 87 | 88 | Serial.print("\nStart Async_HelloServer2 on "); 89 | Serial.print(BOARD_NAME); 90 | Serial.print(" with "); 91 | Serial.println(SHIELD_TYPE); 92 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 93 | 94 | delay(500); 95 | 96 | #if USING_DHCP 97 | // Start the Ethernet connection, using DHCP 98 | Serial.print("Initialize Ethernet using DHCP => "); 99 | Ethernet.begin(); 100 | #else 101 | // Start the Ethernet connection, using static IP 102 | Serial.print("Initialize Ethernet using static IP => "); 103 | Ethernet.begin(myIP, myNetmask, myGW); 104 | Ethernet.setDNSServerIP(mydnsServer); 105 | #endif 106 | 107 | if (!Ethernet.waitForLocalIP(5000)) 108 | { 109 | Serial.println(F("Failed to configure Ethernet")); 110 | 111 | if (!Ethernet.linkStatus()) 112 | { 113 | Serial.println(F("Ethernet cable is not connected.")); 114 | } 115 | 116 | // Stay here forever 117 | while (true) 118 | { 119 | delay(1); 120 | } 121 | } 122 | else 123 | { 124 | Serial.print(F("Connected! IP address:")); 125 | Serial.println(Ethernet.localIP()); 126 | } 127 | 128 | #if USING_DHCP 129 | delay(1000); 130 | #else 131 | delay(2000); 132 | #endif 133 | 134 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 135 | { 136 | handleRoot(request); 137 | }); 138 | 139 | server.on("/inline", [](AsyncWebServerRequest * request) 140 | { 141 | request->send(200, "text/plain", "This works as well"); 142 | }); 143 | 144 | server.on("/gif", [](AsyncWebServerRequest * request) 145 | { 146 | static const uint8_t gif[] = 147 | { 148 | 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x01, 149 | 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, 150 | 0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x19, 0x8c, 0x8f, 0xa9, 0xcb, 0x9d, 151 | 0x00, 0x5f, 0x74, 0xb4, 0x56, 0xb0, 0xb0, 0xd2, 0xf2, 0x35, 0x1e, 0x4c, 152 | 0x0c, 0x24, 0x5a, 0xe6, 0x89, 0xa6, 0x4d, 0x01, 0x00, 0x3b 153 | }; 154 | 155 | char gif_colored[sizeof(gif)]; 156 | 157 | memcpy(gif_colored, gif, sizeof(gif)); 158 | 159 | // Set the background to a random set of colors 160 | gif_colored[16] = millis() % 256; 161 | gif_colored[17] = millis() % 256; 162 | gif_colored[18] = millis() % 256; 163 | 164 | request->send(200, (char *) "image/gif", gif_colored); 165 | }); 166 | 167 | server.onNotFound(handleNotFound); 168 | 169 | server.begin(); 170 | 171 | Serial.print("HTTP EthernetWebServer started @ IP : "); 172 | Serial.println(Ethernet.localIP()); 173 | } 174 | 175 | void loop() 176 | { 177 | } 178 | -------------------------------------------------------------------------------- /examples/MQTTClient_Basic/MQTTClient_Basic.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | MQTTClient_Basic.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | /* 14 | Basic MQTT example (without SSL!) with Authentication 15 | This sketch demonstrates the basic capabilities of the library. 16 | It connects to an MQTT server then: 17 | - providing username and password 18 | - publishes "hello world" to the topic "outTopic" 19 | - subscribes to the topic "inTopic", printing out any messages 20 | it receives. NB - it assumes the received payloads are strings not binary 21 | 22 | It will reconnect to the server if the connection is lost using a blocking 23 | reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to 24 | achieve the same result without blocking the main loop. 25 | */ 26 | 27 | // To remove boolean warnings caused by PubSubClient library 28 | #define boolean bool 29 | 30 | #include "defines.h" 31 | 32 | #include 33 | 34 | // Update these with values suitable for your network. 35 | const char* mqttServer = "broker.emqx.io"; // Broker address 36 | 37 | const char *ID = "MQTTClient_SSL-Client"; // Name of our device, must be unique 38 | const char *TOPIC = "MQTT_Pub"; // Topic to subcribe to 39 | const char *subTopic = "MQTT_Sub"; // Topic to subcribe to 40 | 41 | //IPAddress mqttServer(172, 16, 0, 2); 42 | 43 | void callback(char* topic, byte* payload, unsigned int length) 44 | { 45 | Serial.print("Message arrived ["); 46 | Serial.print(topic); 47 | Serial.print("] "); 48 | 49 | for (unsigned int i = 0; i < length; i++) 50 | { 51 | Serial.print((char)payload[i]); 52 | } 53 | 54 | Serial.println(); 55 | } 56 | 57 | EthernetClient ethClient; 58 | PubSubClient client(mqttServer, 1883, callback, ethClient); 59 | 60 | String data = "Hello from MQTTClient_Basic on " + String(BOARD_NAME) + " with " + String(SHIELD_TYPE); 61 | const char *pubData = data.c_str(); 62 | 63 | void reconnect() 64 | { 65 | // Loop until we're reconnected 66 | while (!client.connected()) 67 | { 68 | Serial.print("Attempting MQTT connection to "); 69 | Serial.print(mqttServer); 70 | 71 | // Attempt to connect 72 | if (client.connect(ID, "try", "try")) 73 | { 74 | Serial.println("...connected"); 75 | 76 | // Once connected, publish an announcement... 77 | client.publish(TOPIC, data.c_str()); 78 | 79 | //Serial.println("Published connection message successfully!"); 80 | //Serial.print("Subcribed to: "); 81 | //Serial.println(subTopic); 82 | 83 | client.subscribe(subTopic); 84 | // for loopback testing 85 | client.subscribe(TOPIC); 86 | } 87 | else 88 | { 89 | Serial.print("...failed, rc="); 90 | Serial.print(client.state()); 91 | Serial.println(" try again in 5 seconds"); 92 | 93 | // Wait 5 seconds before retrying 94 | delay(5000); 95 | } 96 | } 97 | } 98 | 99 | void setup() 100 | { 101 | // Open serial communications and wait for port to open: 102 | Serial.begin(115200); 103 | 104 | while (!Serial && millis() < 5000); 105 | 106 | Serial.print("\nStart MQTTClient_Basic on "); 107 | Serial.print(BOARD_NAME); 108 | Serial.print(" with "); 109 | Serial.println(SHIELD_TYPE); 110 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 111 | 112 | delay(500); 113 | 114 | #if USING_DHCP 115 | // Start the Ethernet connection, using DHCP 116 | Serial.print("Initialize Ethernet using DHCP => "); 117 | Ethernet.begin(); 118 | #else 119 | // Start the Ethernet connection, using static IP 120 | Serial.print("Initialize Ethernet using static IP => "); 121 | Ethernet.begin(myIP, myNetmask, myGW); 122 | Ethernet.setDNSServerIP(mydnsServer); 123 | #endif 124 | 125 | if (!Ethernet.waitForLocalIP(5000)) 126 | { 127 | Serial.println(F("Failed to configure Ethernet")); 128 | 129 | if (!Ethernet.linkStatus()) 130 | { 131 | Serial.println(F("Ethernet cable is not connected.")); 132 | } 133 | 134 | // Stay here forever 135 | while (true) 136 | { 137 | delay(1); 138 | } 139 | } 140 | else 141 | { 142 | Serial.print(F("Connected! IP address:")); 143 | Serial.println(Ethernet.localIP()); 144 | } 145 | 146 | #if USING_DHCP 147 | delay(1000); 148 | #else 149 | delay(2000); 150 | #endif 151 | 152 | client.setServer(mqttServer, 1883); 153 | client.setCallback(callback); 154 | 155 | // Allow the hardware to sort itself out 156 | delay(1500); 157 | } 158 | 159 | #define MQTT_PUBLISH_INTERVAL_MS 5000L 160 | 161 | unsigned long lastMsg = 0; 162 | 163 | void loop() 164 | { 165 | static unsigned long now; 166 | 167 | if (!client.connected()) 168 | { 169 | reconnect(); 170 | } 171 | 172 | // Sending Data 173 | now = millis(); 174 | 175 | if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) 176 | { 177 | lastMsg = now; 178 | 179 | if (!client.publish(TOPIC, pubData)) 180 | { 181 | Serial.println("Message failed to send."); 182 | } 183 | 184 | Serial.print("Message Send : " + String(TOPIC) + " => "); 185 | Serial.println(data); 186 | } 187 | 188 | client.loop(); 189 | } 190 | -------------------------------------------------------------------------------- /examples/MQTTClient_Auth/MQTTClient_Auth.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | MQTTClient_Auth.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | /* 14 | Basic MQTT example (without SSL!) with Authentication 15 | This sketch demonstrates the basic capabilities of the library. 16 | It connects to an MQTT server then: 17 | - providing username and password 18 | - publishes "hello world" to the topic "outTopic" 19 | - subscribes to the topic "inTopic", printing out any messages 20 | it receives. NB - it assumes the received payloads are strings not binary 21 | It will reconnect to the server if the connection is lost using a blocking 22 | reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to 23 | achieve the same result without blocking the main loop. 24 | */ 25 | 26 | // To remove boolean warnings caused by PubSubClient library 27 | #define boolean bool 28 | 29 | #include "defines.h" 30 | 31 | #include 32 | 33 | // Update these with values suitable for your network. 34 | const char* mqttServer = "broker.emqx.io"; // Broker address 35 | 36 | const char *ID = "MQTTClient_Auth"; // Name of our device, must be unique 37 | const char *TOPIC = "MQTT_Pub"; // Topic to subcribe to 38 | const char *subTopic = "MQTT_Sub"; // Topic to subcribe to 39 | 40 | //IPAddress mqttServer(172, 16, 0, 2); 41 | 42 | void callback(char* topic, byte* payload, unsigned int length) 43 | { 44 | Serial.print("Message arrived ["); 45 | Serial.print(topic); 46 | Serial.print("] "); 47 | 48 | for (unsigned int i = 0; i < length; i++) 49 | { 50 | Serial.print((char)payload[i]); 51 | } 52 | 53 | Serial.println(); 54 | } 55 | 56 | EthernetClient ethClient; 57 | PubSubClient client(mqttServer, 1883, callback, ethClient); 58 | 59 | String data = "Hello from MQTTClient_Auth on " + String(BOARD_NAME) + " with " + String(SHIELD_TYPE); 60 | const char *pubData = data.c_str(); 61 | 62 | void reconnect() 63 | { 64 | // Loop until we're reconnected 65 | while (!client.connected()) 66 | { 67 | Serial.print("Attempting MQTT connection to "); 68 | Serial.print(mqttServer); 69 | 70 | // Attempt to connect 71 | if (client.connect("arduino", "try", "try")) 72 | { 73 | Serial.println("...connected"); 74 | 75 | // Once connected, publish an announcement... 76 | client.publish(TOPIC, data.c_str()); 77 | 78 | //Serial.println("Published connection message successfully!"); 79 | //Serial.print("Subcribed to: "); 80 | //Serial.println(subTopic); 81 | 82 | client.subscribe(subTopic); 83 | // for loopback testing 84 | client.subscribe(TOPIC); 85 | } 86 | else 87 | { 88 | Serial.print("...failed, rc="); 89 | Serial.print(client.state()); 90 | Serial.println(" try again in 5 seconds"); 91 | 92 | // Wait 5 seconds before retrying 93 | delay(5000); 94 | } 95 | } 96 | } 97 | 98 | void setup() 99 | { 100 | // Open serial communications and wait for port to open: 101 | Serial.begin(115200); 102 | 103 | while (!Serial && millis() < 5000); 104 | 105 | Serial.print("\nStart MQTTClient_Auth on "); 106 | Serial.print(BOARD_NAME); 107 | Serial.print(" with "); 108 | Serial.println(SHIELD_TYPE); 109 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 110 | 111 | delay(500); 112 | 113 | #if USING_DHCP 114 | // Start the Ethernet connection, using DHCP 115 | Serial.print("Initialize Ethernet using DHCP => "); 116 | Ethernet.begin(); 117 | #else 118 | // Start the Ethernet connection, using static IP 119 | Serial.print("Initialize Ethernet using static IP => "); 120 | Ethernet.begin(myIP, myNetmask, myGW); 121 | Ethernet.setDNSServerIP(mydnsServer); 122 | #endif 123 | 124 | if (!Ethernet.waitForLocalIP(5000)) 125 | { 126 | Serial.println(F("Failed to configure Ethernet")); 127 | 128 | if (!Ethernet.linkStatus()) 129 | { 130 | Serial.println(F("Ethernet cable is not connected.")); 131 | } 132 | 133 | // Stay here forever 134 | while (true) 135 | { 136 | delay(1); 137 | } 138 | } 139 | else 140 | { 141 | Serial.print(F("Connected! IP address:")); 142 | Serial.println(Ethernet.localIP()); 143 | } 144 | 145 | #if USING_DHCP 146 | delay(1000); 147 | #else 148 | delay(2000); 149 | #endif 150 | 151 | // Note - the default maximum packet size is 128 bytes. If the 152 | // combined length of clientId, username and password exceed this use the 153 | // following to increase the buffer size: 154 | // client.setBufferSize(255); 155 | } 156 | 157 | #define MQTT_PUBLISH_INTERVAL_MS 5000L 158 | 159 | unsigned long lastMsg = 0; 160 | 161 | void loop() 162 | { 163 | static unsigned long now; 164 | 165 | if (!client.connected()) 166 | { 167 | reconnect(); 168 | } 169 | 170 | // Sending Data 171 | now = millis(); 172 | 173 | if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) 174 | { 175 | lastMsg = now; 176 | 177 | if (!client.publish(TOPIC, pubData)) 178 | { 179 | Serial.println("Message failed to send."); 180 | } 181 | 182 | Serial.print("Message Send : " + String(TOPIC) + " => "); 183 | Serial.println(data); 184 | } 185 | 186 | client.loop(); 187 | } 188 | -------------------------------------------------------------------------------- /src/AsyncWebHandlers_Teensy41.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncWebHandlers_Teensy41.cpp - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | 11 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 12 | This file is part of the esp8266 core for Arduino environment. 13 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 14 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 | You should have received a copy of the GNU General Public License along with this program. 18 | If not, see . 19 | 20 | Version: 1.7.0 21 | 22 | Version Modified By Date Comments 23 | ------- ----------- ---------- ----------- 24 | 1.4.1 K Hoang 18/03/2022 Initial coding for Teensy 4.1 using built-in QNEthernet. 25 | Bump up version to v1.4.1 to sync with AsyncWebServer_STM32 v1.4.1 26 | 1.5.0 K Hoang 01/10/2022 Fix issue with slow browsers or network. Add function and example to support favicon.ico 27 | 1.6.0 K Hoang 06/10/2022 Option to use non-destroyed cString instead of String to save Heap 28 | 1.6.1 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks 29 | 1.6.2 K Hoang 16/01/2023 Add examples Async_WebSocketsServer 30 | 1.7.0 K Hoang 29/01/2024 Fix file upload handler by adjusting function signatures 31 | *****************************************************************************************************************************/ 32 | 33 | #if !defined(_AWS_TEENSY41_LOGLEVEL_) 34 | #define _AWS_TEENSY41_LOGLEVEL_ 1 35 | #endif 36 | 37 | #include "AsyncWebServer_Teensy41_Debug.h" 38 | 39 | #include "AsyncWebServer_Teensy41.hpp" 40 | #include "AsyncWebHandlerImpl_Teensy41.h" 41 | 42 | ///////////////////////////////////////////////// 43 | 44 | AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, /*FS& fs,*/ const char* path, const char* cache_control) 45 | : _uri(uri), _path(path), _cache_control(cache_control), _last_modified(""), _callback(nullptr) 46 | { 47 | // Ensure leading '/' 48 | if (_uri.length() == 0 || _uri[0] != '/') 49 | _uri = "/" + _uri; 50 | 51 | if (_path.length() == 0 || _path[0] != '/') 52 | _path = "/" + _path; 53 | 54 | // If path ends with '/' we assume a hint that this is a directory to improve performance. 55 | // However - if it does not end with '/' we, can't assume a file, path can still be a directory. 56 | _isDir = _path[_path.length() - 1] == '/'; 57 | 58 | // Remove the trailing '/' so we can handle default file 59 | // Notice that root will be "" not "/" 60 | if (_uri[_uri.length() - 1] == '/') 61 | _uri = _uri.substring(0, _uri.length() - 1); 62 | 63 | if (_path[_path.length() - 1] == '/') 64 | _path = _path.substring(0, _path.length() - 1); 65 | 66 | // Reset stats 67 | _gzipFirst = false; 68 | _gzipStats = 0xF8; 69 | } 70 | 71 | ///////////////////////////////////////////////// 72 | 73 | AsyncStaticWebHandler& AsyncStaticWebHandler::setIsDir(bool isDir) 74 | { 75 | _isDir = isDir; 76 | return *this; 77 | } 78 | 79 | ///////////////////////////////////////////////// 80 | 81 | AsyncStaticWebHandler& AsyncStaticWebHandler::setCacheControl(const char* cache_control) 82 | { 83 | _cache_control = String(cache_control); 84 | 85 | return *this; 86 | } 87 | 88 | ///////////////////////////////////////////////// 89 | 90 | AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_modified) 91 | { 92 | _last_modified = String(last_modified); 93 | 94 | return *this; 95 | } 96 | 97 | ///////////////////////////////////////////////// 98 | 99 | AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(struct tm* last_modified) 100 | { 101 | char result[30]; 102 | 103 | strftime (result, 30, "%a, %d %b %Y %H:%M:%S %Z", last_modified); 104 | 105 | return setLastModified((const char *)result); 106 | } 107 | 108 | ///////////////////////////////////////////////// 109 | 110 | // For Teensy41 111 | AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(time_t last_modified) 112 | { 113 | return setLastModified((struct tm *)gmtime(&last_modified)); 114 | } 115 | 116 | ///////////////////////////////////////////////// 117 | 118 | AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified() 119 | { 120 | time_t last_modified; 121 | 122 | if (time(&last_modified) == 0) //time is not yet set 123 | return *this; 124 | 125 | return setLastModified(last_modified); 126 | } 127 | 128 | ///////////////////////////////////////////////// 129 | 130 | bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest *request) 131 | { 132 | if (request->method() != HTTP_GET 133 | || !request->url().startsWith(_uri) 134 | || !request->isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP) 135 | ) 136 | { 137 | return false; 138 | } 139 | 140 | return false; 141 | } 142 | 143 | ///////////////////////////////////////////////// 144 | 145 | // For Teensy41 146 | #define FILE_IS_REAL(f) (f == true) 147 | 148 | ///////////////////////////////////////////////// 149 | 150 | uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const 151 | { 152 | uint8_t w = value; 153 | uint8_t n; 154 | 155 | for (n = 0; w != 0; n++) 156 | w &= w - 1; 157 | 158 | return n; 159 | } 160 | -------------------------------------------------------------------------------- /src/AsyncWebServer_Teensy41_Debug.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncWebServer_Teensy41_Debug.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | 11 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 12 | This file is part of the esp8266 core for Arduino environment. 13 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 14 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 | You should have received a copy of the GNU General Public License along with this program. 18 | If not, see . 19 | 20 | Version: 1.7.0 21 | 22 | Version Modified By Date Comments 23 | ------- ----------- ---------- ----------- 24 | 1.4.1 K Hoang 18/03/2022 Initial coding for Teensy 4.1 using built-in QNEthernet. 25 | Bump up version to v1.4.1 to sync with AsyncWebServer_STM32 v1.4.1 26 | 1.5.0 K Hoang 01/10/2022 Fix issue with slow browsers or network. Add function and example to support favicon.ico 27 | 1.6.0 K Hoang 06/10/2022 Option to use non-destroyed cString instead of String to save Heap 28 | 1.6.1 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks 29 | 1.6.2 K Hoang 16/01/2023 Add examples Async_WebSocketsServer 30 | 1.7.0 K Hoang 29/01/2024 Fix file upload handler by adjusting function signatures 31 | *****************************************************************************************************************************/ 32 | 33 | #pragma once 34 | 35 | #ifndef _ASYNCWEBSERVER_TEENSY41_DEBUG_H_ 36 | #define _ASYNCWEBSERVER_TEENSY41_DEBUG_H_ 37 | 38 | #ifdef ASYNCWEBSERVER_TEENSY41_DEBUG_PORT 39 | #define DBG_PORT_AWS ASYNCWEBSERVER_TEENSY41_DEBUG_PORT 40 | #else 41 | #define DBG_PORT_AWS Serial 42 | #endif 43 | 44 | // Change _AWS_TEENSY41_LOGLEVEL_ to set tracing and logging verbosity 45 | // 0: DISABLED: no logging 46 | // 1: ERROR: errors 47 | // 2: WARN: errors and warnings 48 | // 3: INFO: errors, warnings and informational (default) 49 | // 4: DEBUG: errors, warnings, informational and debug 50 | 51 | #ifndef _AWS_TEENSY41_LOGLEVEL_ 52 | #define _AWS_TEENSY41_LOGLEVEL_ 1 53 | #endif 54 | 55 | ///////////////////////////////////////////////////////// 56 | 57 | #define AWS_PRINT_MARK AWS_PRINT("[AWS] ") 58 | #define AWS_PRINT_SP DBG_PORT_AWS.print(" ") 59 | 60 | #define AWS_PRINT DBG_PORT_AWS.print 61 | #define AWS_PRINTLN DBG_PORT_AWS.println 62 | 63 | ///////////////////////////////////////////////////////// 64 | 65 | #define LOGERROR(x) if(_AWS_TEENSY41_LOGLEVEL_>0) { AWS_PRINT_MARK; AWS_PRINTLN(x); } 66 | #define LOGERROR0(x) if(_AWS_TEENSY41_LOGLEVEL_>0) { AWS_PRINT(x); } 67 | #define LOGERROR1(x,y) if(_AWS_TEENSY41_LOGLEVEL_>0) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINTLN(y); } 68 | #define LOGERROR2(x,y,z) if(_AWS_TEENSY41_LOGLEVEL_>0) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINT(y); AWS_PRINT_SP; AWS_PRINTLN(z); } 69 | #define LOGERROR3(x,y,z,w) if(_AWS_TEENSY41_LOGLEVEL_>0) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINT(y); AWS_PRINT_SP; AWS_PRINT(z); AWS_PRINT_SP; AWS_PRINTLN(w); } 70 | 71 | ///////////////////////////////////////////////////////// 72 | 73 | #define LOGWARN(x) if(_AWS_TEENSY41_LOGLEVEL_>1) { AWS_PRINT_MARK; AWS_PRINTLN(x); } 74 | #define LOGWARN0(x) if(_AWS_TEENSY41_LOGLEVEL_>1) { AWS_PRINT(x); } 75 | #define LOGWARN1(x,y) if(_AWS_TEENSY41_LOGLEVEL_>1) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINTLN(y); } 76 | #define LOGWARN2(x,y,z) if(_AWS_TEENSY41_LOGLEVEL_>1) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINT(y); AWS_PRINT_SP; AWS_PRINTLN(z); } 77 | #define LOGWARN3(x,y,z,w) if(_AWS_TEENSY41_LOGLEVEL_>1) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINT(y); AWS_PRINT_SP; AWS_PRINT(z); AWS_PRINT_SP; AWS_PRINTLN(w); } 78 | 79 | ///////////////////////////////////////////////////////// 80 | 81 | #define LOGINFO(x) if(_AWS_TEENSY41_LOGLEVEL_>2) { AWS_PRINT_MARK; AWS_PRINTLN(x); } 82 | #define LOGINFO0(x) if(_AWS_TEENSY41_LOGLEVEL_>2) { AWS_PRINT(x); } 83 | #define LOGINFO1(x,y) if(_AWS_TEENSY41_LOGLEVEL_>2) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINTLN(y); } 84 | #define LOGINFO2(x,y,z) if(_AWS_TEENSY41_LOGLEVEL_>2) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINT(y); AWS_PRINT_SP; AWS_PRINTLN(z); } 85 | #define LOGINFO3(x,y,z,w) if(_AWS_TEENSY41_LOGLEVEL_>2) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINT(y); AWS_PRINT_SP; AWS_PRINT(z); AWS_PRINT_SP; AWS_PRINTLN(w); } 86 | 87 | ///////////////////////////////////////////////////////// 88 | 89 | #define LOGDEBUG(x) if(_AWS_TEENSY41_LOGLEVEL_>3) { AWS_PRINT_MARK; AWS_PRINTLN(x); } 90 | #define LOGDEBUG0(x) if(_AWS_TEENSY41_LOGLEVEL_>3) { AWS_PRINT(x); } 91 | #define LOGDEBUG1(x,y) if(_AWS_TEENSY41_LOGLEVEL_>3) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINTLN(y); } 92 | #define LOGDEBUG2(x,y,z) if(_AWS_TEENSY41_LOGLEVEL_>3) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINT(y); AWS_PRINT_SP; AWS_PRINTLN(z); } 93 | #define LOGDEBUG3(x,y,z,w) if(_AWS_TEENSY41_LOGLEVEL_>3) { AWS_PRINT_MARK; AWS_PRINT(x); AWS_PRINT_SP; AWS_PRINT(y); AWS_PRINT_SP; AWS_PRINT(z); AWS_PRINT_SP; AWS_PRINTLN(w); } 94 | 95 | ///////////////////////////////////////////////////////// 96 | 97 | #endif //_ASYNCWEBSERVER_TEENSY41_DEBUG_H_ 98 | -------------------------------------------------------------------------------- /examples/Async_PostServer/Async_PostServer.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_PostServer.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 14 | #error Only Teensy 4.1 supported 15 | #endif 16 | 17 | // Debug Level from 0 to 4 18 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 19 | #define _AWS_TEENSY41_LOGLEVEL_ 1 20 | 21 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 22 | 23 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 24 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 25 | #endif 26 | 27 | #define USING_DHCP true 28 | //#define USING_DHCP false 29 | 30 | #if !USING_DHCP 31 | // Set the static IP address to use if the DHCP fails to assign 32 | IPAddress myIP(192, 168, 2, 222); 33 | IPAddress myNetmask(255, 255, 255, 0); 34 | IPAddress myGW(192, 168, 2, 1); 35 | //IPAddress mydnsServer(192, 168, 2, 1); 36 | IPAddress mydnsServer(8, 8, 8, 8); 37 | #endif 38 | 39 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 40 | using namespace qindesign::network; 41 | 42 | #include 43 | 44 | AsyncWebServer server(80); 45 | 46 | const int led = 13; 47 | 48 | const String postForms = 49 | "\ 50 | \ 51 | AsyncWebServer POST handling\ 52 | \ 55 | \ 56 | \ 57 |

POST plain text to /postplain/


\ 58 |
\ 59 |
\ 60 | \ 61 |
\ 62 |

POST form data to /postform/


\ 63 |
\ 64 |
\ 65 | \ 66 |
\ 67 | \ 68 | "; 69 | 70 | void handleRoot(AsyncWebServerRequest *request) 71 | { 72 | digitalWrite(led, 1); 73 | request->send(200, "text/html", postForms); 74 | digitalWrite(led, 0); 75 | } 76 | 77 | void handlePlain(AsyncWebServerRequest *request) 78 | { 79 | if (request->method() != HTTP_POST) 80 | { 81 | digitalWrite(led, 1); 82 | request->send(405, "text/plain", "Method Not Allowed"); 83 | digitalWrite(led, 0); 84 | } 85 | else 86 | { 87 | digitalWrite(led, 1); 88 | request->send(200, "text/plain", "POST body was:\n" + request->arg("plain")); 89 | digitalWrite(led, 0); 90 | } 91 | } 92 | 93 | void handleForm(AsyncWebServerRequest *request) 94 | { 95 | if (request->method() != HTTP_POST) 96 | { 97 | digitalWrite(led, 1); 98 | request->send(405, "text/plain", "Method Not Allowed"); 99 | digitalWrite(led, 0); 100 | } 101 | else 102 | { 103 | digitalWrite(led, 1); 104 | String message = "POST form was:\n"; 105 | 106 | for (uint8_t i = 0; i < request->args(); i++) 107 | { 108 | message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; 109 | } 110 | 111 | request->send(200, "text/plain", message); 112 | digitalWrite(led, 0); 113 | } 114 | } 115 | 116 | void handleNotFound(AsyncWebServerRequest *request) 117 | { 118 | digitalWrite(led, 1); 119 | String message = "File Not Found\n\n"; 120 | message += "URI: "; 121 | message += request->url(); 122 | message += "\nMethod: "; 123 | message += (request->method() == HTTP_GET) ? "GET" : "POST"; 124 | message += "\nArguments: "; 125 | message += request->args(); 126 | message += "\n"; 127 | 128 | for (uint8_t i = 0; i < request->args(); i++) 129 | { 130 | message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; 131 | } 132 | 133 | request->send(404, "text/plain", message); 134 | digitalWrite(led, 0); 135 | } 136 | 137 | void setup() 138 | { 139 | pinMode(led, OUTPUT); 140 | digitalWrite(led, 0); 141 | 142 | Serial.begin(115200); 143 | 144 | while (!Serial && millis() < 5000); 145 | 146 | delay(200); 147 | 148 | Serial.print("\nStart Async_PostServer on "); 149 | Serial.print(BOARD_NAME); 150 | Serial.print(" with "); 151 | Serial.println(SHIELD_TYPE); 152 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 153 | 154 | delay(500); 155 | 156 | #if USING_DHCP 157 | // Start the Ethernet connection, using DHCP 158 | Serial.print("Initialize Ethernet using DHCP => "); 159 | Ethernet.begin(); 160 | #else 161 | // Start the Ethernet connection, using static IP 162 | Serial.print("Initialize Ethernet using static IP => "); 163 | Ethernet.begin(myIP, myNetmask, myGW); 164 | Ethernet.setDNSServerIP(mydnsServer); 165 | #endif 166 | 167 | if (!Ethernet.waitForLocalIP(5000)) 168 | { 169 | Serial.println(F("Failed to configure Ethernet")); 170 | 171 | if (!Ethernet.linkStatus()) 172 | { 173 | Serial.println(F("Ethernet cable is not connected.")); 174 | } 175 | 176 | // Stay here forever 177 | while (true) 178 | { 179 | delay(1); 180 | } 181 | } 182 | else 183 | { 184 | Serial.print(F("Connected! IP address:")); 185 | Serial.println(Ethernet.localIP()); 186 | } 187 | 188 | #if USING_DHCP 189 | delay(1000); 190 | #else 191 | delay(2000); 192 | #endif 193 | 194 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 195 | { 196 | handleRoot(request); 197 | }); 198 | 199 | //server.on("/postplain/", handlePlain); 200 | server.on("/postplain/", HTTP_POST, [](AsyncWebServerRequest * request) 201 | { 202 | handlePlain(request); 203 | }); 204 | 205 | //server.on("/postform/", handleForm); 206 | server.on("/postform/", HTTP_POST, [](AsyncWebServerRequest * request) 207 | { 208 | handleForm(request); 209 | }); 210 | 211 | server.onNotFound(handleNotFound); 212 | 213 | server.begin(); 214 | 215 | Serial.print(F("HTTP EthernetWebServer started @ IP : ")); 216 | Serial.println(Ethernet.localIP()); 217 | } 218 | 219 | void loop() 220 | { 221 | } 222 | -------------------------------------------------------------------------------- /examples/AsyncMultiWebServer/AsyncMultiWebServer.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncMultiWebServer.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 14 | #error Only Teensy 4.1 supported 15 | #endif 16 | 17 | // Debug Level from 0 to 4 18 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 19 | #define _AWS_TEENSY41_LOGLEVEL_ 1 20 | 21 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 22 | 23 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 24 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 25 | #endif 26 | 27 | #define USING_DHCP true 28 | //#define USING_DHCP false 29 | 30 | #if !USING_DHCP 31 | // Set the static IP address to use if the DHCP fails to assign 32 | IPAddress myIP(192, 168, 2, 222); 33 | IPAddress myNetmask(255, 255, 255, 0); 34 | IPAddress myGW(192, 168, 2, 1); 35 | //IPAddress mydnsServer(192, 168, 2, 1); 36 | IPAddress mydnsServer(8, 8, 8, 8); 37 | #endif 38 | 39 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 40 | using namespace qindesign::network; 41 | 42 | #include 43 | 44 | unsigned int analogReadPin [] = { 12, 13, 14 }; 45 | 46 | #define BUFFER_SIZE 500 47 | 48 | #define HTTP_PORT1 8080 49 | #define HTTP_PORT2 8081 50 | #define HTTP_PORT3 8082 51 | 52 | AsyncWebServer* server1; 53 | AsyncWebServer* server2; 54 | AsyncWebServer* server3; 55 | 56 | AsyncWebServer* multiServer [] = { server1, server2, server3 }; 57 | uint16_t http_port [] = { HTTP_PORT1, HTTP_PORT2, HTTP_PORT3 }; 58 | 59 | #define NUM_SERVERS ( sizeof(multiServer) / sizeof(AsyncWebServer*) ) 60 | 61 | unsigned int serverIndex; 62 | 63 | String createBuffer() 64 | { 65 | char temp[BUFFER_SIZE]; 66 | 67 | memset(temp, 0, sizeof(temp)); 68 | 69 | int sec = millis() / 1000; 70 | int min = sec / 60; 71 | int hr = min / 60; 72 | int day = hr / 24; 73 | 74 | snprintf(temp, BUFFER_SIZE - 1, 75 | "\ 76 | \ 77 | \ 78 | %s\ 79 | \ 82 | \ 83 | \ 84 |

Hello from %s

\ 85 |

running AsyncWebServer_Teensy41

\ 86 |

on %s

\ 87 |

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

\ 88 | \ 89 | ", BOARD_NAME, BOARD_NAME, SHIELD_TYPE, day, hr, min % 60, sec % 60); 90 | 91 | return temp; 92 | } 93 | 94 | 95 | void handleRoot(AsyncWebServerRequest * request) 96 | { 97 | String message = createBuffer(); 98 | request->send(200, F("text/html"), message); 99 | } 100 | 101 | String createNotFoundBuffer(AsyncWebServerRequest * request) 102 | { 103 | String message; 104 | 105 | message.reserve(500); 106 | 107 | message = F("File Not Found\n\n"); 108 | 109 | message += F("URI: "); 110 | message += request->url(); 111 | message += F("\nMethod: "); 112 | message += (request->method() == HTTP_GET) ? F("GET") : F("POST"); 113 | message += F("\nArguments: "); 114 | message += request->args(); 115 | message += F("\n"); 116 | 117 | for (uint8_t i = 0; i < request->args(); i++) 118 | { 119 | message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; 120 | } 121 | 122 | return message; 123 | } 124 | 125 | void handleNotFound(AsyncWebServerRequest * request) 126 | { 127 | String message = createNotFoundBuffer(request); 128 | request->send(404, F("text/plain"), message); 129 | } 130 | 131 | void setup() 132 | { 133 | Serial.begin(115200); 134 | 135 | while (!Serial && millis() < 5000); 136 | 137 | delay(200); 138 | 139 | Serial.print("\nStart AsyncMultiWebServer on "); 140 | Serial.print(BOARD_NAME); 141 | Serial.print(" with "); 142 | Serial.println(SHIELD_TYPE); 143 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 144 | 145 | delay(500); 146 | 147 | #if USING_DHCP 148 | // Start the Ethernet connection, using DHCP 149 | Serial.print("Initialize Ethernet using DHCP => "); 150 | Ethernet.begin(); 151 | #else 152 | // Start the Ethernet connection, using static IP 153 | Serial.print("Initialize Ethernet using static IP => "); 154 | Ethernet.begin(myIP, myNetmask, myGW); 155 | Ethernet.setDNSServerIP(mydnsServer); 156 | #endif 157 | 158 | if (!Ethernet.waitForLocalIP(5000)) 159 | { 160 | Serial.println(F("Failed to configure Ethernet")); 161 | 162 | if (!Ethernet.linkStatus()) 163 | { 164 | Serial.println(F("Ethernet cable is not connected.")); 165 | } 166 | 167 | // Stay here forever 168 | while (true) 169 | { 170 | delay(1); 171 | } 172 | } 173 | else 174 | { 175 | Serial.print(F("Connected! IP address:")); 176 | Serial.println(Ethernet.localIP()); 177 | } 178 | 179 | #if USING_DHCP 180 | delay(1000); 181 | #else 182 | delay(2000); 183 | #endif 184 | 185 | for (serverIndex = 0; serverIndex < NUM_SERVERS; serverIndex++) 186 | { 187 | multiServer[serverIndex] = new AsyncWebServer(http_port[serverIndex]); 188 | 189 | if (multiServer[serverIndex]) 190 | { 191 | Serial.printf("Initialize multiServer OK, serverIndex = %d, port = %d\n", serverIndex, http_port[serverIndex]); 192 | } 193 | else 194 | { 195 | Serial.printf("Error initialize multiServer, serverIndex = %d\n", serverIndex); 196 | 197 | while (1); 198 | } 199 | 200 | multiServer[serverIndex]->on("/", HTTP_GET, [](AsyncWebServerRequest * request) 201 | { 202 | handleRoot(request); 203 | }); 204 | 205 | multiServer[serverIndex]->on("/hello", HTTP_GET, [](AsyncWebServerRequest * request) 206 | { 207 | String message = F("Hello from AsyncWebServer using built-in LAN8742A Ethernet, running on "); 208 | message += BOARD_NAME; 209 | 210 | request->send(200, "text/plain", message); 211 | }); 212 | 213 | multiServer[serverIndex]->onNotFound([](AsyncWebServerRequest * request) 214 | { 215 | handleNotFound(request); 216 | }); 217 | 218 | multiServer[serverIndex]->begin(); 219 | 220 | Serial.printf("HTTP server started at ports %d\n", http_port[serverIndex]); 221 | } 222 | } 223 | 224 | void loop() 225 | { 226 | } 227 | -------------------------------------------------------------------------------- /examples/AsyncWebServer_SendChunked/AsyncWebServer_SendChunked.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncWebServer_SendChunked.ino 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 14 | #error Only Teensy 4.1 supported 15 | #endif 16 | 17 | // Debug Level from 0 to 4 18 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 19 | #define _AWS_TEENSY41_LOGLEVEL_ 4 20 | 21 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 22 | 23 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 24 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 25 | #endif 26 | 27 | #define USING_DHCP true 28 | //#define USING_DHCP false 29 | 30 | #if !USING_DHCP 31 | // Set the static IP address to use if the DHCP fails to assign 32 | IPAddress myIP(192, 168, 2, 222); 33 | IPAddress myNetmask(255, 255, 255, 0); 34 | IPAddress myGW(192, 168, 2, 1); 35 | //IPAddress mydnsServer(192, 168, 2, 1); 36 | IPAddress mydnsServer(8, 8, 8, 8); 37 | #endif 38 | 39 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 40 | using namespace qindesign::network; 41 | 42 | #include 43 | 44 | // In bytes 45 | #define STRING_SIZE 50000 46 | 47 | AsyncWebServer server(80); 48 | 49 | int reqCount = 0; // number of requests received 50 | 51 | #define BUFFER_SIZE 512 52 | char temp[BUFFER_SIZE]; 53 | 54 | void createPage(String &pageInput) 55 | { 56 | int sec = millis() / 1000; 57 | int min = sec / 60; 58 | int hr = min / 60; 59 | int day = hr / 24; 60 | 61 | snprintf(temp, BUFFER_SIZE - 1, 62 | "\ 63 | \ 64 | \ 65 | AsyncWebServer-%s\ 66 | \ 69 | \ 70 | \ 71 |

AsyncWebServer_SendChunked_Teensy41 !

\ 72 |

running on %s

\ 73 |

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

\ 74 | \ 75 | ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); 76 | 77 | pageInput = temp; 78 | } 79 | 80 | void handleNotFound(AsyncWebServerRequest *request) 81 | { 82 | String message = "File Not Found\n\n"; 83 | 84 | message += "URI: "; 85 | message += request->url(); 86 | message += "\nMethod: "; 87 | message += (request->method() == HTTP_GET) ? "GET" : "POST"; 88 | message += "\nArguments: "; 89 | message += request->args(); 90 | message += "\n"; 91 | 92 | for (uint8_t i = 0; i < request->args(); i++) 93 | { 94 | message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; 95 | } 96 | 97 | request->send(404, "text/plain", message); 98 | } 99 | 100 | String out; 101 | 102 | void handleRoot(AsyncWebServerRequest *request) 103 | { 104 | out.reserve(STRING_SIZE); 105 | char temp[70]; 106 | 107 | // clear the String to start over 108 | out = String(); 109 | 110 | createPage(out); 111 | 112 | out += "\r\n"; 113 | 114 | for (uint16_t lineIndex = 0; lineIndex < 500; lineIndex++) 115 | { 116 | out += ""; 120 | } 121 | 122 | out += "
INDEXDATA
"; 117 | out += String(lineIndex); 118 | out += ""; 119 | out += "Teensy41_AsyncWebServer_SendChunked_ABCDEFGHIJKLMNOPQRSTUVWXYZ
\r\n"; 123 | 124 | LOGDEBUG1("Total length to send in chunks =", out.length()); 125 | 126 | AsyncWebServerResponse *response = request->beginChunkedResponse("text/html", [](uint8_t *buffer, size_t maxLen, 127 | size_t filledLength) -> size_t 128 | { 129 | size_t len = min(maxLen, out.length() - filledLength); 130 | memcpy(buffer, out.c_str() + filledLength, len); 131 | 132 | LOGDEBUG1("Bytes sent in chunk =", len); 133 | 134 | return len; 135 | }); 136 | 137 | request->send(response); 138 | } 139 | 140 | void setup() 141 | { 142 | Serial.begin(115200); 143 | 144 | while (!Serial && millis() < 5000); 145 | 146 | delay(200); 147 | 148 | Serial.print("\nStart AsyncWebServer_SendChunked on "); 149 | Serial.print(BOARD_NAME); 150 | Serial.print(" with "); 151 | Serial.println(SHIELD_TYPE); 152 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 153 | 154 | /////////////////////////////////// 155 | 156 | delay(500); 157 | 158 | #if USING_DHCP 159 | // Start the Ethernet connection, using DHCP 160 | Serial.print("Initialize Ethernet using DHCP => "); 161 | Ethernet.begin(); 162 | #else 163 | // Start the Ethernet connection, using static IP 164 | Serial.print("Initialize Ethernet using static IP => "); 165 | Ethernet.begin(myIP, myNetmask, myGW); 166 | Ethernet.setDNSServerIP(mydnsServer); 167 | #endif 168 | 169 | if (!Ethernet.waitForLocalIP(5000)) 170 | { 171 | Serial.println(F("Failed to configure Ethernet")); 172 | 173 | if (!Ethernet.linkStatus()) 174 | { 175 | Serial.println(F("Ethernet cable is not connected.")); 176 | } 177 | 178 | // Stay here forever 179 | while (true) 180 | { 181 | delay(1); 182 | } 183 | } 184 | else 185 | { 186 | Serial.print(F("Connected! IP address:")); 187 | Serial.println(Ethernet.localIP()); 188 | } 189 | 190 | #if USING_DHCP 191 | delay(1000); 192 | #else 193 | delay(2000); 194 | #endif 195 | 196 | /////////////////////////////////// 197 | 198 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 199 | { 200 | handleRoot(request); 201 | }); 202 | 203 | server.on("/inline", [](AsyncWebServerRequest * request) 204 | { 205 | request->send(200, "text/plain", "This works as well"); 206 | }); 207 | 208 | server.onNotFound(handleNotFound); 209 | 210 | server.begin(); 211 | 212 | Serial.print(F("AsyncWebServer is @ IP : ")); 213 | Serial.println(Ethernet.localIP()); 214 | } 215 | 216 | void heartBeatPrint() 217 | { 218 | static int num = 1; 219 | 220 | Serial.print(F(".")); 221 | 222 | if (num == 80) 223 | { 224 | Serial.println(); 225 | num = 1; 226 | } 227 | else if (num++ % 10 == 0) 228 | { 229 | Serial.print(F(" ")); 230 | } 231 | } 232 | 233 | void check_status() 234 | { 235 | static unsigned long checkstatus_timeout = 0; 236 | 237 | #define STATUS_CHECK_INTERVAL 10000L 238 | 239 | // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. 240 | if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) 241 | { 242 | heartBeatPrint(); 243 | checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; 244 | } 245 | } 246 | 247 | void loop() 248 | { 249 | check_status(); 250 | } 251 | -------------------------------------------------------------------------------- /examples/Async_WebSocketsServer/Async_WebSocketsServer.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_WebSocketsServer.ino 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | // 14 | // A simple server implementation showing how to: 15 | // * serve static messages 16 | // * read GET and POST parameters 17 | // * handle missing pages / 404s 18 | // 19 | 20 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 21 | #error Only Teensy 4.1 supported 22 | #endif 23 | 24 | // Debug Level from 0 to 4 25 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 26 | #define _AWS_TEENSY41_LOGLEVEL_ 1 27 | 28 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 29 | 30 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 31 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 32 | #endif 33 | 34 | #define USING_DHCP true 35 | //#define USING_DHCP false 36 | 37 | #if !USING_DHCP 38 | // Set the static IP address to use if the DHCP fails to assign 39 | IPAddress myIP(192, 168, 2, 222); 40 | IPAddress myNetmask(255, 255, 255, 0); 41 | IPAddress myGW(192, 168, 2, 1); 42 | //IPAddress mydnsServer(192, 168, 2, 1); 43 | IPAddress mydnsServer(8, 8, 8, 8); 44 | #endif 45 | 46 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 47 | using namespace qindesign::network; 48 | 49 | #include 50 | 51 | #include "webpage.h" 52 | 53 | AsyncWebServer server(80); 54 | AsyncWebSocket ws("/ws"); 55 | 56 | void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) 57 | { 58 | if (type == WS_EVT_CONNECT) 59 | { 60 | Serial.printf("ws[Server: %s][ClientID: %u] WSClient connected\n", server->url(), client->id()); 61 | client->text("Hello from Teensy4_1 Server"); 62 | } 63 | else if (type == WS_EVT_DISCONNECT) 64 | { 65 | Serial.printf("ws[Server: %s][ClientID: %u] WSClient disconnected\n", server->url(), client->id()); 66 | } 67 | else if (type == WS_EVT_ERROR) 68 | { 69 | //error was received from the other end 70 | Serial.printf("ws[Server: %s][ClientID: %u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); 71 | } 72 | else if (type == WS_EVT_PONG) 73 | { 74 | //pong message was received (in response to a ping request maybe) 75 | Serial.printf("ws[Server: %s][ClientID: %u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char*)data : ""); 76 | } 77 | else if (type == WS_EVT_DATA) 78 | { 79 | //data packet 80 | AwsFrameInfo * info = (AwsFrameInfo*)arg; 81 | 82 | if (info->final && info->index == 0 && info->len == len) 83 | { 84 | //the whole message is in a single frame and we got all of it's data 85 | Serial.printf("ws[Server: %s][ClientID: %u] %s-message[len: %llu]: ", server->url(), client->id(), 86 | (info->opcode == WS_TEXT) ? "text" : "binary", info->len); 87 | 88 | if (info->opcode == WS_TEXT) 89 | { 90 | data[len] = 0; 91 | Serial.printf("%s\n", (char*)data); 92 | } 93 | else 94 | { 95 | for (size_t i = 0; i < info->len; i++) 96 | { 97 | Serial.printf("%02x ", data[i]); 98 | } 99 | 100 | Serial.printf("\n"); 101 | } 102 | 103 | if (info->opcode == WS_TEXT) 104 | client->text("Got your text message"); 105 | else 106 | client->binary("Got your binary message"); 107 | } 108 | else 109 | { 110 | //message is comprised of multiple frames or the frame is split into multiple packets 111 | if (info->index == 0) 112 | { 113 | if (info->num == 0) 114 | { 115 | Serial.printf("ws[Server: %s][ClientID: %u] %s-message start\n", server->url(), client->id(), 116 | (info->message_opcode == WS_TEXT) ? "text" : "binary"); 117 | } 118 | 119 | Serial.printf("ws[Server: %s][ClientID: %u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); 120 | } 121 | 122 | Serial.printf("ws[Server: %s][ClientID: %u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), 123 | info->num, (info->message_opcode == WS_TEXT) ? "text" : "binary", info->index, info->index + len); 124 | 125 | if (info->message_opcode == WS_TEXT) 126 | { 127 | data[len] = 0; 128 | Serial.printf("%s\n", (char*)data); 129 | } 130 | else 131 | { 132 | for (size_t i = 0; i < len; i++) 133 | { 134 | Serial.printf("%02x ", data[i]); 135 | } 136 | 137 | Serial.printf("\n"); 138 | } 139 | 140 | if ((info->index + len) == info->len) 141 | { 142 | Serial.printf("ws[Server: %s][ClientID: %u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); 143 | 144 | if (info->final) 145 | { 146 | Serial.printf("ws[Server: %s][ClientID: %u] %s-message end\n", server->url(), client->id(), 147 | (info->message_opcode == WS_TEXT) ? "text" : "binary"); 148 | 149 | if (info->message_opcode == WS_TEXT) 150 | client->text("I got your text message"); 151 | else 152 | client->binary("I got your binary message"); 153 | } 154 | } 155 | } 156 | } 157 | } 158 | 159 | void handleRoot(AsyncWebServerRequest *request) 160 | { 161 | request->send(200, "text/html", webpageCont); 162 | } 163 | 164 | void setup() 165 | { 166 | Serial.begin(115200); 167 | 168 | while (!Serial && millis() < 5000); 169 | 170 | delay(200); 171 | 172 | Serial.print("\nStarting Async_WebSocketsServer on "); 173 | Serial.print(BOARD_NAME); 174 | Serial.print(" with "); 175 | Serial.println(SHIELD_TYPE); 176 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 177 | 178 | delay(500); 179 | 180 | #if USING_DHCP 181 | // Start the Ethernet connection, using DHCP 182 | Serial.print("Initialize Ethernet using DHCP => "); 183 | Ethernet.begin(); 184 | #else 185 | // Start the Ethernet connection, using static IP 186 | Serial.print("Initialize Ethernet using static IP => "); 187 | Ethernet.begin(myIP, myNetmask, myGW); 188 | Ethernet.setDNSServerIP(mydnsServer); 189 | #endif 190 | 191 | if (!Ethernet.waitForLocalIP(5000)) 192 | { 193 | Serial.println(F("Failed to configure Ethernet")); 194 | 195 | if (!Ethernet.linkStatus()) 196 | { 197 | Serial.println(F("Ethernet cable is not connected.")); 198 | } 199 | 200 | // Stay here forever 201 | while (true) 202 | { 203 | delay(1); 204 | } 205 | } 206 | else 207 | { 208 | Serial.print(F("Connected! IP address:")); 209 | Serial.println(Ethernet.localIP()); 210 | } 211 | 212 | #if USING_DHCP 213 | delay(1000); 214 | #else 215 | delay(2000); 216 | #endif 217 | 218 | /////////////////////////////////// 219 | 220 | ws.onEvent(onWsEvent); 221 | server.addHandler(&ws); 222 | 223 | server.on("/", handleRoot); 224 | server.begin(); 225 | } 226 | 227 | void loop() 228 | { 229 | } 230 | -------------------------------------------------------------------------------- /src/AsyncEventSource_Teensy41.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncEventSource_Teensy41.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | 11 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 12 | This file is part of the esp8266 core for Arduino environment. 13 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 14 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 | You should have received a copy of the GNU General Public License along with this program. 18 | If not, see . 19 | 20 | Version: 1.7.0 21 | 22 | Version Modified By Date Comments 23 | ------- ----------- ---------- ----------- 24 | 1.4.1 K Hoang 18/03/2022 Initial coding for Teensy 4.1 using built-in QNEthernet. 25 | Bump up version to v1.4.1 to sync with AsyncWebServer_STM32 v1.4.1 26 | 1.5.0 K Hoang 01/10/2022 Fix issue with slow browsers or network. Add function and example to support favicon.ico 27 | 1.6.0 K Hoang 06/10/2022 Option to use non-destroyed cString instead of String to save Heap 28 | 1.6.1 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks 29 | 1.6.2 K Hoang 16/01/2023 Add examples Async_WebSocketsServer 30 | 1.7.0 K Hoang 29/01/2024 Fix file upload handler by adjusting function signatures 31 | *****************************************************************************************************************************/ 32 | 33 | #pragma once 34 | 35 | #ifndef ASYNCEVENTSOURCE_TEENSY41_H_ 36 | #define ASYNCEVENTSOURCE_TEENSY41_H_ 37 | 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | #include "AsyncWebSynchronization_Teensy41.h" 44 | 45 | // Teensy41 46 | #include 47 | 48 | ///////////////////////////////////////////////////////// 49 | 50 | #define SSE_MAX_QUEUED_MESSAGES 32 51 | //#define SSE_MAX_QUEUED_MESSAGES 8 52 | 53 | #define DEFAULT_MAX_SSE_CLIENTS 8 54 | //#define DEFAULT_MAX_SSE_CLIENTS 4 55 | 56 | ///////////////////////////////////////////////////////// 57 | 58 | class AsyncEventSource; 59 | class AsyncEventSourceResponse; 60 | class AsyncEventSourceClient; 61 | typedef std::function ArEventHandlerFunction; 62 | 63 | ///////////////////////////////////////////////////////// 64 | 65 | class AsyncEventSourceMessage 66 | { 67 | private: 68 | uint8_t * _data; 69 | size_t _len; 70 | size_t _sent; 71 | //size_t _ack; 72 | size_t _acked; 73 | 74 | public: 75 | AsyncEventSourceMessage(const char * data, size_t len); 76 | ~AsyncEventSourceMessage(); 77 | size_t ack(size_t len, uint32_t time __attribute__((unused))); 78 | size_t send(AsyncClient *client); 79 | 80 | ///////////////////////////////////////////////// 81 | 82 | inline bool finished() 83 | { 84 | return _acked == _len; 85 | } 86 | 87 | ///////////////////////////////////////////////// 88 | 89 | inline bool sent() 90 | { 91 | return _sent == _len; 92 | } 93 | }; 94 | 95 | ///////////////////////////////////////////////// 96 | ///////////////////////////////////////////////// 97 | 98 | class AsyncEventSourceClient 99 | { 100 | private: 101 | AsyncClient *_client; 102 | AsyncEventSource *_server; 103 | uint32_t _lastId; 104 | LinkedList _messageQueue; 105 | void _queueMessage(AsyncEventSourceMessage *dataMessage); 106 | void _runQueue(); 107 | 108 | public: 109 | 110 | AsyncEventSourceClient(AsyncWebServerRequest *request, AsyncEventSource *server); 111 | ~AsyncEventSourceClient(); 112 | 113 | ///////////////////////////////////////////////// 114 | 115 | inline AsyncClient* client() 116 | { 117 | return _client; 118 | } 119 | 120 | ///////////////////////////////////////////////// 121 | 122 | void close(); 123 | void write(const char * message, size_t len); 124 | void send(const char *message, const char *event = NULL, uint32_t id = 0, uint32_t reconnect = 0); 125 | 126 | ///////////////////////////////////////////////// 127 | 128 | inline bool connected() const 129 | { 130 | return (_client != NULL) && _client->connected(); 131 | } 132 | 133 | ///////////////////////////////////////////////// 134 | 135 | inline uint32_t lastId() const 136 | { 137 | return _lastId; 138 | } 139 | 140 | ///////////////////////////////////////////////// 141 | 142 | inline size_t packetsWaiting() const 143 | { 144 | return _messageQueue.length(); 145 | } 146 | 147 | ///////////////////////////////////////////////// 148 | 149 | //system callbacks (do not call) 150 | void _onAck(size_t len, uint32_t time); 151 | void _onPoll(); 152 | void _onTimeout(uint32_t time); 153 | void _onDisconnect(); 154 | }; 155 | 156 | ///////////////////////////////////////////////// 157 | ///////////////////////////////////////////////// 158 | 159 | class AsyncEventSource: public AsyncWebHandler 160 | { 161 | private: 162 | String _url; 163 | LinkedList _clients; 164 | ArEventHandlerFunction _connectcb; 165 | 166 | public: 167 | AsyncEventSource(const String& url); 168 | ~AsyncEventSource(); 169 | 170 | ///////////////////////////////////////////////// 171 | 172 | inline const char * url() const 173 | { 174 | return _url.c_str(); 175 | } 176 | 177 | ///////////////////////////////////////////////// 178 | 179 | void close(); 180 | void onConnect(ArEventHandlerFunction cb); 181 | void send(const char *message, const char *event = NULL, uint32_t id = 0, uint32_t reconnect = 0); 182 | size_t count() const; //number clinets connected 183 | size_t avgPacketsWaiting() const; 184 | 185 | //system callbacks (do not call) 186 | void _addClient(AsyncEventSourceClient * client); 187 | void _handleDisconnect(AsyncEventSourceClient * client); 188 | virtual bool canHandle(AsyncWebServerRequest *request) override final; 189 | virtual void handleRequest(AsyncWebServerRequest *request) override final; 190 | }; 191 | 192 | ///////////////////////////////////////////////// 193 | ///////////////////////////////////////////////// 194 | 195 | class AsyncEventSourceResponse: public AsyncWebServerResponse 196 | { 197 | private: 198 | String _content; 199 | AsyncEventSource *_server; 200 | 201 | public: 202 | AsyncEventSourceResponse(AsyncEventSource *server); 203 | void _respond(AsyncWebServerRequest *request); 204 | size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); 205 | 206 | ///////////////////////////////////////////////// 207 | 208 | inline bool _sourceValid() const 209 | { 210 | return true; 211 | } 212 | }; 213 | 214 | #endif /* ASYNCEVENTSOURCE__TEENSY41_H_ */ 215 | -------------------------------------------------------------------------------- /examples/MQTT_ThingStream/MQTT_ThingStream.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | MQTT_ThingStream.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | *****************************************************************************************************************************/ 12 | 13 | /* 14 | Basic MQTT example (without SSL!) 15 | This sketch demonstrates the basic capabilities of the library. 16 | It connects to an MQTT server then: 17 | - publishes {Hello from MQTT_ThingStream on TEENSY 4.1 with Teensy4.1 QNEthernet} to the topic [Teensy41_Pub] 18 | - subscribes to the topic [Teensy41_Sub], printing out any messages 19 | it receives. NB - it assumes the received payloads are strings not binary 20 | It will reconnect to the server if the connection is lost using a blocking 21 | reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to 22 | achieve the same result without blocking the main loop. 23 | 24 | You will need to populate "certificates.h" with your trust anchors 25 | (see https://github.com/OPEnSLab-OSU/SSLClient/blob/master/TrustAnchors.md) 26 | and my_cert/my_key with your certificate/private key pair 27 | (see https://github.com/OPEnSLab-OSU/SSLClient#mtls). 28 | */ 29 | 30 | // To remove boolean warnings caused by PubSubClient library 31 | #define boolean bool 32 | 33 | #include "defines.h" 34 | 35 | #include 36 | 37 | const char my_cert[] = "FIXME"; 38 | const char my_key[] = "FIXME"; 39 | 40 | #define USING_THINGSTREAM_IO false //true 41 | 42 | #if USING_THINGSTREAM_IO 43 | 44 | const char *MQTT_PREFIX_TOPIC = "teensy41-sniffer/"; 45 | const char *MQTT_ANNOUNCE_TOPIC = "/status"; 46 | const char *MQTT_CONTROL_TOPIC = "/control"; 47 | const char *MQTT_BLE_TOPIC = "/ble"; 48 | 49 | 50 | // GOT FROM ThingsStream! 51 | const char *MQTT_SERVER = "mqtt.thingstream.io"; 52 | const char *MQTT_USER = "MQTT_USER"; 53 | const char *MQTT_PASS = "MQTT_PASS"; 54 | const char *MQTT_CLIENT_ID = "MQTT_CLIENT_ID"; 55 | 56 | String topic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; 57 | String subTopic = MQTT_PREFIX_TOPIC + String("12345678") + MQTT_BLE_TOPIC; 58 | 59 | #else 60 | 61 | const char* MQTT_SERVER = "broker.emqx.io"; // Broker address 62 | 63 | const char* ID = "MQTT_ThingStream"; // Name of our device, must be unique 64 | String topic = "Teensy41_Pub"; // Topic to subcribe to 65 | String subTopic = "Teensy41_Sub"; // Topic to subcribe to 66 | 67 | #endif 68 | 69 | void mqtt_receive_callback(char* topic, byte* payload, unsigned int length); 70 | 71 | const int MQTT_PORT = 1883; //if you use SSL //1883 no SSL 72 | 73 | unsigned long lastMsg = 0; 74 | 75 | // Initialize the SSL client library 76 | // Arguments: EthernetClient, our trust anchors 77 | 78 | 79 | EthernetClient ethClient; 80 | 81 | PubSubClient client(MQTT_SERVER, MQTT_PORT, mqtt_receive_callback, ethClient); 82 | 83 | String data = "Hello from MQTT_ThingStream on " + String(BOARD_NAME) + " with " + String(SHIELD_TYPE); 84 | const char *pubData = data.c_str(); 85 | 86 | /* 87 | Called whenever a payload is received from a subscribed MQTT topic 88 | */ 89 | void mqtt_receive_callback(char* topic, byte* payload, unsigned int length) 90 | { 91 | Serial.print("MQTT Message receive ["); 92 | Serial.print(topic); 93 | Serial.print("] "); 94 | 95 | for (unsigned int i = 0; i < length; i++) 96 | { 97 | Serial.print((char)payload[i]); 98 | } 99 | 100 | Serial.println(); 101 | } 102 | 103 | void reconnect() 104 | { 105 | // Loop until we're reconnected 106 | while (!client.connected()) 107 | { 108 | Serial.print("Attempting MQTT connection to "); 109 | Serial.println(MQTT_SERVER); 110 | 111 | // Attempt to connect 112 | 113 | #if USING_THINGSTREAM_IO 114 | int connect_status = client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, topic.c_str(), 2, false, ""); 115 | #else 116 | int connect_status = client.connect(ID); 117 | #endif 118 | 119 | if (connect_status) 120 | { 121 | Serial.println("...connected"); 122 | 123 | // Once connected, publish an announcement... 124 | client.publish(topic.c_str(), data.c_str()); 125 | 126 | Serial.println("Published connection message successfully!"); 127 | 128 | Serial.print("Subcribed to: "); 129 | Serial.println(subTopic); 130 | 131 | // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 132 | //ethClientSSL.flush(); 133 | // ... and resubscribe 134 | client.subscribe(subTopic.c_str()); 135 | // for loopback testing 136 | client.subscribe(topic.c_str()); 137 | // This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9 138 | //ethClientSSL.flush(); 139 | } 140 | else 141 | { 142 | Serial.print("failed, rc="); 143 | Serial.print(client.state()); 144 | Serial.println(" try again in 5 seconds"); 145 | 146 | // Wait 5 seconds before retrying 147 | delay(5000); 148 | } 149 | } 150 | } 151 | 152 | void setup() 153 | { 154 | // Open serial communications and wait for port to open: 155 | Serial.begin(115200); 156 | 157 | while (!Serial && millis() < 5000); 158 | 159 | Serial.print("\nStart MQTT_ThingStream on "); 160 | Serial.print(BOARD_NAME); 161 | Serial.print(" with "); 162 | Serial.println(SHIELD_TYPE); 163 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 164 | 165 | delay(500); 166 | 167 | #if USING_DHCP 168 | // Start the Ethernet connection, using DHCP 169 | Serial.print("Initialize Ethernet using DHCP => "); 170 | Ethernet.begin(); 171 | #else 172 | // Start the Ethernet connection, using static IP 173 | Serial.print("Initialize Ethernet using static IP => "); 174 | Ethernet.begin(myIP, myNetmask, myGW); 175 | Ethernet.setDNSServerIP(mydnsServer); 176 | #endif 177 | 178 | if (!Ethernet.waitForLocalIP(5000)) 179 | { 180 | Serial.println(F("Failed to configure Ethernet")); 181 | 182 | if (!Ethernet.linkStatus()) 183 | { 184 | Serial.println(F("Ethernet cable is not connected.")); 185 | } 186 | 187 | // Stay here forever 188 | while (true) 189 | { 190 | delay(1); 191 | } 192 | } 193 | else 194 | { 195 | Serial.print(F("Connected! IP address:")); 196 | Serial.println(Ethernet.localIP()); 197 | } 198 | 199 | #if USING_DHCP 200 | delay(1000); 201 | #else 202 | delay(2000); 203 | #endif 204 | 205 | // Note - the default maximum packet size is 256 bytes. If the 206 | // combined length of clientId, username and password exceed this use the 207 | // following to increase the buffer size: 208 | //client.setBufferSize(256); 209 | 210 | Serial.println("***************************************"); 211 | Serial.println(topic); 212 | Serial.println("***************************************"); 213 | } 214 | 215 | #define MQTT_PUBLISH_INTERVAL_MS 5000L 216 | 217 | void loop() 218 | { 219 | static unsigned long now; 220 | 221 | if (!client.connected()) 222 | { 223 | reconnect(); 224 | } 225 | 226 | // Sending Data 227 | now = millis(); 228 | 229 | if (now - lastMsg > MQTT_PUBLISH_INTERVAL_MS) 230 | { 231 | lastMsg = now; 232 | 233 | if (!client.publish(topic.c_str(), pubData)) 234 | { 235 | Serial.println("Message failed to send."); 236 | } 237 | 238 | Serial.print("MQTT Message Send : " + topic + " => "); 239 | Serial.println(data); 240 | } 241 | 242 | client.loop(); 243 | } 244 | -------------------------------------------------------------------------------- /examples/Async_AdvancedWebServer/Async_AdvancedWebServer.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_AdvancedWebServer.ino - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | 12 | Copyright (c) 2015, Majenko Technologies 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without modification, 16 | are permitted provided that the following conditions are met: 17 | 18 | Redistributions of source code must retain the above copyright notice, this 19 | list of conditions and the following disclaimer. 20 | 21 | Redistributions in binary form must reproduce the above copyright notice, this 22 | list of conditions and the following disclaimer in the documentation and/or 23 | other materials provided with the distribution. 24 | 25 | Neither the name of Majenko Technologies nor the names of its 26 | contributors may be used to endorse or promote products derived from 27 | this software without specific prior written permission. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 30 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 32 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 33 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 35 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 36 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | *****************************************************************************************************************************/ 40 | 41 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 42 | #error Only Teensy 4.1 supported 43 | #endif 44 | 45 | // Debug Level from 0 to 4 46 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 47 | #define _AWS_TEENSY41_LOGLEVEL_ 1 48 | 49 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 50 | 51 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 52 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 53 | #endif 54 | 55 | #define USING_DHCP true 56 | //#define USING_DHCP false 57 | 58 | #if !USING_DHCP 59 | // Set the static IP address to use if the DHCP fails to assign 60 | IPAddress myIP(192, 168, 2, 222); 61 | IPAddress myNetmask(255, 255, 255, 0); 62 | IPAddress myGW(192, 168, 2, 1); 63 | //IPAddress mydnsServer(192, 168, 2, 1); 64 | IPAddress mydnsServer(8, 8, 8, 8); 65 | #endif 66 | 67 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 68 | using namespace qindesign::network; 69 | 70 | #include 71 | 72 | AsyncWebServer server(80); 73 | 74 | int reqCount = 0; // number of requests received 75 | 76 | const int led = 13; 77 | 78 | void handleRoot(AsyncWebServerRequest *request) 79 | { 80 | digitalWrite(led, 1); 81 | 82 | #define BUFFER_SIZE 400 83 | 84 | char temp[BUFFER_SIZE]; 85 | int sec = millis() / 1000; 86 | int min = sec / 60; 87 | int hr = min / 60; 88 | int day = hr / 24; 89 | 90 | snprintf(temp, BUFFER_SIZE - 1, 91 | "\ 92 | \ 93 | \ 94 | AsyncWebServer-%s\ 95 | \ 98 | \ 99 | \ 100 |

AsyncWebServer_Teensy41!

\ 101 |

running on %s

\ 102 |

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

\ 103 | \ 104 | \ 105 | ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); 106 | 107 | request->send(200, "text/html", temp); 108 | 109 | digitalWrite(led, 0); 110 | } 111 | 112 | void handleNotFound(AsyncWebServerRequest *request) 113 | { 114 | digitalWrite(led, 1); 115 | String message = "File Not Found\n\n"; 116 | 117 | message += "URI: "; 118 | message += request->url(); 119 | message += "\nMethod: "; 120 | message += (request->method() == HTTP_GET) ? "GET" : "POST"; 121 | message += "\nArguments: "; 122 | message += request->args(); 123 | message += "\n"; 124 | 125 | for (uint8_t i = 0; i < request->args(); i++) 126 | { 127 | message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; 128 | } 129 | 130 | request->send(404, "text/plain", message); 131 | digitalWrite(led, 0); 132 | } 133 | 134 | void drawGraph(AsyncWebServerRequest *request) 135 | { 136 | String out; 137 | 138 | out.reserve(4000); 139 | char temp[70]; 140 | 141 | out += "\n"; 142 | out += "\n"; 143 | out += "\n"; 144 | int y = rand() % 130; 145 | 146 | for (int x = 10; x < 300; x += 10) 147 | { 148 | int y2 = rand() % 130; 149 | sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); 150 | out += temp; 151 | y = y2; 152 | } 153 | 154 | out += "\n\n"; 155 | 156 | request->send(200, "image/svg+xml", out); 157 | } 158 | 159 | 160 | void setup() 161 | { 162 | pinMode(led, OUTPUT); 163 | digitalWrite(led, 0); 164 | 165 | Serial.begin(115200); 166 | 167 | while (!Serial && millis() < 5000); 168 | 169 | delay(200); 170 | 171 | Serial.print("\nStart Async_AdvancedWebServer on "); 172 | Serial.print(BOARD_NAME); 173 | Serial.print(" with "); 174 | Serial.println(SHIELD_TYPE); 175 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 176 | 177 | delay(500); 178 | 179 | #if USING_DHCP 180 | // Start the Ethernet connection, using DHCP 181 | Serial.print("Initialize Ethernet using DHCP => "); 182 | Ethernet.begin(); 183 | #else 184 | // Start the Ethernet connection, using static IP 185 | Serial.print("Initialize Ethernet using static IP => "); 186 | Ethernet.begin(myIP, myNetmask, myGW); 187 | Ethernet.setDNSServerIP(mydnsServer); 188 | #endif 189 | 190 | if (!Ethernet.waitForLocalIP(5000)) 191 | { 192 | Serial.println(F("Failed to configure Ethernet")); 193 | 194 | if (!Ethernet.linkStatus()) 195 | { 196 | Serial.println(F("Ethernet cable is not connected.")); 197 | } 198 | 199 | // Stay here forever 200 | while (true) 201 | { 202 | delay(1); 203 | } 204 | } 205 | else 206 | { 207 | Serial.print(F("Connected! IP address:")); 208 | Serial.println(Ethernet.localIP()); 209 | } 210 | 211 | #if USING_DHCP 212 | delay(1000); 213 | #else 214 | delay(2000); 215 | #endif 216 | 217 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 218 | { 219 | handleRoot(request); 220 | }); 221 | 222 | server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) 223 | { 224 | drawGraph(request); 225 | }); 226 | 227 | server.on("/inline", [](AsyncWebServerRequest * request) 228 | { 229 | request->send(200, "text/plain", "This works as well"); 230 | }); 231 | 232 | server.onNotFound(handleNotFound); 233 | 234 | server.begin(); 235 | 236 | Serial.print(F("HTTP EthernetWebServer is @ IP : ")); 237 | Serial.println(Ethernet.localIP()); 238 | } 239 | 240 | void loop() 241 | { 242 | } 243 | -------------------------------------------------------------------------------- /src/AsyncWebHandlerImpl_Teensy41.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncWebHandlerImpl_Teensy41.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | 11 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 12 | This file is part of the esp8266 core for Arduino environment. 13 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 14 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 | You should have received a copy of the GNU General Public License along with this program. 18 | If not, see . 19 | 20 | Version: 1.7.0 21 | 22 | Version Modified By Date Comments 23 | ------- ----------- ---------- ----------- 24 | 1.4.1 K Hoang 18/03/2022 Initial coding for Teensy 4.1 using built-in QNEthernet. 25 | Bump up version to v1.4.1 to sync with AsyncWebServer_STM32 v1.4.1 26 | 1.5.0 K Hoang 01/10/2022 Fix issue with slow browsers or network. Add function and example to support favicon.ico 27 | 1.6.0 K Hoang 06/10/2022 Option to use non-destroyed cString instead of String to save Heap 28 | 1.6.1 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks 29 | 1.6.2 K Hoang 16/01/2023 Add examples Async_WebSocketsServer 30 | 1.7.0 K Hoang 29/01/2024 Fix file upload handler by adjusting function signatures 31 | *****************************************************************************************************************************/ 32 | 33 | #pragma once 34 | 35 | #ifndef ASYNCWEBSERVERHANDLERIMPL_TEENSY41_H_ 36 | #define ASYNCWEBSERVERHANDLERIMPL_TEENSY41_H_ 37 | 38 | #include 39 | 40 | #ifdef ASYNCWEBSERVER_REGEX 41 | #include 42 | #endif 43 | 44 | #include "stddef.h" 45 | #include 46 | 47 | ///////////////////////////////////////////////// 48 | 49 | class AsyncStaticWebHandler: public AsyncWebHandler 50 | { 51 | private: 52 | uint8_t _countBits(const uint8_t value) const; 53 | 54 | protected: 55 | String _uri; 56 | String _path; 57 | String _cache_control; 58 | String _last_modified; 59 | AwsTemplateProcessor _callback; 60 | bool _isDir; 61 | bool _gzipFirst; 62 | uint8_t _gzipStats; 63 | 64 | public: 65 | AsyncStaticWebHandler(const char* uri, const char* path, const char* cache_control); 66 | virtual bool canHandle(AsyncWebServerRequest *request) override final; 67 | virtual void handleRequest(AsyncWebServerRequest *request) override final; 68 | AsyncStaticWebHandler& setIsDir(bool isDir); 69 | AsyncStaticWebHandler& setCacheControl(const char* cache_control); 70 | AsyncStaticWebHandler& setLastModified(const char* last_modified); 71 | AsyncStaticWebHandler& setLastModified(struct tm* last_modified); 72 | 73 | AsyncStaticWebHandler& setLastModified(time_t last_modified); 74 | AsyncStaticWebHandler& setLastModified(); //sets to current time. Make sure sntp is runing and time is updated 75 | 76 | ///////////////////////////////////////////////// 77 | 78 | AsyncStaticWebHandler& setTemplateProcessor(AwsTemplateProcessor newCallback) 79 | { 80 | _callback = newCallback; 81 | return *this; 82 | } 83 | }; 84 | 85 | class AsyncCallbackWebHandler: public AsyncWebHandler 86 | { 87 | private: 88 | protected: 89 | String _uri; 90 | WebRequestMethodComposite _method; 91 | ArRequestHandlerFunction _onRequest; 92 | ArUploadHandlerFunction _onUpload; 93 | ArBodyHandlerFunction _onBody; 94 | bool _isRegex; 95 | 96 | public: 97 | AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), 98 | _isRegex(false) {} 99 | 100 | ///////////////////////////////////////////////// 101 | 102 | inline void setUri(const String& uri) 103 | { 104 | _uri = uri; 105 | _isRegex = uri.startsWith("^") && uri.endsWith("$"); 106 | } 107 | 108 | ///////////////////////////////////////////////// 109 | 110 | inline void setMethod(WebRequestMethodComposite method) 111 | { 112 | _method = method; 113 | } 114 | 115 | ///////////////////////////////////////////////// 116 | 117 | inline void onRequest(ArRequestHandlerFunction fn) 118 | { 119 | _onRequest = fn; 120 | } 121 | 122 | ///////////////////////////////////////////////// 123 | 124 | inline void onUpload(ArUploadHandlerFunction fn) 125 | { 126 | _onUpload = fn; 127 | } 128 | 129 | ///////////////////////////////////////////////// 130 | 131 | inline void onBody(ArBodyHandlerFunction fn) 132 | { 133 | _onBody = fn; 134 | } 135 | 136 | ///////////////////////////////////////////////// 137 | 138 | virtual bool canHandle(AsyncWebServerRequest *request) override final 139 | { 140 | if (!_onRequest) 141 | return false; 142 | 143 | if (!(_method & request->method())) 144 | return false; 145 | 146 | #ifdef ASYNCWEBSERVER_REGEX 147 | 148 | if (_isRegex) 149 | { 150 | std::regex pattern(_uri.c_str()); 151 | std::smatch matches; 152 | std::string s(request->url().c_str()); 153 | 154 | if (std::regex_search(s, matches, pattern)) 155 | { 156 | for (size_t i = 1; i < matches.size(); ++i) 157 | { 158 | // start from 1 159 | request->_addPathParam(matches[i].str().c_str()); 160 | } 161 | } 162 | else 163 | { 164 | return false; 165 | } 166 | } 167 | else 168 | #endif 169 | if (_uri.length() && _uri.endsWith("*")) 170 | { 171 | String uriTemplate = String(_uri); 172 | uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); 173 | 174 | if (!request->url().startsWith(uriTemplate)) 175 | return false; 176 | } 177 | else if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) 178 | return false; 179 | 180 | request->addInterestingHeader("ANY"); 181 | 182 | return true; 183 | } 184 | 185 | ///////////////////////////////////////////////// 186 | 187 | virtual void handleRequest(AsyncWebServerRequest *request) override final 188 | { 189 | if (_onRequest) 190 | _onRequest(request); 191 | else 192 | request->send(500); 193 | } 194 | 195 | ///////////////////////////////////////////////// 196 | 197 | virtual void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, 198 | bool final) override final 199 | { 200 | if (_onUpload) 201 | _onUpload(request, filename, index, data, len, final); 202 | } 203 | 204 | ///////////////////////////////////////////////// 205 | 206 | virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, 207 | size_t total) override final 208 | { 209 | if (_onBody) 210 | _onBody(request, data, len, index, total); 211 | } 212 | 213 | ///////////////////////////////////////////////// 214 | 215 | virtual bool isRequestHandlerTrivial() override final 216 | { 217 | return _onRequest ? false : true; 218 | } 219 | }; 220 | 221 | #endif /* ASYNCWEBSERVERHANDLERIMPL_TEENSY41_H_ */ 222 | -------------------------------------------------------------------------------- /examples/Async_AdvancedWebServer_favicon/Async_AdvancedWebServer_favicon.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | Async_AdvancedWebServer.ino 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | Licensed under GPLv3 license 11 | 12 | Copyright (c) 2015, Majenko Technologies 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without modification, 16 | are permitted provided that the following conditions are met: 17 | 18 | Redistributions of source code must retain the above copyright notice, this 19 | list of conditions and the following disclaimer. 20 | 21 | Redistributions in binary form must reproduce the above copyright notice, this 22 | list of conditions and the following disclaimer in the documentation and/or 23 | other materials provided with the distribution. 24 | 25 | Neither the name of Majenko Technologies nor the names of its 26 | contributors may be used to endorse or promote products derived from 27 | this software without specific prior written permission. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 30 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 31 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 32 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 33 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 35 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 36 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | *****************************************************************************************************************************/ 40 | 41 | 42 | #if !( defined(CORE_TEENSY) && defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) ) 43 | #error Only Teensy 4.1 supported 44 | #endif 45 | 46 | // Debug Level from 0 to 4 47 | #define _TEENSY41_ASYNC_TCP_LOGLEVEL_ 1 48 | #define _AWS_TEENSY41_LOGLEVEL_ 1 49 | 50 | #define SHIELD_TYPE "Teensy4.1 QNEthernet" 51 | 52 | #if (_AWS_TEENSY41_LOGLEVEL_ > 3) 53 | #warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error 54 | #endif 55 | 56 | #define USING_DHCP true 57 | //#define USING_DHCP false 58 | 59 | #if !USING_DHCP 60 | // Set the static IP address to use if the DHCP fails to assign 61 | IPAddress myIP(192, 168, 2, 222); 62 | IPAddress myNetmask(255, 255, 255, 0); 63 | IPAddress myGW(192, 168, 2, 1); 64 | //IPAddress mydnsServer(192, 168, 2, 1); 65 | IPAddress mydnsServer(8, 8, 8, 8); 66 | #endif 67 | 68 | #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet 69 | using namespace qindesign::network; 70 | 71 | #include "favicon.h" 72 | #include 73 | 74 | AsyncWebServer server(80); 75 | 76 | int reqCount = 0; // number of requests received 77 | 78 | const int led = 13; 79 | 80 | #define BUFFER_SIZE 512 81 | char temp[BUFFER_SIZE]; 82 | 83 | void handleRoot(AsyncWebServerRequest *request) 84 | { 85 | digitalWrite(led, 1); 86 | 87 | int sec = millis() / 1000; 88 | int min = sec / 60; 89 | int hr = min / 60; 90 | int day = hr / 24; 91 | 92 | snprintf(temp, BUFFER_SIZE - 1, 93 | "\ 94 | \ 95 | \ 96 | AsyncWebServer-%s\ 97 | \ 100 | \ 101 | \ 102 |

AsyncWebServer_Teensy41!

\ 103 |

running on %s

\ 104 |

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

\ 105 | \ 106 | \ 107 | ", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60); 108 | 109 | request->send(200, "text/html", temp); 110 | 111 | digitalWrite(led, 0); 112 | } 113 | void drawFavicon(AsyncWebServerRequest *request) 114 | { 115 | AsyncWebServerResponse *response = request->beginResponse(200, "image/x-icon", favicon_ico_gz, favicon_ico_gz_len); 116 | 117 | response->addHeader("Content-Encoding", "gzip"); 118 | request->send(response); 119 | } 120 | 121 | void handleNotFound(AsyncWebServerRequest *request) 122 | { 123 | digitalWrite(led, 1); 124 | String message = "File Not Found\n\n"; 125 | 126 | message += "URI: "; 127 | message += request->url(); 128 | message += "\nMethod: "; 129 | message += (request->method() == HTTP_GET) ? "GET" : "POST"; 130 | message += "\nArguments: "; 131 | message += request->args(); 132 | message += "\n"; 133 | 134 | for (uint8_t i = 0; i < request->args(); i++) 135 | { 136 | message += " " + request->argName(i) + ": " + request->arg(i) + "\n"; 137 | } 138 | 139 | request->send(404, "text/plain", message); 140 | digitalWrite(led, 0); 141 | } 142 | 143 | void drawGraph(AsyncWebServerRequest *request) 144 | { 145 | String out; 146 | 147 | out.reserve(4000); 148 | char temp[70]; 149 | 150 | out += "\n"; 151 | out += "\n"; 152 | out += "\n"; 153 | int y = rand() % 130; 154 | 155 | for (int x = 10; x < 300; x += 10) 156 | { 157 | int y2 = rand() % 130; 158 | sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); 159 | out += temp; 160 | y = y2; 161 | } 162 | 163 | out += "\n\n"; 164 | 165 | request->send(200, "image/svg+xml", out); 166 | } 167 | 168 | 169 | void setup() 170 | { 171 | pinMode(led, OUTPUT); 172 | digitalWrite(led, 0); 173 | 174 | Serial.begin(115200); 175 | 176 | while (!Serial && millis() < 5000); 177 | 178 | delay(200); 179 | 180 | Serial.print("\nStart Async_AdvancedWebServer_favicon on "); 181 | Serial.print(BOARD_NAME); 182 | Serial.print(" with "); 183 | Serial.println(SHIELD_TYPE); 184 | Serial.println(ASYNC_WEBSERVER_TEENSY41_VERSION); 185 | 186 | delay(500); 187 | 188 | #if USING_DHCP 189 | // Start the Ethernet connection, using DHCP 190 | Serial.print("Initialize Ethernet using DHCP => "); 191 | Ethernet.begin(); 192 | #else 193 | // Start the Ethernet connection, using static IP 194 | Serial.print("Initialize Ethernet using static IP => "); 195 | Ethernet.begin(myIP, myNetmask, myGW); 196 | Ethernet.setDNSServerIP(mydnsServer); 197 | #endif 198 | 199 | if (!Ethernet.waitForLocalIP(5000)) 200 | { 201 | Serial.println(F("Failed to configure Ethernet")); 202 | 203 | if (!Ethernet.linkStatus()) 204 | { 205 | Serial.println(F("Ethernet cable is not connected.")); 206 | } 207 | 208 | // Stay here forever 209 | while (true) 210 | { 211 | delay(1); 212 | } 213 | } 214 | else 215 | { 216 | Serial.print(F("Connected! IP address:")); 217 | Serial.println(Ethernet.localIP()); 218 | } 219 | 220 | #if USING_DHCP 221 | delay(1000); 222 | #else 223 | delay(2000); 224 | #endif 225 | 226 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 227 | { 228 | handleRoot(request); 229 | }); 230 | 231 | server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request) 232 | { 233 | drawGraph(request); 234 | }); 235 | 236 | server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest * request) 237 | { 238 | drawFavicon(request); 239 | }); 240 | 241 | server.on("/inline", [](AsyncWebServerRequest * request) 242 | { 243 | request->send(200, "text/plain", "This works as well"); 244 | }); 245 | 246 | server.onNotFound(handleNotFound); 247 | 248 | server.begin(); 249 | 250 | Serial.print(F("HTTP EthernetWebServer is @ IP : ")); 251 | Serial.println(Ethernet.localIP()); 252 | } 253 | 254 | void loop() 255 | { 256 | } 257 | -------------------------------------------------------------------------------- /src/AsyncWebResponseImpl_Teensy41.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AsyncWebResponseImpl_Teensy41.h - Dead simple AsyncWebServer for Teensy41 QNEthernet 3 | 4 | For Teensy41 with QNEthernet 5 | 6 | AsyncWebServer_Teensy41 is a library for the Teensy41 with QNEthernet 7 | 8 | Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer) 9 | Built by Khoi Hoang https://github.com/khoih-prog/AsyncWebServer_Teensy41 10 | 11 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 12 | This file is part of the esp8266 core for Arduino environment. 13 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 14 | as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version. 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 | You should have received a copy of the GNU General Public License along with this program. 18 | If not, see . 19 | 20 | Version: 1.7.0 21 | 22 | Version Modified By Date Comments 23 | ------- ----------- ---------- ----------- 24 | 1.4.1 K Hoang 18/03/2022 Initial coding for Teensy 4.1 using built-in QNEthernet. 25 | Bump up version to v1.4.1 to sync with AsyncWebServer_STM32 v1.4.1 26 | 1.5.0 K Hoang 01/10/2022 Fix issue with slow browsers or network. Add function and example to support favicon.ico 27 | 1.6.0 K Hoang 06/10/2022 Option to use non-destroyed cString instead of String to save Heap 28 | 1.6.1 K Hoang 10/11/2022 Add examples to demo how to use beginChunkedResponse() to send in chunks 29 | 1.6.2 K Hoang 16/01/2023 Add examples Async_WebSocketsServer 30 | 1.7.0 K Hoang 29/01/2024 Fix file upload handler by adjusting function signatures 31 | *****************************************************************************************************************************/ 32 | 33 | #pragma once 34 | 35 | #ifndef ASYNCWEBSERVERRESPONSEIMPL_TEENSY41_H_ 36 | #define ASYNCWEBSERVERRESPONSEIMPL_TEENSY41_H_ 37 | 38 | #ifdef Arduino_h 39 | // arduino is not compatible with std::vector 40 | #undef min 41 | #undef max 42 | #endif 43 | 44 | #include 45 | 46 | // It is possible to restore these defines, but one can use _min and _max instead. Or std::min, std::max. 47 | 48 | ///////////////////////////////////////////////// 49 | 50 | class AsyncBasicResponse: public AsyncWebServerResponse 51 | { 52 | private: 53 | String _content; 54 | 55 | char *_contentCstr; // RSMOD 56 | String _partialHeader; 57 | 58 | public: 59 | AsyncBasicResponse(int code, const String& contentType = String(), const String& content = String()); 60 | 61 | AsyncBasicResponse(int code, const String& contentType, const char *content = nullptr); // RSMOD 62 | 63 | void _respond(AsyncWebServerRequest *request); 64 | 65 | size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); 66 | 67 | ///////////////////////////////////////////////// 68 | 69 | inline bool _sourceValid() const 70 | { 71 | return true; 72 | } 73 | 74 | ///////////////////////////////////////////////// 75 | }; 76 | 77 | ///////////////////////////////////////////////// 78 | 79 | class AsyncAbstractResponse: public AsyncWebServerResponse 80 | { 81 | private: 82 | String _head; 83 | // Data is inserted into cache at begin(). 84 | // This is inefficient with vector, but if we use some other container, 85 | // we won't be able to access it as contiguous array of bytes when reading from it, 86 | // so by gaining performance in one place, we'll lose it in another. 87 | std::vector _cache; 88 | size_t _readDataFromCacheOrContent(uint8_t* data, const size_t len); 89 | size_t _fillBufferAndProcessTemplates(uint8_t* buf, size_t maxLen); 90 | 91 | protected: 92 | AwsTemplateProcessor _callback; 93 | 94 | public: 95 | AsyncAbstractResponse(AwsTemplateProcessor callback = nullptr); 96 | void _respond(AsyncWebServerRequest *request); 97 | size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); 98 | 99 | ///////////////////////////////////////////////// 100 | 101 | inline bool _sourceValid() const 102 | { 103 | return false; 104 | } 105 | 106 | ///////////////////////////////////////////////// 107 | 108 | virtual size_t _fillBuffer(uint8_t *buf __attribute__((unused)), size_t maxLen __attribute__((unused))) 109 | { 110 | return 0; 111 | } 112 | 113 | ///////////////////////////////////////////////// 114 | }; 115 | 116 | ///////////////////////////////////////////////// 117 | 118 | #ifndef TEMPLATE_PLACEHOLDER 119 | #define TEMPLATE_PLACEHOLDER '%' 120 | #endif 121 | 122 | ///////////////////////////////////////////////// 123 | 124 | #define TEMPLATE_PARAM_NAME_LENGTH 32 125 | 126 | ///////////////////////////////////////////////// 127 | 128 | class AsyncStreamResponse: public AsyncAbstractResponse 129 | { 130 | private: 131 | Stream *_content; 132 | 133 | public: 134 | AsyncStreamResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); 135 | 136 | ///////////////////////////////////////////////// 137 | 138 | inline bool _sourceValid() const 139 | { 140 | return !!(_content); 141 | } 142 | 143 | ///////////////////////////////////////////////// 144 | 145 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 146 | }; 147 | 148 | ///////////////////////////////////////////////// 149 | 150 | class AsyncCallbackResponse: public AsyncAbstractResponse 151 | { 152 | private: 153 | AwsResponseFiller _content; 154 | size_t _filledLength; 155 | 156 | public: 157 | AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, 158 | AwsTemplateProcessor templateCallback = nullptr); 159 | 160 | ///////////////////////////////////////////////// 161 | 162 | inline bool _sourceValid() const 163 | { 164 | return !!(_content); 165 | } 166 | 167 | ///////////////////////////////////////////////// 168 | 169 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 170 | }; 171 | 172 | ///////////////////////////////////////////////// 173 | 174 | class AsyncChunkedResponse: public AsyncAbstractResponse 175 | { 176 | private: 177 | AwsResponseFiller _content; 178 | size_t _filledLength; 179 | 180 | public: 181 | AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, 182 | AwsTemplateProcessor templateCallback = nullptr); 183 | 184 | ///////////////////////////////////////////////// 185 | 186 | inline bool _sourceValid() const 187 | { 188 | return !!(_content); 189 | } 190 | 191 | ///////////////////////////////////////////////// 192 | 193 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 194 | }; 195 | 196 | ///////////////////////////////////////////////// 197 | 198 | class cbuf; 199 | 200 | ///////////////////////////////////////////////// 201 | 202 | class AsyncProgmemResponse: public AsyncAbstractResponse 203 | { 204 | private: 205 | const uint8_t * _content; 206 | size_t _readLength; 207 | 208 | public: 209 | AsyncProgmemResponse(int code, const String& contentType, const uint8_t * content, size_t len, 210 | AwsTemplateProcessor callback = nullptr); 211 | 212 | ///////////////////////////////////////////////// 213 | 214 | inline bool _sourceValid() const 215 | { 216 | return (_state < RESPONSE_END); 217 | } 218 | 219 | ///////////////////////////////////////////////// 220 | 221 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 222 | }; 223 | 224 | ///////////////////////////////////////////////// 225 | 226 | class AsyncResponseStream: public AsyncAbstractResponse, public Print 227 | { 228 | private: 229 | cbuf *_content; 230 | 231 | public: 232 | AsyncResponseStream(const String& contentType, size_t bufferSize); 233 | ~AsyncResponseStream(); 234 | 235 | ///////////////////////////////////////////////// 236 | 237 | inline bool _sourceValid() const 238 | { 239 | return (_state < RESPONSE_END); 240 | } 241 | 242 | ///////////////////////////////////////////////// 243 | 244 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 245 | size_t write(const uint8_t *data, size_t len); 246 | size_t write(uint8_t data); 247 | using Print::write; 248 | }; 249 | 250 | ///////////////////////////////////////////////// 251 | 252 | #endif /* ASYNCWEBSERVERRESPONSEIMPL_TEENSY41_H_ */ 253 | --------------------------------------------------------------------------------