Merge pull request #192 from mathieucarbou/move

Prepare move to https://github.com/ESP32Async/AsyncTCP
This commit is contained in:
Me No Dev
2025-01-20 18:16:40 +02:00
committed by GitHub
26 changed files with 2125 additions and 1658 deletions

22
.clang-format Normal file
View File

@ -0,0 +1,22 @@
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignConsecutiveMacros: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: Inline
BinPackArguments: false
ColumnLimit: 0
ContinuationIndentWidth: 2
FixNamespaceComments: false
IndentAccessModifiers: true
IndentCaseLabels: true
IndentPPDirectives: BeforeHash
IndentWidth: 2
NamespaceIndentation: All
PointerAlignment: Left
ReferenceAlignment: Left
TabWidth: 2
UseTab: Never

22
.clang-format copy Normal file
View File

@ -0,0 +1,22 @@
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignConsecutiveMacros: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: Inline
BinPackArguments: false
ColumnLimit: 0
ContinuationIndentWidth: 2
FixNamespaceComments: false
IndentAccessModifiers: true
IndentCaseLabels: true
IndentPPDirectives: BeforeHash
IndentWidth: 2
NamespaceIndentation: All
PointerAlignment: Left
ReferenceAlignment: Left
TabWidth: 2
UseTab: Never

