├── 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 | [](https://www.ardu-badge.com/AsyncWebServer_Teensy41)
4 | [](https://github.com/khoih-prog/AsyncWebServer_Teensy41/releases)
5 | [](https://github.com/khoih-prog/AsyncWebServer_Teensy41/blob/master/LICENSE)
6 | [](#Contributing)
7 | [](http://github.com/khoih-prog/AsyncWebServer_Teensy41/issues)
8 |
9 |
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 | \
62 | POST form data to /postform/
\
63 | \
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| INDEX | DATA |
";
113 |
114 | for (uint16_t lineIndex = 0; lineIndex < 500; lineIndex++)
115 | {
116 | out += "| ";
117 | out += String(lineIndex);
118 | out += " | ";
119 | out += "Teensy41_AsyncWebServer_SendChunked_ABCDEFGHIJKLMNOPQRSTUVWXYZ |
";
120 | }
121 |
122 | out += "
\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";
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";
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 |
--------------------------------------------------------------------------------