35
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,35 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''
---
**Please make sure to go through the recommendations before opening a bug report:**
[https://github.com/ESP32Async/AsyncTCP?tab=readme-ov-file#important-recommendations](https://github.com/ESP32Async/AsyncTCP?tab=readme-ov-file#important-recommendations)
**Description**
A clear and concise description of what the bug is.
**Board**
esp32dev, esp32s3, etc
**Ethernet adapter used ?**
If yes, please specify which one
**Stack trace**
Please provide the stack trace here taken with `monitor_filters = esp32_exception_decoder`.
**Any issue opened with a non readable stack trace will be ignored because not helpful at all.**
As an alternative, you can use [https://maximeborges.github.io/esp-stacktrace-decoder/](https://maximeborges.github.io/esp-stacktrace-decoder/).
**Additional notes**
Add any other context about the problem here.

10
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@ -0,0 +1,10 @@
---
name: Question
about: Describe your question
title: "[Q]"
labels: question
assignees: ''
---

10
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,10 @@
# Set update schedule for GitHub Actions
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"

View File

@ -1,36 +0,0 @@
#!/bin/bash
export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32"
if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
echo "Installing ESP32 Arduino Core ..."
script_init_path="$PWD"
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif"
cd "$ARDUINO_USR_PATH/hardware/espressif"
echo "Installing Python Serial ..."
pip install pyserial > /dev/null
if [ "$OS_IS_WINDOWS" == "1" ]; then
echo "Installing Python Requests ..."
pip install requests > /dev/null
fi
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
echo "Linking Core..."
ln -s $GITHUB_WORKSPACE esp32
else
echo "Cloning Core Repository..."
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
fi
echo "Updating Submodules ..."
cd esp32
git submodule update --init --recursive > /dev/null 2>&1
echo "Installing Platform Tools ..."
cd tools && python get.py
cd $script_init_path
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"
echo ""
fi

View File

@ -1,220 +0,0 @@
#!/bin/bash
#OSTYPE: 'linux-gnu', ARCH: 'x86_64' => linux64
#OSTYPE: 'msys', ARCH: 'x86_64' => win32
#OSTYPE: 'darwin18', ARCH: 'i386' => macos
OSBITS=`arch`
if [[ "$OSTYPE" == "linux"* ]]; then
export OS_IS_LINUX="1"
ARCHIVE_FORMAT="tar.xz"
if [[ "$OSBITS" == "i686" ]]; then
OS_NAME="linux32"
elif [[ "$OSBITS" == "x86_64" ]]; then
OS_NAME="linux64"
elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then
OS_NAME="linuxarm"
else
OS_NAME="$OSTYPE-$OSBITS"
echo "Unknown OS '$OS_NAME'"
exit 1
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
export OS_IS_MACOS="1"
ARCHIVE_FORMAT="zip"
OS_NAME="macosx"
elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
export OS_IS_WINDOWS="1"
ARCHIVE_FORMAT="zip"
OS_NAME="windows"
else
OS_NAME="$OSTYPE-$OSBITS"
echo "Unknown OS '$OS_NAME'"
exit 1
fi
export OS_NAME
ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
if [ "$OS_IS_MACOS" == "1" ]; then
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java"
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
elif [ "$OS_IS_WINDOWS" == "1" ]; then
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
else
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
export ARDUINO_USR_PATH="$HOME/Arduino"
fi
if [ ! -d "$ARDUINO_IDE_PATH" ]; then
echo "Installing Arduino IDE on $OS_NAME ..."
echo "Downloading 'arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
if [ "$OS_IS_LINUX" == "1" ]; then
wget -O "arduino.$ARCHIVE_FORMAT" "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
mv arduino-nightly "$ARDUINO_IDE_PATH"
else
curl -o "arduino.$ARCHIVE_FORMAT" -L "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
if [ "$OS_IS_MACOS" == "1" ]; then
mv "Arduino.app" "/Applications/Arduino.app"
else
mv arduino-nightly "$ARDUINO_IDE_PATH"
fi
fi
rm -rf "arduino.$ARCHIVE_FORMAT"
mkdir -p "$ARDUINO_USR_PATH/libraries"
mkdir -p "$ARDUINO_USR_PATH/hardware"
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
echo ""
fi
function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_sketch <fqbn> <path-to-ino> [extra-options]"
return 1
fi
local fqbn="$1"
local sketch="$2"
local xtra_opts="$3"
local win_opts=""
if [ "$OS_IS_WINDOWS" == "1" ]; then
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
fi
echo ""
echo "Compiling '"$(basename "$sketch")"' ..."
mkdir -p "$ARDUINO_BUILD_DIR"
mkdir -p "$ARDUINO_CACHE_DIR"
$ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 \
-fqbn=$fqbn \
-warnings="all" \
-tools "$ARDUINO_IDE_PATH/tools-builder" \
-tools "$ARDUINO_IDE_PATH/tools" \
-built-in-libraries "$ARDUINO_IDE_PATH/libraries" \
-hardware "$ARDUINO_IDE_PATH/hardware" \
-hardware "$ARDUINO_USR_PATH/hardware" \
-libraries "$ARDUINO_USR_PATH/libraries" \
-build-cache "$ARDUINO_CACHE_DIR" \
-build-path "$ARDUINO_BUILD_DIR" \
$win_opts $xtra_opts "$sketch"
}
function count_sketches() # count_sketches <examples-path>
{
local examples="$1"
rm -rf sketches.txt
if [ ! -d "$examples" ]; then
touch sketches.txt
return 0
fi
local sketches=$(find $examples -name *.ino)
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
continue
fi
echo $sketch >> sketches.txt
sketchnum=$(($sketchnum + 1))
done
return $sketchnum
}
function build_sketches() # build_sketches <fqbn> <examples-path> <chunk> <total-chunks> [extra-options]
{
local fqbn=$1
local examples=$2
local chunk_idex=$3
local chunks_num=$4
local xtra_opts=$5
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_sketches <fqbn> <examples-path> [<chunk> <total-chunks>] [extra-options]"
return 1
fi
if [ "$#" -lt 4 ]; then
chunk_idex="0"
chunks_num="1"
xtra_opts=$3
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
set +e
count_sketches "$examples"
local sketchcount=$?
set -e
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
local start_num=$(( $start_index + 1 ))
echo "Found $sketchcount Sketches";
echo "Chunk Count : $chunks_num"
echo "Chunk Size : $chunk_size"
echo "Start Sketch: $start_num"
echo "End Sketch : $end_index"
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [ "${sketchdirname}.ino" != "$sketchname" ] \
|| [ -f "$sketchdir/.test.skip" ]; then
continue
fi
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
build_sketch "$fqbn" "$sketch" "$xtra_opts"
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
done
return 0
}

View File

@ -1,133 +0,0 @@
#!/bin/bash
echo "Installing Python Wheel ..."
pip install wheel > /dev/null 2>&1
echo "Installing PlatformIO ..."
pip install -U platformio > /dev/null 2>&1
echo "PlatformIO has been installed"
echo ""
function build_pio_sketch(){ # build_pio_sketch <board> <path-to-ino>
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketch <board> <path-to-ino>"
return 1
fi
local board="$1"
local sketch="$2"
local sketch_dir=$(dirname "$sketch")
echo ""
echo "Compiling '"$(basename "$sketch")"' ..."
python -m platformio ci -l '.' --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv"
}
function count_sketches() # count_sketches <examples-path>
{
local examples="$1"
rm -rf sketches.txt
if [ ! -d "$examples" ]; then
touch sketches.txt
return 0
fi
local sketches=$(find $examples -name *.ino)
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
continue
fi
echo $sketch >> sketches.txt
sketchnum=$(($sketchnum + 1))
done
return $sketchnum
}
function build_pio_sketches() # build_pio_sketches <board> <examples-path> <chunk> <total-chunks>
{
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketches <board> <examples-path> [<chunk> <total-chunks>]"
return 1
fi
local board=$1
local examples=$2
local chunk_idex=$3
local chunks_num=$4
if [ "$#" -lt 4 ]; then
chunk_idex="0"
chunks_num="1"
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
set +e
count_sketches "$examples"
local sketchcount=$?
set -e
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
local start_num=$(( $start_index + 1 ))
echo "Found $sketchcount Sketches";
echo "Chunk Count : $chunks_num"
echo "Chunk Size : $chunk_size"
echo "Start Sketch: $start_num"
echo "End Sketch : $end_index"
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [ "${sketchdirname}.ino" != "$sketchname" ] \
|| [ -f "$sketchdir/.test.skip" ]; then
continue
fi
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
build_pio_sketch "$board" "$sketch"
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
done
return 0
}

View File

@ -1,64 +0,0 @@
#!/bin/bash
set -e
if [ ! -z "$TRAVIS_BUILD_DIR" ]; then
export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR"
export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG"
elif [ -z "$GITHUB_WORKSPACE" ]; then
export GITHUB_WORKSPACE="$PWD"
export GITHUB_REPOSITORY="me-no-dev/AsyncTCP"
fi
CHUNK_INDEX=$1
CHUNKS_CNT=$2
BUILD_PIO=0
if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then
CHUNK_INDEX=0
CHUNKS_CNT=1
elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ]; then
CHUNK_INDEX=$CHUNKS_CNT
elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
BUILD_PIO=1
fi
if [ "$BUILD_PIO" -eq 0 ]; then
# ArduinoIDE Test
source ./.github/scripts/install-arduino-ide.sh
source ./.github/scripts/install-arduino-core-esp32.sh
echo "Installing AsyncTCP ..."
cp -rf "$GITHUB_WORKSPACE" "$ARDUINO_USR_PATH/libraries/AsyncTCP"
FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
build_sketches "$FQBN" "$GITHUB_WORKSPACE/examples"
if [ ! "$OS_IS_WINDOWS" == "1" ]; then
echo "Installing ESPAsyncWebServer ..."
git clone https://github.com/me-no-dev/ESPAsyncWebServer "$ARDUINO_USR_PATH/libraries/ESPAsyncWebServer" > /dev/null 2>&1
echo "Installing ArduinoJson ..."
git clone https://github.com/bblanchon/ArduinoJson "$ARDUINO_USR_PATH/libraries/ArduinoJson" > /dev/null 2>&1
build_sketches "$FQBN" "$ARDUINO_USR_PATH/libraries/ESPAsyncWebServer/examples"
fi
else
# PlatformIO Test
source ./.github/scripts/install-platformio.sh
echo "Installing AsyncTCP ..."
python -m platformio lib --storage-dir "$GITHUB_WORKSPACE" install
BOARD="esp32dev"
build_pio_sketches "$BOARD" "$GITHUB_WORKSPACE/examples"
if [[ "$OSTYPE" != "cygwin" ]] && [[ "$OSTYPE" != "msys" ]] && [[ "$OSTYPE" != "win32" ]]; then
echo "Installing ESPAsyncWebServer ..."
python -m platformio lib -g install https://github.com/me-no-dev/ESPAsyncWebServer.git > /dev/null 2>&1
git clone https://github.com/me-no-dev/ESPAsyncWebServer "$HOME/ESPAsyncWebServer" > /dev/null 2>&1
echo "Installing ArduinoJson ..."
python -m platformio lib -g install https://github.com/bblanchon/ArduinoJson.git > /dev/null 2>&1
build_pio_sketches "$BOARD" "$HOME/ESPAsyncWebServer/examples"
fi
fi

95
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,95 @@
name: Async TCP CI
on:
push:
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build-arduino:
name: ${{ matrix.config }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
config: [arduino-cli.yaml, arduino-cli-dev.yaml]
steps:
- uses: actions/checkout@v4
- uses: arduino/setup-arduino-cli@v1
- name: Download board
run: |
arduino-cli --config-file ${{ matrix.config }} core update-index
arduino-cli --config-file ${{ matrix.config }} board listall
arduino-cli --config-file ${{ matrix.config }} core install esp32:esp32
- name: Compile Sketch
run: arduino-cli --config-file ${{ matrix.config }} --library ./src/ compile --fqbn esp32:esp32:esp32 ./examples/Client/Client.ino
- name: Compile Sketch with IPv6
env:
LWIP_IPV6: true
run: arduino-cli --config-file ${{ matrix.config }} --library ./src/ compile --fqbn esp32:esp32:esp32 ./examples/Client/Client.ino
platformio:
name: "pio:${{ matrix.env }}:${{ matrix.board }}"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- env: ci-arduino-2
board: esp32dev
- env: ci-arduino-2
board: esp32-s2-saola-1
- env: ci-arduino-2
board: esp32-s3-devkitc-1
- env: ci-arduino-2
board: esp32-c3-devkitc-02
- env: ci-arduino-3
board: esp32dev
- env: ci-arduino-3
board: esp32-s2-saola-1
- env: ci-arduino-3
board: esp32-s3-devkitc-1
- env: ci-arduino-3
board: esp32-c3-devkitc-02
- env: ci-arduino-3
board: esp32-c6-devkitc-1
- env: ci-arduino-311
board: esp32dev
- env: ci-arduino-311
board: esp32-s2-saola-1
- env: ci-arduino-311
board: esp32-s3-devkitc-1
- env: ci-arduino-311
board: esp32-c3-devkitc-02
- env: ci-arduino-311
board: esp32-c6-devkitc-1
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Cache PlatformIO
uses: actions/cache@v4
with:
key: ${{ runner.os }}-pio
path: |
~/.cache/pip
~/.platformio
- name: Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Build
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio
- run: PLATFORMIO_SRC_DIR=examples/Client PIO_BOARD=${{ matrix.board }} pio run -e ${{ matrix.env }}

View File

@ -1,32 +0,0 @@
name: Async TCP CI
on:
push:
branches:
- master
- release/*
pull_request:
jobs:
build-arduino:
name: Arduino on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- name: Build Tests
run: bash ./.github/scripts/on-push.sh 0 1
build-pio:
name: PlatformIO on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- name: Build Tests
run: bash ./.github/scripts/on-push.sh 1 1

6
.gitignore vendored
View File

@ -1,2 +1,6 @@
.DS_Store
.lh
/.pio
/.vscode
/logs

2
.gitpod.Dockerfile vendored Normal file
View File

@ -0,0 +1,2 @@
FROM gitpod/workspace-python-3.11
USER gitpod

9
.gitpod.yml Normal file
View File

@ -0,0 +1,9 @@
tasks:
- command: pip install --upgrade pip && pip install -U platformio && platformio run
image:
file: .gitpod.Dockerfile
vscode:
extensions:
- shardulm94.trailing-spaces

View File

@ -1,34 +0,0 @@
sudo: false
language: python
os:
- linux
git:
depth: false
stages:
- build
jobs:
include:
- name: "Arduino Build"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh
- name: "PlatformIO Build"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 1 1
notifications:
email:
on_success: change
on_failure: change
webhooks:
urls:
- https://webhooks.gitter.im/e/60e65d0c78ea0a920347
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false

129
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,129 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
https://sidweb.nl/cms3/en/contact.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

60
README.ESP32Async.md Normal file
View File

@ -0,0 +1,60 @@
# AsyncTCP
[![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/)
[![Continuous Integration](https://github.com/ESP32Async/AsyncTCP/actions/workflows/ci.yml/badge.svg)](https://github.com/ESP32Async/AsyncTCP/actions/workflows/ci.yml)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/ESP32Async/library/AsyncTCP.svg)](https://registry.platformio.org/libraries/ESP32Async/AsyncTCP)
Discord Server: [https://discord.gg/X7zpGdyUcY](https://discord.gg/X7zpGdyUcY)
### Async TCP Library for ESP32 Arduino
This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs.
This library is the base for [ESPAsyncWebServer](https://github.com/ESP32Async/ESPAsyncWebServer)
## AsyncClient and AsyncServer
The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use.
## Changes
- `library.properties` for Arduino IDE users
- Add `CONFIG_ASYNC_TCP_MAX_ACK_TIME`
- Add `CONFIG_ASYNC_TCP_PRIORITY`
- Add `CONFIG_ASYNC_TCP_QUEUE_SIZE`
- Add `setKeepAlive()`
- Arduino 3 / ESP-IDF 5 compatibility
- Better CI
- Better example
- Customizable macros
- Fix for "Required to lock TCPIP core functionality". Ref: https://github.com/ESP32Async/AsyncTCP/issues/27 and https://github.com/espressif/arduino-esp32/issues/10526
- Fix for "ack timeout 4" client disconnects.
- Fix from https://github.com/me-no-dev/AsyncTCP/pull/173 (partially applied)
- Fix from https://github.com/me-no-dev/AsyncTCP/pull/184
- IPv6
- LIBRETINY support
- LibreTuya
- Reduce logging of non critical messages
- Use IPADDR6_INIT() macro to set connecting IPv6 address
- xTaskCreateUniversal function
## Coordinates
```
ESP32Async/AsyncTCP @ ^3.3.2
```
## Important recommendations
Most of the crashes are caused by improper configuration of the library for the project.
Here are some recommendations to avoid them.
I personally use the following configuration in my projects:
```c++
-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 // (keep default)
-D CONFIG_ASYNC_TCP_PRIORITY=10 // (keep default)
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=64 // (keep default)
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1 // force async_tcp task to be on same core as the app (default is core 0)
-D CONFIG_ASYNC_TCP_STACK_SIZE=4096 // reduce the stack size (default is 16K)
```

View File

@ -1,13 +1,13 @@
# AsyncTCP
[![Build Status](https://travis-ci.org/me-no-dev/AsyncTCP.svg?branch=master)](https://travis-ci.org/me-no-dev/AsyncTCP) ![](https://github.com/me-no-dev/AsyncTCP/workflows/Async%20TCP%20CI/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/2f7e4d1df8b446d192cbfec6dc174d2d)](https://www.codacy.com/manual/me-no-dev/AsyncTCP?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=me-no-dev/AsyncTCP&amp;utm_campaign=Badge_Grade)
![https://avatars.githubusercontent.com/u/195753706?s=96&v=4](https://avatars.githubusercontent.com/u/195753706?s=96&v=4)
### Async TCP Library for ESP32 Arduino
# Project moved to [ESP32Async](https://github.com/organizations/ESP32Async) organization at [https://github.com/ESP32Async/AsyncTCP](https://github.com/ESP32Async/AsyncTCP)
[![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Discord Server: [https://discord.gg/X7zpGdyUcY](https://discord.gg/X7zpGdyUcY)
This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs.
Please see the new links:
This library is the base for [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer)
## AsyncClient and AsyncServer
The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use.
- `ESP32Async/ESPAsyncWebServer @ 3.6.0` (ESP32, ESP8266, RP2040)
- `ESP32Async/AsyncTCP @ 3.3.2` (ESP32)
- `ESP32Async/ESPAsyncTCP @ 2.0.0` (ESP8266)
- `https://github.com/ESP32Async/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` (AsyncTCP alternative for ESP32)
- `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (RP2040)

25
arduino-cli-dev.yaml Normal file
View File

@ -0,0 +1,25 @@
board_manager:
additional_urls:
- https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json
directories:
builtin.libraries: ./src/
build_cache:
compilations_before_purge: 10
ttl: 720h0m0s
daemon:
port: "50051"
library:
enable_unsafe_install: false
logging:
file: ""
format: text
level: info
metrics:
addr: :9090
enabled: true
output:
no_color: false
sketch:
always_export_binaries: false
updater:
enable_notification: true

25
arduino-cli.yaml Normal file
View File

@ -0,0 +1,25 @@
board_manager:
additional_urls:
- https://espressif.github.io/arduino-esp32/package_esp32_index.json
directories:
builtin.libraries: ./src/
build_cache:
compilations_before_purge: 10
ttl: 720h0m0s
daemon:
port: "50051"
library:
enable_unsafe_install: false
logging:
file: ""
format: text
level: info
metrics:
addr: :9090
enabled: true
output:
no_color: false
sketch:
always_export_binaries: false
updater:
enable_notification: true

View File

@ -0,0 +1,81 @@
#include <Arduino.h>
#include <AsyncTCP.h>
#include <WiFi.h>
// Run a server at the root of the project with:
// > python3 -m http.server 3333
// Now you can open a browser and test it works by visiting http://192.168.125.122:3333/ or http://192.168.125.122:3333/README.md
#define HOST "192.168.125.122"
#define PORT 3333
// WiFi SSID to connect to
#define WIFI_SSID "IoT"
// 16 slots on esp32 (CONFIG_LWIP_MAX_ACTIVE_TCP)
#define MAX_CLIENTS CONFIG_LWIP_MAX_ACTIVE_TCP
// #define MAX_CLIENTS 1
size_t permits = MAX_CLIENTS;
void makeRequest() {
if (!permits)
return;
Serial.printf("** permits: %d\n", permits);
AsyncClient* client = new AsyncClient;
client->onError([](void* arg, AsyncClient* client, int8_t error) {
Serial.printf("** error occurred %s \n", client->errorToString(error));
client->close(true);
delete client;
});
client->onConnect([](void* arg, AsyncClient* client) {
permits--;
Serial.printf("** client has been connected: %" PRIu16 "\n", client->localPort());
client->onDisconnect([](void* arg, AsyncClient* client) {
Serial.printf("** client has been disconnected: %" PRIu16 "\n", client->localPort());
client->close(true);
delete client;
permits++;
makeRequest();
});
client->onData([](void* arg, AsyncClient* client, void* data, size_t len) {
Serial.printf("** data received by client: %" PRIu16 ": len=%u\n", client->localPort(), len);
});
client->write("GET /README.md HTTP/1.1\r\nHost: " HOST "\r\nUser-Agent: ESP\r\nConnection: close\r\n\r\n");
});
if (client->connect(HOST, PORT)) {
} else {
Serial.println("** connection failed");
}
}
void setup() {
Serial.begin(115200);
while (!Serial)
continue;
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("** connected to WiFi");
Serial.println(WiFi.localIP());
for (size_t i = 0; i < MAX_CLIENTS; i++)
makeRequest();
}
void loop() {
delay(1000);
Serial.printf("** free heap: %" PRIu32 "\n", ESP.getFreeHeap());
}

View File

@ -1,22 +1,31 @@
{
"name":"AsyncTCP",
"description":"Asynchronous TCP Library for ESP32",
"keywords":"async,tcp",
"name": "AsyncTCP",
"version": "3.3.2",
"description": "Asynchronous TCP Library for ESP32",
"keywords": "async,tcp",
"repository": {
"type": "git",
"url": "https://github.com/ESP32Async/AsyncTCP.git"
},
"authors":
{
"name": "Hristo Gochkov",
"name": "ESP32Async",
"maintainer": true
},
"repository":
{
"type": "git",
"url": "https://github.com/me-no-dev/AsyncTCP.git"
},
"version": "1.1.1",
"license": "LGPL-3.0",
"frameworks": "arduino",
"platforms": "espressif32",
"build": {
"libCompatMode": 2
}
"platforms": [
"espressif32",
"libretiny"
],
"export": {
"include": [
"examples",
"src",
"library.json",
"library.properties",
"LICENSE",
"README.md"
]
}
}

View File

@ -1,9 +1,11 @@
name=AsyncTCP
version=1.1.1
author=Me-No-Dev
maintainer=Me-No-Dev
name=Async TCP
includes=AsyncTCP.h
version=3.3.2
author=ESP32Async
maintainer=ESP32Async
sentence=Async TCP Library for ESP32
paragraph=Async TCP Library for ESP32
category=Other
url=https://github.com/me-no-dev/AsyncTCP
url=https://github.com/ESP32Async/AsyncTCP.git
architectures=*
license=LGPL-3.0

43
platformio.ini Normal file
View File

@ -0,0 +1,43 @@
[platformio]
default_envs = arduino-2, arduino-3, arduino-311
lib_dir = .
src_dir = examples/Client
[env]
framework = arduino
build_flags =
-Wall -Wextra
-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=5000
-D CONFIG_ASYNC_TCP_PRIORITY=10
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=64
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1
-D CONFIG_ASYNC_TCP_STACK_SIZE=4096
-D CONFIG_ARDUHAL_LOG_COLORS
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
upload_protocol = esptool
monitor_speed = 115200
monitor_filters = esp32_exception_decoder, log2file
board = esp32dev
[env:arduino-2]
platform = espressif32@6.9.0
[env:arduino-3]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip
[env:arduino-311]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.11/platform-espressif32.zip
; CI
[env:ci-arduino-2]
platform = espressif32@6.9.0
board = ${sysenv.PIO_BOARD}
[env:ci-arduino-3]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip
board = ${sysenv.PIO_BOARD}
[env:ci-arduino-311]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.11/platform-espressif32.zip
board = ${sysenv.PIO_BOARD}

File diff suppressed because it is too large Load Diff

View File

@ -22,31 +22,70 @@
#ifndef ASYNCTCP_H_
#define ASYNCTCP_H_
#include "IPAddress.h"
#include "sdkconfig.h"
#include <functional>
extern "C" {
#include "freertos/semphr.h"
#include "lwip/pbuf.h"
}
#define ASYNCTCP_VERSION "3.3.2"
#define ASYNCTCP_VERSION_MAJOR 3
#define ASYNCTCP_VERSION_MINOR 3
#define ASYNCTCP_VERSION_REVISION 2
#define ASYNCTCP_FORK_ESP32Async
//If core is not defined, then we are running in Arduino or PIO
#include "IPAddress.h"
#if ESP_IDF_VERSION_MAJOR < 5
#include "IPv6Address.h"
#endif
#include "lwip/ip6_addr.h"
#include "lwip/ip_addr.h"
#include <functional>
#ifndef LIBRETINY
#include "sdkconfig.h"
extern "C" {
#include "freertos/semphr.h"
#include "lwip/pbuf.h"
}
#else
extern "C" {
#include <lwip/pbuf.h>
#include <semphr.h>
}
#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 // any available core
#endif
// If core is not defined, then we are running in Arduino or PIO
#ifndef CONFIG_ASYNC_TCP_RUNNING_CORE
#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 //any available core
#define CONFIG_ASYNC_TCP_USE_WDT 1 //if enabled, adds between 33us and 200us per event
#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 // any available core
#endif
// guard AsyncTCP task with watchdog
#ifndef CONFIG_ASYNC_TCP_USE_WDT
#define CONFIG_ASYNC_TCP_USE_WDT 1
#endif
#ifndef CONFIG_ASYNC_TCP_STACK_SIZE
#define CONFIG_ASYNC_TCP_STACK_SIZE 8192 * 2
#endif
#ifndef CONFIG_ASYNC_TCP_PRIORITY
#define CONFIG_ASYNC_TCP_PRIORITY 10
#endif
#ifndef CONFIG_ASYNC_TCP_QUEUE_SIZE
#define CONFIG_ASYNC_TCP_QUEUE_SIZE 64
#endif
#ifndef CONFIG_ASYNC_TCP_MAX_ACK_TIME
#define CONFIG_ASYNC_TCP_MAX_ACK_TIME 5000
#endif
class AsyncClient;
#define ASYNC_MAX_ACK_TIME 5000
#define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given)
#define ASYNC_WRITE_FLAG_MORE 0x02 //will not send PSH flag, meaning that there should be more data to be sent before the application should react.
#define ASYNC_WRITE_FLAG_COPY 0x01 // will allocate new buffer to hold the data while sending (else will hold reference to the data given)
#define ASYNC_WRITE_FLAG_MORE 0x02 // will not send PSH flag, meaning that there should be more data to be sent before the application should react.
typedef std::function<void(void*, AsyncClient*)> AcConnectHandler;
typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)> AcAckHandler;
typedef std::function<void(void*, AsyncClient*, int8_t error)> AcErrorHandler;
typedef std::function<void(void*, AsyncClient*, void *data, size_t len)> AcDataHandler;
typedef std::function<void(void*, AsyncClient*, struct pbuf *pb)> AcPacketHandler;
typedef std::function<void(void*, AsyncClient*, void* data, size_t len)> AcDataHandler;
typedef std::function<void(void*, AsyncClient*, struct pbuf* pb)> AcPacketHandler;
typedef std::function<void(void*, AsyncClient*, uint32_t time)> AcTimeoutHandler;
struct tcp_pcb;
@ -57,91 +96,172 @@ class AsyncClient {
AsyncClient(tcp_pcb* pcb = 0);
~AsyncClient();
AsyncClient & operator=(const AsyncClient &other);
AsyncClient & operator+=(const AsyncClient &other);
AsyncClient& operator=(const AsyncClient& other);
AsyncClient& operator+=(const AsyncClient& other);
bool operator==(const AsyncClient &other);
bool operator==(const AsyncClient& other);
bool operator!=(const AsyncClient &other) {
bool operator!=(const AsyncClient& other) {
return !(*this == other);
}
bool connect(IPAddress ip, uint16_t port);
bool connect(const IPAddress& ip, uint16_t port);
#if ESP_IDF_VERSION_MAJOR < 5
bool connect(const IPv6Address& ip, uint16_t port);
#endif
bool connect(const char* host, uint16_t port);
/**
* @brief close connection
*
* @param now - ignored
*/
void close(bool now = false);
void stop();
// same as close()
void stop() { close(false); };
int8_t abort();
bool free();
bool canSend();//ack is not pending
size_t space();//space available in the TCP window
size_t add(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY);//add for sending
bool send();//send all data added with the method above
// ack is not pending
bool canSend();
// TCP buffer space available
size_t space();
//write equals add()+send()
size_t write(const char* data);
size_t write(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY); //only when canSend() == true
/**
* @brief add data to be send (but do not send yet)
* @note add() would call lwip's tcp_write()
By default apiflags=ASYNC_WRITE_FLAG_COPY
You could try to use apiflags with this flag unset to pass data by reference and avoid copy to socket buffer,
but looks like it does not work for Arduino's lwip in ESP32/IDF at least
it is enforced in https://github.com/espressif/esp-lwip/blob/0606eed9d8b98a797514fdf6eabb4daf1c8c8cd9/src/core/tcp_out.c#L422C5-L422C30
if LWIP_NETIF_TX_SINGLE_PBUF is set, and it is set indeed in IDF
https://github.com/espressif/esp-idf/blob/a0f798cfc4bbd624aab52b2c194d219e242d80c1/components/lwip/port/include/lwipopts.h#L744
*
* @param data
* @param size
* @param apiflags
* @return size_t amount of data that has been copied
*/
size_t add(const char* data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY);
/**
* @brief send data previously add()'ed
*
* @return true on success
* @return false on error
*/
bool send();
/**
* @brief add and enqueue data for sending
* @note it is same as add() + send()
* @note only make sense when canSend() == true
*
* @param data
* @param size
* @param apiflags
* @return size_t
*/
size_t write(const char* data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY);
/**
* @brief add and enque data for sending
* @note treats data as null-terminated string
*
* @param data
* @return size_t
*/
size_t write(const char* data) { return data == NULL ? 0 : write(data, strlen(data)); };
uint8_t state();
bool connecting();
bool connected();
bool disconnecting();
bool disconnected();
bool freeable();//disconnected or disconnecting
// disconnected or disconnecting
bool freeable();
uint16_t getMss();
uint32_t getRxTimeout();
void setRxTimeout(uint32_t timeout);//no RX data timeout for the connection in seconds
// no RX data timeout for the connection in seconds
void setRxTimeout(uint32_t timeout);
uint32_t getAckTimeout();
void setAckTimeout(uint32_t timeout);//no ACK timeout for the last sent packet in milliseconds
// no ACK timeout for the last sent packet in milliseconds
void setAckTimeout(uint32_t timeout);
void setNoDelay(bool nodelay);
bool getNoDelay();
void setKeepAlive(uint32_t ms, uint8_t cnt);
uint32_t getRemoteAddress();
uint16_t getRemotePort();
uint32_t getLocalAddress();
uint16_t getLocalPort();
#if LWIP_IPV6
ip6_addr_t getRemoteAddress6();
ip6_addr_t getLocalAddress6();
#if ESP_IDF_VERSION_MAJOR < 5
IPv6Address remoteIP6();
IPv6Address localIP6();
#else
IPAddress remoteIP6();
IPAddress localIP6();
#endif
#endif
//compatibility
// compatibility
IPAddress remoteIP();
uint16_t remotePort();
uint16_t remotePort();
IPAddress localIP();
uint16_t localPort();
uint16_t localPort();
void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect
void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected
void onAck(AcAckHandler cb, void* arg = 0); //ack received
void onError(AcErrorHandler cb, void* arg = 0); //unsuccessful connect or error
void onData(AcDataHandler cb, void* arg = 0); //data received (called if onPacket is not used)
void onPacket(AcPacketHandler cb, void* arg = 0); //data received
void onTimeout(AcTimeoutHandler cb, void* arg = 0); //ack timeout
void onPoll(AcConnectHandler cb, void* arg = 0); //every 125ms when connected
// set callback - on successful connect
void onConnect(AcConnectHandler cb, void* arg = 0);
// set callback - disconnected
void onDisconnect(AcConnectHandler cb, void* arg = 0);
// set callback - ack received
void onAck(AcAckHandler cb, void* arg = 0);
// set callback - unsuccessful connect or error
void onError(AcErrorHandler cb, void* arg = 0);
// set callback - data received (called if onPacket is not used)
void onData(AcDataHandler cb, void* arg = 0);
// set callback - data received
void onPacket(AcPacketHandler cb, void* arg = 0);
// set callback - ack timeout
void onTimeout(AcTimeoutHandler cb, void* arg = 0);
// set callback - every 125ms when connected
void onPoll(AcConnectHandler cb, void* arg = 0);
void ackPacket(struct pbuf * pb);//ack pbuf from onPacket
size_t ack(size_t len); //ack data that you have not acked using the method below
void ackLater(){ _ack_pcb = false; } //will not ack the current packet. Call from onData
// ack pbuf from onPacket
void ackPacket(struct pbuf* pb);
// ack data that you have not acked using the method below
size_t ack(size_t len);
// will not ack the current packet. Call from onData
void ackLater() { _ack_pcb = false; }
const char * errorToString(int8_t error);
const char * stateToString();
static const char* errorToString(int8_t error);
const char* stateToString();
//Do not use any of the functions below!
static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb);
static int8_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err);
static int8_t _s_fin(void *arg, struct tcp_pcb *tpcb, int8_t err);
static int8_t _s_lwip_fin(void *arg, struct tcp_pcb *tpcb, int8_t err);
static void _s_error(void *arg, int8_t err);
static int8_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len);
static int8_t _s_connected(void* arg, void* tpcb, int8_t err);
static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg);
// internal callbacks - Do NOT call any of the functions below in user code!
static int8_t _s_poll(void* arg, struct tcp_pcb* tpcb);
static int8_t _s_recv(void* arg, struct tcp_pcb* tpcb, struct pbuf* pb, int8_t err);
static int8_t _s_fin(void* arg, struct tcp_pcb* tpcb, int8_t err);
static int8_t _s_lwip_fin(void* arg, struct tcp_pcb* tpcb, int8_t err);
static void _s_error(void* arg, int8_t err);
static int8_t _s_sent(void* arg, struct tcp_pcb* tpcb, uint16_t len);
static int8_t _s_connected(void* arg, struct tcp_pcb* tpcb, int8_t err);
static void _s_dns_found(const char* name, struct ip_addr* ipaddr, void* arg);
int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err);
tcp_pcb * pcb(){ return _pcb; }
tcp_pcb* pcb() { return _pcb; }
protected:
bool _connect(ip_addr_t addr, uint16_t port);
tcp_pcb* _pcb;
int8_t _closed_slot;
int8_t _closed_slot;
AcConnectHandler _connect_cb;
void* _connect_cb_arg;
@ -160,25 +280,25 @@ class AsyncClient {
AcConnectHandler _poll_cb;
void* _poll_cb_arg;
bool _pcb_busy;
uint32_t _pcb_sent_at;
bool _ack_pcb;
uint32_t _tx_last_packet;
uint32_t _rx_ack_len;
uint32_t _rx_last_packet;
uint32_t _rx_since_timeout;
uint32_t _rx_timeout;
uint32_t _rx_last_ack;
uint32_t _ack_timeout;
uint16_t _connect_port;
int8_t _close();
void _free_closed_slot();
void _allocate_closed_slot();
int8_t _connected(void* pcb, int8_t err);
bool _allocate_closed_slot();
int8_t _connected(tcp_pcb* pcb, int8_t err);
void _error(int8_t err);
int8_t _poll(tcp_pcb* pcb);
int8_t _sent(tcp_pcb* pcb, uint16_t len);
int8_t _fin(tcp_pcb* pcb, int8_t err);
int8_t _lwip_fin(tcp_pcb* pcb, int8_t err);
void _dns_found(struct ip_addr *ipaddr);
void _dns_found(struct ip_addr* ipaddr);
public:
AsyncClient* prev;
@ -188,6 +308,9 @@ class AsyncClient {
class AsyncServer {
public:
AsyncServer(IPAddress addr, uint16_t port);
#if ESP_IDF_VERSION_MAJOR < 5
AsyncServer(IPv6Address addr, uint16_t port);
#endif
AsyncServer(uint16_t port);
~AsyncServer();
void onClient(AcConnectHandler cb, void* arg);
@ -197,13 +320,18 @@ class AsyncServer {
bool getNoDelay();
uint8_t status();
//Do not use any of the functions below!
static int8_t _s_accept(void *arg, tcp_pcb* newpcb, int8_t err);
static int8_t _s_accepted(void *arg, AsyncClient* client);
// Do not use any of the functions below!
static int8_t _s_accept(void* arg, tcp_pcb* newpcb, int8_t err);
static int8_t _s_accepted(void* arg, AsyncClient* client);
protected:
uint16_t _port;
bool _bind4 = false;
bool _bind6 = false;
IPAddress _addr;
#if ESP_IDF_VERSION_MAJOR < 5
IPv6Address _addr6;
#endif
bool _noDelay;
tcp_pcb* _pcb;
AcConnectHandler _connect_cb;
@ -213,5 +341,4 @@ class AsyncServer {
int8_t _accepted(AsyncClient* client);
};
#endif /* ASYNCTCP_H_ */