diff --git a/lib/AsyncTCP/CMakeLists.txt b/lib/AsyncTCP/CMakeLists.txt
deleted file mode 100644
index f52e1c9..0000000
--- a/lib/AsyncTCP/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-set(COMPONENT_SRCDIRS
- "src"
-)
-
-set(COMPONENT_ADD_INCLUDEDIRS
- "src"
-)
-
-set(COMPONENT_REQUIRES
- "arduino-esp32"
-)
-
-register_component()
-
-target_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti)
diff --git a/lib/AsyncTCP/Kconfig.projbuild b/lib/AsyncTCP/Kconfig.projbuild
deleted file mode 100644
index 1774926..0000000
--- a/lib/AsyncTCP/Kconfig.projbuild
+++ /dev/null
@@ -1,30 +0,0 @@
-menu "AsyncTCP Configuration"
-
-choice ASYNC_TCP_RUNNING_CORE
- bool "Core on which AsyncTCP's thread is running"
- default ASYNC_TCP_RUN_CORE1
- help
- Select on which core AsyncTCP is running
-
- config ASYNC_TCP_RUN_CORE0
- bool "CORE 0"
- config ASYNC_TCP_RUN_CORE1
- bool "CORE 1"
- config ASYNC_TCP_RUN_NO_AFFINITY
- bool "BOTH"
-
-endchoice
-
-config ASYNC_TCP_RUNNING_CORE
- int
- default 0 if ASYNC_TCP_RUN_CORE0
- default 1 if ASYNC_TCP_RUN_CORE1
- default -1 if ASYNC_TCP_RUN_NO_AFFINITY
-
-config ASYNC_TCP_USE_WDT
- bool "Enable WDT for the AsyncTCP task"
- default "y"
- help
- Enable WDT for the AsyncTCP task, so it will trigger if a handler is locking the thread.
-
-endmenu
diff --git a/lib/AsyncTCP/LICENSE b/lib/AsyncTCP/LICENSE
deleted file mode 100644
index 65c5ca8..0000000
--- a/lib/AsyncTCP/LICENSE
+++ /dev/null
@@ -1,165 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/lib/AsyncTCP/README.md b/lib/AsyncTCP/README.md
deleted file mode 100644
index 61ccd09..0000000
--- a/lib/AsyncTCP/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# AsyncTCP
-
-[](https://opensource.org/license/lgpl-3-0/)
-[](https://github.com/mathieucarbou/AsyncTCP/actions/workflows/ci.yml)
-[](https://registry.platformio.org/libraries/mathieucarbou/AsyncTCP)
-
-A fork of the [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) library by [@me-no-dev](https://github.com/me-no-dev) for [ESPHome](https://esphome.io).
-
-### 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/mathieucarbou/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 in this fork
-
-- All improvements from [ESPHome fork](https://github.com/esphome/AsyncTCP)
-- Reverted back `library.properties` for Arduino IDE users
-- Arduino 3 / ESP-IDF 5 compatibility
-- IPv6 support
-
-## Coordinates
-
-```
-mathieucarbou/AsyncTCP @ ^3.2.4
-```
-
-## Important recommendations
-
-Most of the crashes are caused by improper configuration of the library for the project.
-Here are some recommendations to avoid them.
-
-1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1`
-2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`.
- The default value of `16384` might be too much for your project.
- You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage.
-3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`.
- Default is `10`.
-4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`.
- Default is `64`.
-5. You can decrease the maximum ack time `-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000`.
- Default is `5000`.
-
-I personally use the following configuration in my projects:
-
-```c++
- -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000
- -D CONFIG_ASYNC_TCP_PRIORITY=10
- -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128
- -D CONFIG_ASYNC_TCP_RUNNING_CORE=1
- -D CONFIG_ASYNC_TCP_STACK_SIZE=4096
-```
diff --git a/lib/AsyncTCP/arduino-cli-dev.yaml b/lib/AsyncTCP/arduino-cli-dev.yaml
deleted file mode 100644
index 174df7a..0000000
--- a/lib/AsyncTCP/arduino-cli-dev.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-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
diff --git a/lib/AsyncTCP/arduino-cli.yaml b/lib/AsyncTCP/arduino-cli.yaml
deleted file mode 100644
index 42365f4..0000000
--- a/lib/AsyncTCP/arduino-cli.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-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
diff --git a/lib/AsyncTCP/component.mk b/lib/AsyncTCP/component.mk
deleted file mode 100644
index bb5bb16..0000000
--- a/lib/AsyncTCP/component.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-COMPONENT_ADD_INCLUDEDIRS := src
-COMPONENT_SRCDIRS := src
-CXXFLAGS += -fno-rtti
diff --git a/lib/AsyncTCP/examples/ClientServer/Client/Client.ino b/lib/AsyncTCP/examples/ClientServer/Client/Client.ino
deleted file mode 100644
index 47d8bc7..0000000
--- a/lib/AsyncTCP/examples/ClientServer/Client/Client.ino
+++ /dev/null
@@ -1,42 +0,0 @@
-#include
-
-#include "config.h"
-
-static void replyToServer(void* arg) {
- AsyncClient* client = reinterpret_cast(arg);
-
- // send reply
- if (client->space() > 32 && client->canSend()) {
- char message[32];
- client->add(message, strlen(message));
- client->send();
- }
-}
-
-/* event callbacks */
-static void handleData(void* arg, AsyncClient* client, void *data, size_t len) {
- Serial.printf("\n data received from %s \n", client->remoteIP().toString().c_str());
- Serial.write((uint8_t*)data, len);
-
-}
-
-void onConnect(void* arg, AsyncClient* client) {
- Serial.printf("\n client has been connected to %s on port %d \n", SERVER_HOST_NAME, TCP_PORT);
- replyToServer(client);
-}
-
-
-void setup() {
- Serial.begin(115200);
- delay(20);
-
- AsyncClient* client = new AsyncClient;
- client->onData(&handleData, client);
- client->onConnect(&onConnect, client);
- client->connect(SERVER_HOST_NAME, TCP_PORT);
-
-}
-
-void loop() {
-
-}
diff --git a/lib/AsyncTCP/examples/ClientServer/Client/config.h b/lib/AsyncTCP/examples/ClientServer/Client/config.h
deleted file mode 100644
index cf51e91..0000000
--- a/lib/AsyncTCP/examples/ClientServer/Client/config.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef CONFIG_H
-#define CONFIG_H
-
-/*
- * This example demonstrate how to use asynchronous client & server APIs
- * in order to establish tcp socket connections in client server manner.
- * server is running (on port 7050) on one ESP, acts as AP, and other clients running on
- * remaining ESPs acts as STAs. after connection establishment between server and clients
- * there is a simple message transfer in every 2s. clients connect to server via it's host name
- * (in this case 'esp_server') with help of DNS service running on server side.
- *
- * Note: default MSS for ESPAsyncTCP is 536 byte and defualt ACK timeout is 5s.
-*/
-
-#define SSID "ESP-TEST"
-#define PASSWORD "123456789"
-
-#define SERVER_HOST_NAME "esp_server"
-
-#define TCP_PORT 7050
-#define DNS_PORT 53
-
-#endif // CONFIG_H
diff --git a/lib/AsyncTCP/library.json b/lib/AsyncTCP/library.json
deleted file mode 100644
index c449f2a..0000000
--- a/lib/AsyncTCP/library.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "name": "AsyncTCP",
- "version": "3.2.4",
- "description": "Asynchronous TCP Library for ESP32",
- "keywords": "async,tcp",
- "repository": {
- "type": "git",
- "url": "https://github.com/mathieucarbou/AsyncTCP.git"
- },
- "authors": [
- {
- "name": "Hristo Gochkov"
- },
- {
- "name": "Mathieu Carbou",
- "maintainer": true
- }
- ],
- "license": "LGPL-3.0",
- "frameworks": "arduino",
- "platforms": [
- "espressif32",
- "libretiny"
- ],
- "build": {
- "libCompatMode": 2
- },
- "export": {
- "include": [
- "examples",
- "src",
- "library.json",
- "library.properties",
- "LICENSE",
- "README.md"
- ]
- }
-}
\ No newline at end of file
diff --git a/lib/AsyncTCP/library.properties b/lib/AsyncTCP/library.properties
deleted file mode 100644
index 12a504c..0000000
--- a/lib/AsyncTCP/library.properties
+++ /dev/null
@@ -1,9 +0,0 @@
-name=AsyncTCP
-version=3.2.4
-author=Me-No-Dev
-maintainer=Mathieu Carbou
-sentence=Async TCP Library for ESP32
-paragraph=Async TCP Library for ESP32
-category=Other
-url=https://github.com/mathieucarbou/AsyncTCP.git
-architectures=*
diff --git a/lib/AsyncTCP/platformio.ini b/lib/AsyncTCP/platformio.ini
deleted file mode 100644
index 4cfad22..0000000
--- a/lib/AsyncTCP/platformio.ini
+++ /dev/null
@@ -1,48 +0,0 @@
-[env]
-framework = arduino
-build_flags =
- -Wall -Wextra
- -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
-
-[platformio]
-lib_dir = .
-src_dir = examples/ClientServer/Client
-
-[env:arduino]
-platform = espressif32
-board = esp32dev
-
-[env:arduino-2]
-platform = espressif32@6.7.0
-board = esp32dev
-
-[env:arduino-3]
-platform = espressif32
-platform_packages=
- platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.3
- platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.3/esp32-arduino-libs-3.0.3.zip
-board = esp32dev
-
-[env:pioarduino-esp32dev]
-platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip
-board = esp32dev
-
-[env:pioarduino-esp32-s2]
-platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip
-board = esp32-s2-saola-1
-
-[env:pioarduino-esp32-s3]
-platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip
-board = esp32-s3-devkitc-1
-
-[env:pioarduino-esp32-c3]
-platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip
-board = esp32-c3-devkitc-02
-
-[env:pioarduino-esp32-c6]
-platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip
-board = esp32-c6-devkitc-1
diff --git a/lib/AsyncTCP/src/AsyncTCP.cpp b/lib/AsyncTCP/src/AsyncTCP.cpp
deleted file mode 100644
index 2dae2cb..0000000
--- a/lib/AsyncTCP/src/AsyncTCP.cpp
+++ /dev/null
@@ -1,1557 +0,0 @@
-/*
- Asynchronous TCP library for Espressif MCUs
-
- Copyright (c) 2016 Hristo Gochkov. All rights reserved.
- This file is part of the esp8266 core for Arduino environment.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "Arduino.h"
-
-#include "AsyncTCP.h"
-extern "C"{
-#include "lwip/opt.h"
-#include "lwip/tcp.h"
-#include "lwip/inet.h"
-#include "lwip/dns.h"
-#include "lwip/err.h"
-}
-#if CONFIG_ASYNC_TCP_USE_WDT
-#include "esp_task_wdt.h"
-#endif
-
-// Required for:
-// https://github.com/espressif/arduino-esp32/blob/3.0.3/libraries/Network/src/NetworkInterface.cpp#L37-L47
-#if ESP_IDF_VERSION_MAJOR >= 5
-#include
-#endif
-
-/*
- * TCP/IP Event Task
- * */
-
-typedef enum {
- LWIP_TCP_SENT, LWIP_TCP_RECV, LWIP_TCP_FIN, LWIP_TCP_ERROR, LWIP_TCP_POLL, LWIP_TCP_CLEAR, LWIP_TCP_ACCEPT, LWIP_TCP_CONNECTED, LWIP_TCP_DNS
-} lwip_event_t;
-
-typedef struct {
- lwip_event_t event;
- void *arg;
- union {
- struct {
- tcp_pcb * pcb;
- int8_t err;
- } connected;
- struct {
- int8_t err;
- } error;
- struct {
- tcp_pcb * pcb;
- uint16_t len;
- } sent;
- struct {
- tcp_pcb * pcb;
- pbuf * pb;
- int8_t err;
- } recv;
- struct {
- tcp_pcb * pcb;
- int8_t err;
- } fin;
- struct {
- tcp_pcb * pcb;
- } poll;
- struct {
- AsyncClient * client;
- } accept;
- struct {
- const char * name;
- ip_addr_t addr;
- } dns;
- };
-} lwip_event_packet_t;
-
-static QueueHandle_t _async_queue;
-static TaskHandle_t _async_service_task_handle = NULL;
-
-
-SemaphoreHandle_t _slots_lock;
-const int _number_of_closed_slots = CONFIG_LWIP_MAX_ACTIVE_TCP;
-static uint32_t _closed_slots[_number_of_closed_slots];
-static uint32_t _closed_index = []() {
- _slots_lock = xSemaphoreCreateBinary();
- xSemaphoreGive(_slots_lock);
- for (int i = 0; i < _number_of_closed_slots; ++ i) {
- _closed_slots[i] = 1;
- }
- return 1;
-}();
-
-
-static inline bool _init_async_event_queue(){
- if(!_async_queue){
- _async_queue = xQueueCreate(CONFIG_ASYNC_TCP_QUEUE_SIZE, sizeof(lwip_event_packet_t *));
- if(!_async_queue){
- return false;
- }
- }
- return true;
-}
-
-static inline bool _send_async_event(lwip_event_packet_t ** e){
- return _async_queue && xQueueSend(_async_queue, e, portMAX_DELAY) == pdPASS;
-}
-
-static inline bool _prepend_async_event(lwip_event_packet_t ** e){
- return _async_queue && xQueueSendToFront(_async_queue, e, portMAX_DELAY) == pdPASS;
-}
-
-static inline bool _get_async_event(lwip_event_packet_t ** e){
- return _async_queue && xQueueReceive(_async_queue, e, portMAX_DELAY) == pdPASS;
-}
-
-static bool _remove_events_with_arg(void * arg){
- lwip_event_packet_t * first_packet = NULL;
- lwip_event_packet_t * packet = NULL;
-
- if(!_async_queue){
- return false;
- }
- //figure out which is the first packet so we can keep the order
- while(!first_packet){
- if(xQueueReceive(_async_queue, &first_packet, 0) != pdPASS){
- return false;
- }
- //discard packet if matching
- if((int)first_packet->arg == (int)arg){
- free(first_packet);
- first_packet = NULL;
- //return first packet to the back of the queue
- } else if(xQueueSend(_async_queue, &first_packet, portMAX_DELAY) != pdPASS){
- return false;
- }
- }
-
- while(xQueuePeek(_async_queue, &packet, 0) == pdPASS && packet != first_packet){
- if(xQueueReceive(_async_queue, &packet, 0) != pdPASS){
- return false;
- }
- if((int)packet->arg == (int)arg){
- free(packet);
- packet = NULL;
- } else if(xQueueSend(_async_queue, &packet, portMAX_DELAY) != pdPASS){
- return false;
- }
- }
- return true;
-}
-
-static void _handle_async_event(lwip_event_packet_t * e){
- if(e->arg == NULL){
- // do nothing when arg is NULL
- //ets_printf("event arg == NULL: 0x%08x\n", e->recv.pcb);
- } else if(e->event == LWIP_TCP_CLEAR){
- _remove_events_with_arg(e->arg);
- } else if(e->event == LWIP_TCP_RECV){
- //ets_printf("-R: 0x%08x\n", e->recv.pcb);
- AsyncClient::_s_recv(e->arg, e->recv.pcb, e->recv.pb, e->recv.err);
- } else if(e->event == LWIP_TCP_FIN){
- //ets_printf("-F: 0x%08x\n", e->fin.pcb);
- AsyncClient::_s_fin(e->arg, e->fin.pcb, e->fin.err);
- } else if(e->event == LWIP_TCP_SENT){
- //ets_printf("-S: 0x%08x\n", e->sent.pcb);
- AsyncClient::_s_sent(e->arg, e->sent.pcb, e->sent.len);
- } else if(e->event == LWIP_TCP_POLL){
- //ets_printf("-P: 0x%08x\n", e->poll.pcb);
- AsyncClient::_s_poll(e->arg, e->poll.pcb);
- } else if(e->event == LWIP_TCP_ERROR){
- //ets_printf("-E: 0x%08x %d\n", e->arg, e->error.err);
- AsyncClient::_s_error(e->arg, e->error.err);
- } else if(e->event == LWIP_TCP_CONNECTED){
- //ets_printf("C: 0x%08x 0x%08x %d\n", e->arg, e->connected.pcb, e->connected.err);
- AsyncClient::_s_connected(e->arg, e->connected.pcb, e->connected.err);
- } else if(e->event == LWIP_TCP_ACCEPT){
- //ets_printf("A: 0x%08x 0x%08x\n", e->arg, e->accept.client);
- AsyncServer::_s_accepted(e->arg, e->accept.client);
- } else if(e->event == LWIP_TCP_DNS){
- //ets_printf("D: 0x%08x %s = %s\n", e->arg, e->dns.name, ipaddr_ntoa(&e->dns.addr));
- AsyncClient::_s_dns_found(e->dns.name, &e->dns.addr, e->arg);
- }
- free((void*)(e));
-}
-
-static void _async_service_task(void *pvParameters){
- lwip_event_packet_t * packet = NULL;
- for (;;) {
- if(_get_async_event(&packet)){
-#if CONFIG_ASYNC_TCP_USE_WDT
- if(esp_task_wdt_add(NULL) != ESP_OK){
- log_e("Failed to add async task to WDT");
- }
-#endif
- _handle_async_event(packet);
-#if CONFIG_ASYNC_TCP_USE_WDT
- if(esp_task_wdt_delete(NULL) != ESP_OK){
- log_e("Failed to remove loop task from WDT");
- }
-#endif
- }
- }
- vTaskDelete(NULL);
- _async_service_task_handle = NULL;
-}
-/*
-static void _stop_async_task(){
- if(_async_service_task_handle){
- vTaskDelete(_async_service_task_handle);
- _async_service_task_handle = NULL;
- }
-}
-*/
-
-static bool customTaskCreateUniversal(
- TaskFunction_t pxTaskCode,
- const char * const pcName,
- const uint32_t usStackDepth,
- void * const pvParameters,
- UBaseType_t uxPriority,
- TaskHandle_t * const pxCreatedTask,
- const BaseType_t xCoreID) {
-#ifndef CONFIG_FREERTOS_UNICORE
- if(xCoreID >= 0 && xCoreID < 2) {
- return xTaskCreatePinnedToCore(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, xCoreID);
- } else {
-#endif
- return xTaskCreate(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask);
-#ifndef CONFIG_FREERTOS_UNICORE
- }
-#endif
-}
-
-static bool _start_async_task(){
- if(!_init_async_event_queue()){
- return false;
- }
- if(!_async_service_task_handle){
- customTaskCreateUniversal(_async_service_task, "async_tcp", CONFIG_ASYNC_TCP_STACK_SIZE, NULL, CONFIG_ASYNC_TCP_PRIORITY, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE);
- if(!_async_service_task_handle){
- return false;
- }
- }
- return true;
-}
-
-/*
- * LwIP Callbacks
- * */
-
-static int8_t _tcp_clear_events(void * arg) {
- lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t));
- e->event = LWIP_TCP_CLEAR;
- e->arg = arg;
- if (!_prepend_async_event(&e)) {
- free((void*)(e));
- }
- return ERR_OK;
-}
-
-static int8_t _tcp_connected(void * arg, tcp_pcb * pcb, int8_t err) {
- //ets_printf("+C: 0x%08x\n", pcb);
- lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t));
- e->event = LWIP_TCP_CONNECTED;
- e->arg = arg;
- e->connected.pcb = pcb;
- e->connected.err = err;
- if (!_prepend_async_event(&e)) {
- free((void*)(e));
- }
- return ERR_OK;
-}
-
-static int8_t _tcp_poll(void * arg, struct tcp_pcb * pcb) {
- //ets_printf("+P: 0x%08x\n", pcb);
- lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t));
- e->event = LWIP_TCP_POLL;
- e->arg = arg;
- e->poll.pcb = pcb;
- if (!_send_async_event(&e)) {
- free((void*)(e));
- }
- return ERR_OK;
-}
-
-static int8_t _tcp_recv(void * arg, struct tcp_pcb * pcb, struct pbuf *pb, int8_t err) {
- lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t));
- e->arg = arg;
- if(pb){
- //ets_printf("+R: 0x%08x\n", pcb);
- e->event = LWIP_TCP_RECV;
- e->recv.pcb = pcb;
- e->recv.pb = pb;
- e->recv.err = err;
- } else {
- //ets_printf("+F: 0x%08x\n", pcb);
- e->event = LWIP_TCP_FIN;
- e->fin.pcb = pcb;
- e->fin.err = err;
- //close the PCB in LwIP thread
- AsyncClient::_s_lwip_fin(e->arg, e->fin.pcb, e->fin.err);
- }
- if (!_send_async_event(&e)) {
- free((void*)(e));
- }
- return ERR_OK;
-}
-
-static int8_t _tcp_sent(void * arg, struct tcp_pcb * pcb, uint16_t len) {
- //ets_printf("+S: 0x%08x\n", pcb);
- lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t));
- e->event = LWIP_TCP_SENT;
- e->arg = arg;
- e->sent.pcb = pcb;
- e->sent.len = len;
- if (!_send_async_event(&e)) {
- free((void*)(e));
- }
- return ERR_OK;
-}
-
-static void _tcp_error(void * arg, int8_t err) {
- //ets_printf("+E: 0x%08x\n", arg);
- lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t));
- e->event = LWIP_TCP_ERROR;
- e->arg = arg;
- e->error.err = err;
- if (!_send_async_event(&e)) {
- free((void*)(e));
- }
-}
-
-static void _tcp_dns_found(const char * name, struct ip_addr * ipaddr, void * arg) {
- lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t));
- //ets_printf("+DNS: name=%s ipaddr=0x%08x arg=%x\n", name, ipaddr, arg);
- e->event = LWIP_TCP_DNS;
- e->arg = arg;
- e->dns.name = name;
- if (ipaddr) {
- memcpy(&e->dns.addr, ipaddr, sizeof(struct ip_addr));
- } else {
- memset(&e->dns.addr, 0, sizeof(e->dns.addr));
- }
- if (!_send_async_event(&e)) {
- free((void*)(e));
- }
-}
-
-//Used to switch out from LwIP thread
-static int8_t _tcp_accept(void * arg, AsyncClient * client) {
- lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t));
- e->event = LWIP_TCP_ACCEPT;
- e->arg = arg;
- e->accept.client = client;
- if (!_prepend_async_event(&e)) {
- free((void*)(e));
- }
- return ERR_OK;
-}
-
-/*
- * TCP/IP API Calls
- * */
-
-#include "lwip/priv/tcpip_priv.h"
-
-typedef struct {
- struct tcpip_api_call_data call;
- tcp_pcb * pcb;
- int8_t closed_slot;
- int8_t err;
- union {
- struct {
- const char* data;
- size_t size;
- uint8_t apiflags;
- } write;
- size_t received;
- struct {
- ip_addr_t * addr;
- uint16_t port;
- tcp_connected_fn cb;
- } connect;
- struct {
- ip_addr_t * addr;
- uint16_t port;
- } bind;
- uint8_t backlog;
- };
-} tcp_api_call_t;
-
-static err_t _tcp_output_api(struct tcpip_api_call_data *api_call_msg){
- tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
- msg->err = ERR_CONN;
- if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
- msg->err = tcp_output(msg->pcb);
- }
- return msg->err;
-}
-
-static esp_err_t _tcp_output(tcp_pcb * pcb, int8_t closed_slot) {
- if(!pcb){
- return ERR_CONN;
- }
- tcp_api_call_t msg;
- msg.pcb = pcb;
- msg.closed_slot = closed_slot;
- tcpip_api_call(_tcp_output_api, (struct tcpip_api_call_data*)&msg);
- return msg.err;
-}
-
-static err_t _tcp_write_api(struct tcpip_api_call_data *api_call_msg){
- tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
- msg->err = ERR_CONN;
- if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
- msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags);
- }
- return msg->err;
-}
-
-static esp_err_t _tcp_write(tcp_pcb * pcb, int8_t closed_slot, const char* data, size_t size, uint8_t apiflags) {
- if(!pcb){
- return ERR_CONN;
- }
- tcp_api_call_t msg;
- msg.pcb = pcb;
- msg.closed_slot = closed_slot;
- msg.write.data = data;
- msg.write.size = size;
- msg.write.apiflags = apiflags;
- tcpip_api_call(_tcp_write_api, (struct tcpip_api_call_data*)&msg);
- return msg.err;
-}
-
-static err_t _tcp_recved_api(struct tcpip_api_call_data *api_call_msg){
- tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
- msg->err = ERR_CONN;
- if(msg->closed_slot != -1 && !_closed_slots[msg->closed_slot]) {
- msg->err = 0;
- tcp_recved(msg->pcb, msg->received);
- }
- return msg->err;
-}
-
-static esp_err_t _tcp_recved(tcp_pcb * pcb, int8_t closed_slot, size_t len) {
- if(!pcb){
- return ERR_CONN;
- }
- tcp_api_call_t msg;
- msg.pcb = pcb;
- msg.closed_slot = closed_slot;
- msg.received = len;
- tcpip_api_call(_tcp_recved_api, (struct tcpip_api_call_data*)&msg);
- return msg.err;
-}
-
-static err_t _tcp_close_api(struct tcpip_api_call_data *api_call_msg){
- tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
- msg->err = ERR_CONN;
- if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
- msg->err = tcp_close(msg->pcb);
- }
- return msg->err;
-}
-
-static esp_err_t _tcp_close(tcp_pcb * pcb, int8_t closed_slot) {
- if(!pcb){
- return ERR_CONN;
- }
- tcp_api_call_t msg;
- msg.pcb = pcb;
- msg.closed_slot = closed_slot;
- tcpip_api_call(_tcp_close_api, (struct tcpip_api_call_data*)&msg);
- return msg.err;
-}
-
-static err_t _tcp_abort_api(struct tcpip_api_call_data *api_call_msg){
- tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
- msg->err = ERR_CONN;
- if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
- tcp_abort(msg->pcb);
- }
- return msg->err;
-}
-
-static esp_err_t _tcp_abort(tcp_pcb * pcb, int8_t closed_slot) {
- if(!pcb){
- return ERR_CONN;
- }
- tcp_api_call_t msg;
- msg.pcb = pcb;
- msg.closed_slot = closed_slot;
- tcpip_api_call(_tcp_abort_api, (struct tcpip_api_call_data*)&msg);
- return msg.err;
-}
-
-static err_t _tcp_connect_api(struct tcpip_api_call_data *api_call_msg){
- tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
- msg->err = tcp_connect(msg->pcb, msg->connect.addr, msg->connect.port, msg->connect.cb);
- return msg->err;
-}
-
-static esp_err_t _tcp_connect(tcp_pcb * pcb, int8_t closed_slot, ip_addr_t * addr, uint16_t port, tcp_connected_fn cb) {
- if(!pcb){
- return ESP_FAIL;
- }
- tcp_api_call_t msg;
- msg.pcb = pcb;
- msg.closed_slot = closed_slot;
- msg.connect.addr = addr;
- msg.connect.port = port;
- msg.connect.cb = cb;
- tcpip_api_call(_tcp_connect_api, (struct tcpip_api_call_data*)&msg);
- return msg.err;
-}
-
-static err_t _tcp_bind_api(struct tcpip_api_call_data *api_call_msg){
- tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
- msg->err = tcp_bind(msg->pcb, msg->bind.addr, msg->bind.port);
- return msg->err;
-}
-
-static esp_err_t _tcp_bind(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port) {
- if(!pcb){
- return ESP_FAIL;
- }
- tcp_api_call_t msg;
- msg.pcb = pcb;
- msg.closed_slot = -1;
- msg.bind.addr = addr;
- msg.bind.port = port;
- tcpip_api_call(_tcp_bind_api, (struct tcpip_api_call_data*)&msg);
- return msg.err;
-}
-
-static err_t _tcp_listen_api(struct tcpip_api_call_data *api_call_msg){
- tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
- msg->err = 0;
- msg->pcb = tcp_listen_with_backlog(msg->pcb, msg->backlog);
- return msg->err;
-}
-
-static tcp_pcb * _tcp_listen_with_backlog(tcp_pcb * pcb, uint8_t backlog) {
- if(!pcb){
- return NULL;
- }
- tcp_api_call_t msg;
- msg.pcb = pcb;
- msg.closed_slot = -1;
- msg.backlog = backlog?backlog:0xFF;
- tcpip_api_call(_tcp_listen_api, (struct tcpip_api_call_data*)&msg);
- return msg.pcb;
-}
-
-
-
-/*
- Async TCP Client
- */
-
-AsyncClient::AsyncClient(tcp_pcb* pcb)
-: _connect_cb(0)
-, _connect_cb_arg(0)
-, _discard_cb(0)
-, _discard_cb_arg(0)
-, _sent_cb(0)
-, _sent_cb_arg(0)
-, _error_cb(0)
-, _error_cb_arg(0)
-, _recv_cb(0)
-, _recv_cb_arg(0)
-, _pb_cb(0)
-, _pb_cb_arg(0)
-, _timeout_cb(0)
-, _timeout_cb_arg(0)
-, _ack_pcb(true)
-, _tx_last_packet(0)
-, _rx_timeout(0)
-, _rx_last_ack(0)
-, _ack_timeout(CONFIG_ASYNC_TCP_MAX_ACK_TIME)
-, _connect_port(0)
-, prev(NULL)
-, next(NULL)
-{
- _pcb = pcb;
- _closed_slot = -1;
- if(_pcb){
- _rx_last_packet = millis();
- tcp_arg(_pcb, this);
- tcp_recv(_pcb, &_tcp_recv);
- tcp_sent(_pcb, &_tcp_sent);
- tcp_err(_pcb, &_tcp_error);
- tcp_poll(_pcb, &_tcp_poll, 1);
- if(!_allocate_closed_slot()) {
- _close();
- }
- }
-}
-
-AsyncClient::~AsyncClient(){
- if(_pcb) {
- _close();
- }
- _free_closed_slot();
-}
-
-/*
- * Operators
- * */
-
-AsyncClient& AsyncClient::operator=(const AsyncClient& other){
- if (_pcb) {
- _close();
- }
-
- _pcb = other._pcb;
- _closed_slot = other._closed_slot;
- if (_pcb) {
- _rx_last_packet = millis();
- tcp_arg(_pcb, this);
- tcp_recv(_pcb, &_tcp_recv);
- tcp_sent(_pcb, &_tcp_sent);
- tcp_err(_pcb, &_tcp_error);
- tcp_poll(_pcb, &_tcp_poll, 1);
- }
- return *this;
-}
-
-bool AsyncClient::operator==(const AsyncClient &other) {
- return _pcb == other._pcb;
-}
-
-AsyncClient & AsyncClient::operator+=(const AsyncClient &other) {
- if(next == NULL){
- next = (AsyncClient*)(&other);
- next->prev = this;
- } else {
- AsyncClient *c = next;
- while(c->next != NULL) {
- c = c->next;
- }
- c->next =(AsyncClient*)(&other);
- c->next->prev = c;
- }
- return *this;
-}
-
-/*
- * Callback Setters
- * */
-
-void AsyncClient::onConnect(AcConnectHandler cb, void* arg){
- _connect_cb = cb;
- _connect_cb_arg = arg;
-}
-
-void AsyncClient::onDisconnect(AcConnectHandler cb, void* arg){
- _discard_cb = cb;
- _discard_cb_arg = arg;
-}
-
-void AsyncClient::onAck(AcAckHandler cb, void* arg){
- _sent_cb = cb;
- _sent_cb_arg = arg;
-}
-
-void AsyncClient::onError(AcErrorHandler cb, void* arg){
- _error_cb = cb;
- _error_cb_arg = arg;
-}
-
-void AsyncClient::onData(AcDataHandler cb, void* arg){
- _recv_cb = cb;
- _recv_cb_arg = arg;
-}
-
-void AsyncClient::onPacket(AcPacketHandler cb, void* arg){
- _pb_cb = cb;
- _pb_cb_arg = arg;
-}
-
-void AsyncClient::onTimeout(AcTimeoutHandler cb, void* arg){
- _timeout_cb = cb;
- _timeout_cb_arg = arg;
-}
-
-void AsyncClient::onPoll(AcConnectHandler cb, void* arg){
- _poll_cb = cb;
- _poll_cb_arg = arg;
-}
-
-/*
- * Main Public Methods
- * */
-
-bool AsyncClient::_connect(ip_addr_t addr, uint16_t port){
- if (_pcb){
- log_d("already connected, state %d", _pcb->state);
- return false;
- }
- if(!_start_async_task()){
- log_e("failed to start task");
- return false;
- }
-
- if(!_allocate_closed_slot()) {
- log_e("failed to allocate: closed slot full");
- return false;
- }
-
- tcp_pcb* pcb = tcp_new_ip_type(addr.type);
- if (!pcb){
- log_e("pcb == NULL");
- return false;
- }
-
- tcp_arg(pcb, this);
- tcp_err(pcb, &_tcp_error);
- tcp_recv(pcb, &_tcp_recv);
- tcp_sent(pcb, &_tcp_sent);
- tcp_poll(pcb, &_tcp_poll, 1);
- esp_err_t err =_tcp_connect(pcb, _closed_slot, &addr, port,(tcp_connected_fn)&_tcp_connected);
- return err == ESP_OK;
-}
-
-bool AsyncClient::connect(const IPAddress& ip, uint16_t port){
- ip_addr_t addr;
-#if ESP_IDF_VERSION_MAJOR < 5
- addr.u_addr.ip4.addr = ip;
- addr.type = IPADDR_TYPE_V4;
-#else
- ip.to_ip_addr_t(&addr);
-#endif
-
- return _connect(addr, port);
-}
-
-#if LWIP_IPV6 && ESP_IDF_VERSION_MAJOR < 5
-bool AsyncClient::connect(const IPv6Address& ip, uint16_t port){
- ip_addr_t addr;
- addr.type = IPADDR_TYPE_V6;
- memcpy(addr.u_addr.ip6.addr, static_cast(ip), sizeof(uint32_t) * 4);
-
- return _connect(addr, port);
-}
-#endif
-
-bool AsyncClient::connect(const char* host, uint16_t port){
- ip_addr_t addr;
-
- if(!_start_async_task()){
- log_e("failed to start task");
- return false;
- }
-
- err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
- if(err == ERR_OK) {
-#if ESP_IDF_VERSION_MAJOR < 5
-#if LWIP_IPV6
- if(addr.type == IPADDR_TYPE_V6) {
- return connect(IPv6Address(addr.u_addr.ip6.addr), port);
- }
- return connect(IPAddress(addr.u_addr.ip4.addr), port);
-#else
- return connect(IPAddress(addr.addr), port);
-#endif
-#else
- return _connect(addr, port);
-#endif
- } else if(err == ERR_INPROGRESS) {
- _connect_port = port;
- return true;
- }
- log_d("error: %d", err);
- return false;
-}
-
-void AsyncClient::close(bool now){
- if(_pcb){
- _tcp_recved(_pcb, _closed_slot, _rx_ack_len);
- }
- _close();
-}
-
-int8_t AsyncClient::abort(){
- if(_pcb) {
- _tcp_abort(_pcb, _closed_slot );
- _pcb = NULL;
- }
- return ERR_ABRT;
-}
-
-size_t AsyncClient::space(){
- if((_pcb != NULL) && (_pcb->state == 4)){
- return tcp_sndbuf(_pcb);
- }
- return 0;
-}
-
-size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
- if(!_pcb || size == 0 || data == NULL) {
- return 0;
- }
- size_t room = space();
- if(!room) {
- return 0;
- }
- size_t will_send = (room < size) ? room : size;
- int8_t err = ERR_OK;
- err = _tcp_write(_pcb, _closed_slot, data, will_send, apiflags);
- if(err != ERR_OK) {
- return 0;
- }
- return will_send;
-}
-
-bool AsyncClient::send(){
- auto backup = _tx_last_packet;
- _tx_last_packet = millis();
- if (_tcp_output(_pcb, _closed_slot) == ERR_OK) {
- return true;
- }
- _tx_last_packet = backup;
- return false;
-}
-
-size_t AsyncClient::ack(size_t len){
- if(len > _rx_ack_len)
- len = _rx_ack_len;
- if(len){
- _tcp_recved(_pcb, _closed_slot, len);
- }
- _rx_ack_len -= len;
- return len;
-}
-
-void AsyncClient::ackPacket(struct pbuf * pb){
- if(!pb){
- return;
- }
- _tcp_recved(_pcb, _closed_slot, pb->len);
- pbuf_free(pb);
-}
-
-/*
- * Main Private Methods
- * */
-
-int8_t AsyncClient::_close(){
- //ets_printf("X: 0x%08x\n", (uint32_t)this);
- int8_t err = ERR_OK;
- if(_pcb) {
- tcp_arg(_pcb, NULL);
- tcp_sent(_pcb, NULL);
- tcp_recv(_pcb, NULL);
- tcp_err(_pcb, NULL);
- tcp_poll(_pcb, NULL, 0);
- _tcp_clear_events(this);
- err = _tcp_close(_pcb, _closed_slot);
- if(err != ERR_OK) {
- err = abort();
- }
- _free_closed_slot();
- _pcb = NULL;
- if(_discard_cb) {
- _discard_cb(_discard_cb_arg, this);
- }
- }
- return err;
-}
-
-bool AsyncClient::_allocate_closed_slot(){
- if (_closed_slot != -1) {
- return true;
- }
- xSemaphoreTake(_slots_lock, portMAX_DELAY);
- uint32_t closed_slot_min_index = 0;
- for (int i = 0; i < _number_of_closed_slots; ++ i) {
- if ((_closed_slot == -1 || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) {
- closed_slot_min_index = _closed_slots[i];
- _closed_slot = i;
- }
- }
- if (_closed_slot != -1) {
- _closed_slots[_closed_slot] = 0;
- }
- xSemaphoreGive(_slots_lock);
- return (_closed_slot != -1);
-}
-
-void AsyncClient::_free_closed_slot(){
- xSemaphoreTake(_slots_lock, portMAX_DELAY);
- if (_closed_slot != -1) {
- _closed_slots[_closed_slot] = _closed_index;
- _closed_slot = -1;
- ++ _closed_index;
- }
- xSemaphoreGive(_slots_lock);
-}
-
-/*
- * Private Callbacks
- * */
-
-int8_t AsyncClient::_connected(tcp_pcb* pcb, int8_t err){
- _pcb = reinterpret_cast(pcb);
- if(_pcb){
- _rx_last_packet = millis();
- }
- if(_connect_cb) {
- _connect_cb(_connect_cb_arg, this);
- }
- return ERR_OK;
-}
-
-void AsyncClient::_error(int8_t err) {
- if(_pcb){
- tcp_arg(_pcb, NULL);
- if(_pcb->state == LISTEN) {
- tcp_sent(_pcb, NULL);
- tcp_recv(_pcb, NULL);
- tcp_err(_pcb, NULL);
- tcp_poll(_pcb, NULL, 0);
- }
- _free_closed_slot();
- _pcb = NULL;
- }
- if(_error_cb) {
- _error_cb(_error_cb_arg, this, err);
- }
- if(_discard_cb) {
- _discard_cb(_discard_cb_arg, this);
- }
-}
-
-//In LwIP Thread
-int8_t AsyncClient::_lwip_fin(tcp_pcb* pcb, int8_t err) {
- if(!_pcb || pcb != _pcb){
- log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
- return ERR_OK;
- }
- tcp_arg(_pcb, NULL);
- if(_pcb->state == LISTEN) {
- tcp_sent(_pcb, NULL);
- tcp_recv(_pcb, NULL);
- tcp_err(_pcb, NULL);
- tcp_poll(_pcb, NULL, 0);
- }
- if(tcp_close(_pcb) != ERR_OK) {
- tcp_abort(_pcb);
- }
- _free_closed_slot();
- _pcb = NULL;
- return ERR_OK;
-}
-
-//In Async Thread
-int8_t AsyncClient::_fin(tcp_pcb* pcb, int8_t err) {
- _tcp_clear_events(this);
- if(_discard_cb) {
- _discard_cb(_discard_cb_arg, this);
- }
- return ERR_OK;
-}
-
-int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) {
- _rx_last_ack = _rx_last_packet = millis();
- if(_sent_cb) {
- _sent_cb(_sent_cb_arg, this, len, (_rx_last_packet - _tx_last_packet));
- }
- return ERR_OK;
-}
-
-int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) {
- if(!_pcb || pcb != _pcb){
- log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
- return ERR_OK;
- }
- size_t total = 0;
- while((pb != NULL) && (ERR_OK == err)) {
- _rx_last_packet = millis();
- //we should not ack before we assimilate the data
- _ack_pcb = true;
- pbuf *b = pb;
- pb = b->next;
- b->next = NULL;
- total += b->len;
- if(_pb_cb){
- _pb_cb(_pb_cb_arg, this, b);
- } else {
- if(_recv_cb) {
- _recv_cb(_recv_cb_arg, this, b->payload, b->len);
- }
- if(!_ack_pcb) {
- _rx_ack_len += b->len;
- }
- }
- pbuf_free(b);
- }
- return _tcp_recved(pcb, _closed_slot, total);
-}
-
-int8_t AsyncClient::_poll(tcp_pcb* pcb){
- if(!_pcb){
- // log_d("pcb is NULL");
- return ERR_OK;
- }
- if(pcb != _pcb){
- log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
- return ERR_OK;
- }
-
- uint32_t now = millis();
-
- // ACK Timeout
- if(_ack_timeout){
- const uint32_t one_day = 86400000;
- bool last_tx_is_after_last_ack = (_rx_last_ack - _tx_last_packet + one_day) < one_day;
- if(last_tx_is_after_last_ack && (now - _tx_last_packet) >= _ack_timeout) {
- log_d("ack timeout %d", pcb->state);
- if(_timeout_cb)
- _timeout_cb(_timeout_cb_arg, this, (now - _tx_last_packet));
- return ERR_OK;
- }
- }
- // RX Timeout
- if(_rx_timeout && (now - _rx_last_packet) >= (_rx_timeout * 1000)) {
- log_d("rx timeout %d", pcb->state);
- _close();
- return ERR_OK;
- }
- // Everything is fine
- if(_poll_cb) {
- _poll_cb(_poll_cb_arg, this);
- }
- return ERR_OK;
-}
-
-void AsyncClient::_dns_found(struct ip_addr *ipaddr){
-#if ESP_IDF_VERSION_MAJOR < 5
- if(ipaddr && IP_IS_V4(ipaddr)){
- connect(IPAddress(ip_addr_get_ip4_u32(ipaddr)), _connect_port);
-#if LWIP_IPV6
- } else if(ipaddr && ipaddr->u_addr.ip6.addr){
- connect(IPv6Address(ipaddr->u_addr.ip6.addr), _connect_port);
-#endif
-#else
- if(ipaddr) {
- IPAddress ip;
- ip.from_ip_addr_t(ipaddr);
- connect(ip, _connect_port);
-#endif
- } else {
- if(_error_cb) {
- _error_cb(_error_cb_arg, this, -55);
- }
- if(_discard_cb) {
- _discard_cb(_discard_cb_arg, this);
- }
- }
-}
-
-/*
- * Public Helper Methods
- * */
-
-void AsyncClient::stop() {
- close(false);
-}
-
-bool AsyncClient::free(){
- if(!_pcb) {
- return true;
- }
- if(_pcb->state == 0 || _pcb->state > 4) {
- return true;
- }
- return false;
-}
-
-size_t AsyncClient::write(const char* data) {
- if(data == NULL) {
- return 0;
- }
- return write(data, strlen(data));
-}
-
-size_t AsyncClient::write(const char* data, size_t size, uint8_t apiflags) {
- size_t will_send = add(data, size, apiflags);
- if(!will_send || !send()) {
- return 0;
- }
- return will_send;
-}
-
-void AsyncClient::setRxTimeout(uint32_t timeout){
- _rx_timeout = timeout;
-}
-
-uint32_t AsyncClient::getRxTimeout(){
- return _rx_timeout;
-}
-
-uint32_t AsyncClient::getAckTimeout(){
- return _ack_timeout;
-}
-
-void AsyncClient::setAckTimeout(uint32_t timeout){
- _ack_timeout = timeout;
-}
-
-void AsyncClient::setNoDelay(bool nodelay){
- if(!_pcb) {
- return;
- }
- if(nodelay) {
- tcp_nagle_disable(_pcb);
- } else {
- tcp_nagle_enable(_pcb);
- }
-}
-
-bool AsyncClient::getNoDelay(){
- if(!_pcb) {
- return false;
- }
- return tcp_nagle_disabled(_pcb);
-}
-
-void AsyncClient::setKeepAlive(uint32_t ms, uint8_t cnt){
- if(ms!=0) {
- _pcb->so_options |= SOF_KEEPALIVE; //Turn on TCP Keepalive for the given pcb
- // Set the time between keepalive messages in milli-seconds
- _pcb->keep_idle = ms;
- _pcb->keep_intvl = ms;
- _pcb->keep_cnt = cnt; //The number of unanswered probes required to force closure of the socket
- } else {
- _pcb->so_options &= ~SOF_KEEPALIVE; //Turn off TCP Keepalive for the given pcb
- }
-}
-
-uint16_t AsyncClient::getMss(){
- if(!_pcb) {
- return 0;
- }
- return tcp_mss(_pcb);
-}
-
-uint32_t AsyncClient::getRemoteAddress() {
- if(!_pcb) {
- return 0;
- }
-#if LWIP_IPV4 && LWIP_IPV6
- return _pcb->remote_ip.u_addr.ip4.addr;
-#else
- return _pcb->remote_ip.addr;
-#endif
-}
-
-#if LWIP_IPV6
-ip6_addr_t AsyncClient::getRemoteAddress6() {
- if(!_pcb) {
- ip6_addr_t nulladdr;
- ip6_addr_set_zero(&nulladdr);
- return nulladdr;
- }
- return _pcb->remote_ip.u_addr.ip6;
-}
-
-ip6_addr_t AsyncClient::getLocalAddress6() {
- if(!_pcb) {
- ip6_addr_t nulladdr;
- ip6_addr_set_zero(&nulladdr);
- return nulladdr;
- }
- return _pcb->local_ip.u_addr.ip6;
-}
-#if ESP_IDF_VERSION_MAJOR < 5
-IPv6Address AsyncClient::remoteIP6() {
- return IPv6Address(getRemoteAddress6().addr);
-}
-
-IPv6Address AsyncClient::localIP6() {
- return IPv6Address(getLocalAddress6().addr);
-}
-#else
-IPAddress AsyncClient::remoteIP6() {
- if (!_pcb) {
- return IPAddress(IPType::IPv6);
- }
- IPAddress ip;
- ip.from_ip_addr_t(&(_pcb->remote_ip));
- return ip;
-}
-
-IPAddress AsyncClient::localIP6() {
- if (!_pcb) {
- return IPAddress(IPType::IPv6);
- }
- IPAddress ip;
- ip.from_ip_addr_t(&(_pcb->local_ip));
- return ip;
-}
-#endif
-#endif
-
-uint16_t AsyncClient::getRemotePort() {
- if(!_pcb) {
- return 0;
- }
- return _pcb->remote_port;
-}
-
-uint32_t AsyncClient::getLocalAddress() {
- if(!_pcb) {
- return 0;
- }
-#if LWIP_IPV4 && LWIP_IPV6
- return _pcb->local_ip.u_addr.ip4.addr;
-#else
- return _pcb->local_ip.addr;
-#endif
-}
-
-uint16_t AsyncClient::getLocalPort() {
- if(!_pcb) {
- return 0;
- }
- return _pcb->local_port;
-}
-
-IPAddress AsyncClient::remoteIP() {
-#if ESP_IDF_VERSION_MAJOR < 5
- return IPAddress(getRemoteAddress());
-#else
- if (!_pcb) {
- return IPAddress();
- }
- IPAddress ip;
- ip.from_ip_addr_t(&(_pcb->remote_ip));
- return ip;
-#endif
-}
-
-uint16_t AsyncClient::remotePort() {
- return getRemotePort();
-}
-
-IPAddress AsyncClient::localIP() {
-#if ESP_IDF_VERSION_MAJOR < 5
- return IPAddress(getLocalAddress());
-#else
- if (!_pcb) {
- return IPAddress();
- }
- IPAddress ip;
- ip.from_ip_addr_t(&(_pcb->local_ip));
- return ip;
-#endif
-}
-
-
-uint16_t AsyncClient::localPort() {
- return getLocalPort();
-}
-
-uint8_t AsyncClient::state() {
- if(!_pcb) {
- return 0;
- }
- return _pcb->state;
-}
-
-bool AsyncClient::connected(){
- if (!_pcb) {
- return false;
- }
- return _pcb->state == 4;
-}
-
-bool AsyncClient::connecting(){
- if (!_pcb) {
- return false;
- }
- return _pcb->state > 0 && _pcb->state < 4;
-}
-
-bool AsyncClient::disconnecting(){
- if (!_pcb) {
- return false;
- }
- return _pcb->state > 4 && _pcb->state < 10;
-}
-
-bool AsyncClient::disconnected(){
- if (!_pcb) {
- return true;
- }
- return _pcb->state == 0 || _pcb->state == 10;
-}
-
-bool AsyncClient::freeable(){
- if (!_pcb) {
- return true;
- }
- return _pcb->state == 0 || _pcb->state > 4;
-}
-
-bool AsyncClient::canSend(){
- return space() > 0;
-}
-
-const char * AsyncClient::errorToString(int8_t error){
- switch(error){
- case ERR_OK: return "OK";
- case ERR_MEM: return "Out of memory error";
- case ERR_BUF: return "Buffer error";
- case ERR_TIMEOUT: return "Timeout";
- case ERR_RTE: return "Routing problem";
- case ERR_INPROGRESS: return "Operation in progress";
- case ERR_VAL: return "Illegal value";
- case ERR_WOULDBLOCK: return "Operation would block";
- case ERR_USE: return "Address in use";
- case ERR_ALREADY: return "Already connected";
- case ERR_CONN: return "Not connected";
- case ERR_IF: return "Low-level netif error";
- case ERR_ABRT: return "Connection aborted";
- case ERR_RST: return "Connection reset";
- case ERR_CLSD: return "Connection closed";
- case ERR_ARG: return "Illegal argument";
- case -55: return "DNS failed";
- default: return "UNKNOWN";
- }
-}
-
-const char * AsyncClient::stateToString(){
- switch(state()){
- case 0: return "Closed";
- case 1: return "Listen";
- case 2: return "SYN Sent";
- case 3: return "SYN Received";
- case 4: return "Established";
- case 5: return "FIN Wait 1";
- case 6: return "FIN Wait 2";
- case 7: return "Close Wait";
- case 8: return "Closing";
- case 9: return "Last ACK";
- case 10: return "Time Wait";
- default: return "UNKNOWN";
- }
-}
-
-/*
- * Static Callbacks (LwIP C2C++ interconnect)
- * */
-
-void AsyncClient::_s_dns_found(const char * name, struct ip_addr * ipaddr, void * arg){
- reinterpret_cast(arg)->_dns_found(ipaddr);
-}
-
-int8_t AsyncClient::_s_poll(void * arg, struct tcp_pcb * pcb) {
- return reinterpret_cast(arg)->_poll(pcb);
-}
-
-int8_t AsyncClient::_s_recv(void * arg, struct tcp_pcb * pcb, struct pbuf *pb, int8_t err) {
- return reinterpret_cast(arg)->_recv(pcb, pb, err);
-}
-
-int8_t AsyncClient::_s_fin(void * arg, struct tcp_pcb * pcb, int8_t err) {
- return reinterpret_cast(arg)->_fin(pcb, err);
-}
-
-int8_t AsyncClient::_s_lwip_fin(void * arg, struct tcp_pcb * pcb, int8_t err) {
- return reinterpret_cast(arg)->_lwip_fin(pcb, err);
-}
-
-int8_t AsyncClient::_s_sent(void * arg, struct tcp_pcb * pcb, uint16_t len) {
- return reinterpret_cast(arg)->_sent(pcb, len);
-}
-
-void AsyncClient::_s_error(void * arg, int8_t err) {
- reinterpret_cast(arg)->_error(err);
-}
-
-int8_t AsyncClient::_s_connected(void * arg, struct tcp_pcb * pcb, int8_t err){
- return reinterpret_cast(arg)->_connected(pcb, err);
-}
-
-/*
- Async TCP Server
- */
-
-AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
-: _port(port)
-#if ESP_IDF_VERSION_MAJOR < 5
-, _bind4(true)
-, _bind6(false)
-#else
-, _bind4(addr.type() != IPType::IPv6)
-, _bind6(addr.type() == IPType::IPv6)
-#endif
-, _addr(addr)
-, _noDelay(false)
-, _pcb(0)
-, _connect_cb(0)
-, _connect_cb_arg(0)
-{}
-
-#if ESP_IDF_VERSION_MAJOR < 5
-AsyncServer::AsyncServer(IPv6Address addr, uint16_t port)
-: _port(port)
-, _bind4(false)
-, _bind6(true)
-, _addr6(addr)
-, _noDelay(false)
-, _pcb(0)
-, _connect_cb(0)
-, _connect_cb_arg(0)
-{}
-#endif
-
-AsyncServer::AsyncServer(uint16_t port)
-: _port(port)
-, _bind4(true)
-, _bind6(false)
-, _addr((uint32_t) IPADDR_ANY)
-#if ESP_IDF_VERSION_MAJOR < 5
-, _addr6()
-#endif
-, _noDelay(false)
-, _pcb(0)
-, _connect_cb(0)
-, _connect_cb_arg(0)
-{}
-
-AsyncServer::~AsyncServer(){
- end();
-}
-
-void AsyncServer::onClient(AcConnectHandler cb, void* arg){
- _connect_cb = cb;
- _connect_cb_arg = arg;
-}
-
-void AsyncServer::begin(){
- if(_pcb) {
- return;
- }
-
- if(!_start_async_task()){
- log_e("failed to start task");
- return;
- }
- int8_t err;
- _pcb = tcp_new_ip_type(_bind4 && _bind6 ? IPADDR_TYPE_ANY : (_bind6 ? IPADDR_TYPE_V6 : IPADDR_TYPE_V4));
- if (!_pcb){
- log_e("_pcb == NULL");
- return;
- }
-
- ip_addr_t local_addr;
-#if ESP_IDF_VERSION_MAJOR < 5
- if (_bind6) { // _bind6 && _bind4 both at the same time is not supported on Arduino 2 in this lib API
- local_addr.type = IPADDR_TYPE_V6;
- memcpy(local_addr.u_addr.ip6.addr, static_cast(_addr6), sizeof(uint32_t) * 4);
- } else {
- local_addr.type = IPADDR_TYPE_V4;
- local_addr.u_addr.ip4.addr = _addr;
- }
-#else
- _addr.to_ip_addr_t(&local_addr);
-#endif
- err = _tcp_bind(_pcb, &local_addr, _port);
-
- if (err != ERR_OK) {
- _tcp_close(_pcb, -1);
- log_e("bind error: %d", err);
- return;
- }
-
- static uint8_t backlog = 5;
- _pcb = _tcp_listen_with_backlog(_pcb, backlog);
- if (!_pcb) {
- log_e("listen_pcb == NULL");
- return;
- }
- tcp_arg(_pcb, (void*) this);
- tcp_accept(_pcb, &_s_accept);
-}
-
-void AsyncServer::end(){
- if(_pcb){
- tcp_arg(_pcb, NULL);
- tcp_accept(_pcb, NULL);
- if(tcp_close(_pcb) != ERR_OK){
- _tcp_abort(_pcb, -1);
- }
- _pcb = NULL;
- }
-}
-
-//runs on LwIP thread
-int8_t AsyncServer::_accept(tcp_pcb* pcb, int8_t err){
- //ets_printf("+A: 0x%08x\n", pcb);
- if(_connect_cb){
- AsyncClient *c = new AsyncClient(pcb);
- if(c){
- c->setNoDelay(_noDelay);
- return _tcp_accept(this, c);
- }
- }
- if(tcp_close(pcb) != ERR_OK){
- tcp_abort(pcb);
- }
- log_d("FAIL");
- return ERR_OK;
-}
-
-int8_t AsyncServer::_accepted(AsyncClient* client){
- if(_connect_cb){
- _connect_cb(_connect_cb_arg, client);
- }
- return ERR_OK;
-}
-
-void AsyncServer::setNoDelay(bool nodelay){
- _noDelay = nodelay;
-}
-
-bool AsyncServer::getNoDelay(){
- return _noDelay;
-}
-
-uint8_t AsyncServer::status(){
- if (!_pcb) {
- return 0;
- }
- return _pcb->state;
-}
-
-int8_t AsyncServer::_s_accept(void * arg, tcp_pcb * pcb, int8_t err){
- return reinterpret_cast(arg)->_accept(pcb, err);
-}
-
-int8_t AsyncServer::_s_accepted(void *arg, AsyncClient* client){
- return reinterpret_cast(arg)->_accepted(client);
-}
diff --git a/lib/AsyncTCP/src/AsyncTCP.h b/lib/AsyncTCP/src/AsyncTCP.h
deleted file mode 100644
index feac4d2..0000000
--- a/lib/AsyncTCP/src/AsyncTCP.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- Asynchronous TCP library for Espressif MCUs
-
- Copyright (c) 2016 Hristo Gochkov. All rights reserved.
- This file is part of the esp8266 core for Arduino environment.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef ASYNCTCP_H_
-#define ASYNCTCP_H_
-
-#define ASYNCTCP_VERSION "3.2.4"
-#define ASYNCTCP_VERSION_MAJOR 3
-#define ASYNCTCP_VERSION_MINOR 2
-#define ASYNCTCP_VERSION_REVISION 4
-#define ASYNCTCP_FORK_mathieucarbou
-
-#include "IPAddress.h"
-#if ESP_IDF_VERSION_MAJOR < 5
-#include "IPv6Address.h"
-#endif
-#include
-#include "lwip/ip_addr.h"
-#include "lwip/ip6_addr.h"
-
-#ifndef LIBRETINY
-#include "sdkconfig.h"
-extern "C" {
- #include "freertos/semphr.h"
- #include "lwip/pbuf.h"
-}
-#else
-extern "C" {
- #include
- #include
-}
-#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 //any available core
-#define CONFIG_ASYNC_TCP_USE_WDT 0
-#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
-#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_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 AcConnectHandler;
-typedef std::function AcAckHandler;
-typedef std::function AcErrorHandler;
-typedef std::function AcDataHandler;
-typedef std::function AcPacketHandler;
-typedef std::function AcTimeoutHandler;
-
-struct tcp_pcb;
-struct ip_addr;
-
-class AsyncClient {
- public:
- AsyncClient(tcp_pcb* pcb = 0);
- ~AsyncClient();
-
- AsyncClient & operator=(const AsyncClient &other);
- AsyncClient & operator+=(const AsyncClient &other);
-
- bool operator==(const AsyncClient &other);
-
- bool operator!=(const AsyncClient &other) {
- return !(*this == other);
- }
- 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);
- void close(bool now = false);
- void stop();
- 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
-
- //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
-
- uint8_t state();
- bool connecting();
- bool connected();
- bool disconnecting();
- bool disconnected();
- bool freeable();//disconnected or disconnecting
-
- uint16_t getMss();
-
- uint32_t getRxTimeout();
- void setRxTimeout(uint32_t timeout);//no RX data timeout for the connection in seconds
-
- uint32_t getAckTimeout();
- void setAckTimeout(uint32_t timeout);//no ACK timeout for the last sent packet in milliseconds
-
- 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
- IPAddress remoteIP();
- uint16_t remotePort();
- IPAddress localIP();
- 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
-
- 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
-
- 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, 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; }
-
- protected:
- bool _connect(ip_addr_t addr, uint16_t port);
-
- tcp_pcb* _pcb;
- int8_t _closed_slot;
-
- AcConnectHandler _connect_cb;
- void* _connect_cb_arg;
- AcConnectHandler _discard_cb;
- void* _discard_cb_arg;
- AcAckHandler _sent_cb;
- void* _sent_cb_arg;
- AcErrorHandler _error_cb;
- void* _error_cb_arg;
- AcDataHandler _recv_cb;
- void* _recv_cb_arg;
- AcPacketHandler _pb_cb;
- void* _pb_cb_arg;
- AcTimeoutHandler _timeout_cb;
- void* _timeout_cb_arg;
- AcConnectHandler _poll_cb;
- void* _poll_cb_arg;
-
- bool _ack_pcb;
- uint32_t _tx_last_packet;
- uint32_t _rx_ack_len;
- uint32_t _rx_last_packet;
- uint32_t _rx_timeout;
- uint32_t _rx_last_ack;
- uint32_t _ack_timeout;
- uint16_t _connect_port;
-
- int8_t _close();
- void _free_closed_slot();
- 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);
-
- public:
- AsyncClient* prev;
- AsyncClient* next;
-};
-
-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);
- void begin();
- void end();
- void setNoDelay(bool nodelay);
- 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);
-
- 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;
- void* _connect_cb_arg;
-
- int8_t _accept(tcp_pcb* newpcb, int8_t err);
- int8_t _accepted(AsyncClient* client);
-};
-
-
-#endif /* ASYNCTCP_H_ */
diff --git a/lib/MqttLogger/src/MqttLogger.cpp b/lib/MqttLogger/src/MqttLogger.cpp
index d8d08f7..ea59c0c 100644
--- a/lib/MqttLogger/src/MqttLogger.cpp
+++ b/lib/MqttLogger/src/MqttLogger.cpp
@@ -7,7 +7,7 @@ MqttLogger::MqttLogger(MqttLoggerMode mode)
this->setBufferSize(MQTT_MAX_PACKET_SIZE);
}
-MqttLogger::MqttLogger(MqttClient& client, const char* topic, MqttLoggerMode mode)
+MqttLogger::MqttLogger(esp_mqtt_client_handle_t client, const char* topic, MqttLoggerMode mode)
{
this->setClient(client);
this->setTopic(topic);
@@ -19,9 +19,9 @@ MqttLogger::~MqttLogger()
{
}
-void MqttLogger::setClient(MqttClient& client)
+void MqttLogger::setClient(esp_mqtt_client_handle_t client)
{
- this->client = &client;
+ this->client = client;
}
void MqttLogger::setTopic(const char* topic)
@@ -69,21 +69,22 @@ boolean MqttLogger::setBufferSize(uint16_t size)
}
// send & reset current buffer
-void MqttLogger::sendBuffer()
+void MqttLogger::sendBuffer()
{
if (this->bufferCnt > 0)
{
bool doSerial = this->mode==MqttLoggerMode::SerialOnly || this->mode==MqttLoggerMode::MqttAndSerial || this->mode==MqttLoggerMode::MqttAndSerialAndWeb || this->mode==MqttLoggerMode::SerialAndWeb;
bool doWebSerial = this->mode==MqttLoggerMode::MqttAndSerialAndWeb || this->mode==MqttLoggerMode::SerialAndWeb;
-
- if (this->mode!=MqttLoggerMode::SerialOnly && this->mode!=MqttLoggerMode::SerialAndWeb && this->client != NULL && this->client->connected())
+
+ if (this->mode!=MqttLoggerMode::SerialOnly && this->mode!=MqttLoggerMode::SerialAndWeb && this->client != NULL)
{
- this->client->publish(topic, 0, true, this->buffer, this->bufferCnt);
- } else if (this->mode == MqttLoggerMode::MqttAndSerialFallback)
+ esp_mqtt_client_publish(this->client, topic, (const char*)this->buffer, this->bufferCnt, 0, 1);
+ }
+ else if (this->mode == MqttLoggerMode::MqttAndSerialFallback)
{
doSerial = true;
}
- if (doSerial)
+ if (doSerial)
{
Serial.write(this->buffer, this->bufferCnt);
Serial.println();
diff --git a/lib/MqttLogger/src/MqttLogger.h b/lib/MqttLogger/src/MqttLogger.h
index d82e62a..cb35fcc 100644
--- a/lib/MqttLogger/src/MqttLogger.h
+++ b/lib/MqttLogger/src/MqttLogger.h
@@ -11,7 +11,7 @@
#include
#include
-#include
+#include
//#include "MycilaWebSerial.h"
#define MQTT_MAX_PACKET_SIZE 1024
@@ -32,16 +32,16 @@ private:
uint8_t* buffer;
uint8_t* bufferEnd;
uint16_t bufferCnt = 0, bufferSize = 0;
- MqttClient* client;
+ esp_mqtt_client_handle_t client;
MqttLoggerMode mode;
void sendBuffer();
public:
MqttLogger(MqttLoggerMode mode=MqttLoggerMode::MqttAndSerialFallback);
- MqttLogger(MqttClient& client, const char* topic, MqttLoggerMode mode=MqttLoggerMode::MqttAndSerialFallback);
+ MqttLogger(esp_mqtt_client_handle_t client, const char* topic, MqttLoggerMode mode=MqttLoggerMode::MqttAndSerialFallback);
~MqttLogger();
- void setClient(MqttClient& client);
+ void setClient(esp_mqtt_client_handle_t client);
void setTopic(const char* topic);
void setMode(MqttLoggerMode mode);
void setRetained(boolean retained);
diff --git a/lib/espMqttClient/CMakeLists.txt b/lib/espMqttClient/CMakeLists.txt
deleted file mode 100644
index 3702227..0000000
--- a/lib/espMqttClient/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-set(COMPONENT_SRCDIRS
- "src" "src/Packets" "src/Transport"
-)
-
-set(COMPONENT_ADD_INCLUDEDIRS
- "src" "src/Packets" "src/Transport"
-)
-
-set(COMPONENT_REQUIRES
- "arduino-esp32"
- "AsyncTCP"
-)
-
-register_component()
-
-target_compile_definitions(${COMPONENT_TARGET} PUBLIC -DESP32)
-target_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti)
diff --git a/lib/espMqttClient/LICENSE b/lib/espMqttClient/LICENSE
deleted file mode 100644
index 1cc5546..0000000
--- a/lib/espMqttClient/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2022 Bert Melis
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/lib/espMqttClient/README.md b/lib/espMqttClient/README.md
deleted file mode 100644
index 7b0bfdd..0000000
--- a/lib/espMqttClient/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# espMqttClient
-
-MQTT client library for the Espressif devices ESP8266 and ESP32 on the Arduino framework.
-Aims to be a non-blocking, fully compliant MQTT 3.1.1 client.
-
-
-
-
-[](https://registry.platformio.org/libraries/bertmelis/espMqttClient)
-
-# Features
-
-- MQTT 3.1.1 compliant library
-- Sending and receiving at all QoS levels
-- TCP and TCP/TLS using standard WiFiClient and WiFiClientSecure connections
-- Virtually unlimited incoming and outgoing payload sizes
-- Readable and understandable code
-- Fully async clients available via [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) or [ESPAsnycTCP](https://github.com/me-no-dev/ESPAsyncTCP) (no TLS supported).
-- Supported platforms:
- - Espressif ESP8266 and ESP32 using the Arduino framework
- - Espressif ESP32 using the ESP IDF, see [esp idf component](https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html)
-- Basic Linux compatibility*. This includes WSL on Windows
-
- > Linux compatibility is mainly for automatic testing. It relies on a quick and dirty Arduino-style `Client` with a POSIX TCP client underneath and Arduino-style `ClientPosixIPAddress` class. These are lacking many features needed for proper Linux support.
-
-## Dependencies
-
-This libraries requires [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) and [ESPAsnycTCP](https://github.com/me-no-dev/ESPAsyncTCP). These libraries are not actively maintained and have some bugs. There are alternatives available on Github but make sure these alternatives fit in your project.
-
-Because of this, I have removed the explicit dependency. You will have to manually add the libraries so you can choose the version which best suites your code.
-
-# Documentation
-
-See [documentation](https://www.emelis.net/espMqttClient/) and the [examples](examples/).
-
-## Limitations
-
-### MQTT 3.1.1 Compliancy
-
-Outgoing messages and session data are not stored in non-volatile memory. Any events like loss of power or sudden resets result in loss of data. Despite this limitation, one could still consider this library as fully complaint based on the non normative remark in point 4.1.1 of the specification.
-
-### Non-blocking
-
-This library aims to be fully non-blocking. It is however limited by the underlying `WiFiClient` library which is part of the Arduino framework and has a blocking `connect` method. This is not an issue on ESP32 because the call is offloaded to a separate task. On ESP8266 however, connecting will block until succesful or until the connection timeouts.
-
-If you need a fully asynchronous MQTT client, you can use `espMqttClientAsync` which uses AsyncTCP/ESPAsyncTCP under the hood. These underlying libraries do not support TLS (anymore). I will not provide support TLS for the async client.
-
-# Bugs and feature requests
-
-Please use Github's facilities to get in touch.
-
-# About this library
-
-This client wouldn't exist without [Async-mqtt-client](https://github.com/marvinroger/async-mqtt-client). It has been my go-to MQTT client for many years. It was fast, reliable and had features that were non-existing in alternative libraries. However, the underlying async TCP libraries are lacking updates, especially updates related to secure connections. Adapting this library to use up-to-date TCP clients would not be trivial. I eventually decided to write my own MQTT library, from scratch.
-
-The result is an almost non-blocking library with no external dependencies. The library is almost a drop-in replacement for the async-mqtt-client except a few parameter type changes (eg. `uint8_t*` instead of `char*` for payloads).
-
-# License
-
-This library is released under the MIT Licence. A copy is included in the repo.
-Parts of this library, most notably the API, are based on [Async MQTT client for ESP8266 and ESP32](https://github.com/marvinroger/async-mqtt-client).
diff --git a/lib/espMqttClient/component.mk b/lib/espMqttClient/component.mk
deleted file mode 100644
index bb5bb16..0000000
--- a/lib/espMqttClient/component.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-COMPONENT_ADD_INCLUDEDIRS := src
-COMPONENT_SRCDIRS := src
-CXXFLAGS += -fno-rtti
diff --git a/lib/espMqttClient/docs/_config.yml b/lib/espMqttClient/docs/_config.yml
deleted file mode 100644
index 6975b20..0000000
--- a/lib/espMqttClient/docs/_config.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-theme: jekyll-theme-cayman
-title: espMqttClient
-description: |
- MQTT client library for the Espressif devices ESP8266 and ESP32 on the Arduino framework.
- Aims to be a non-blocking fully compliant MQTT 3.1.1 client.
-show_downloads: false
diff --git a/lib/espMqttClient/docs/index.md b/lib/espMqttClient/docs/index.md
deleted file mode 100644
index 4385ee9..0000000
--- a/lib/espMqttClient/docs/index.md
+++ /dev/null
@@ -1,587 +0,0 @@
-
-
-
-[](https://registry.platformio.org/libraries/bertmelis/espMqttClient)
-
-# Features
-
-- MQTT 3.1.1 compliant library
-- Sending and receiving at all QoS levels
-- TCP and TCP/TLS using standard WiFiClient and WiFiClientSecure connections
-- Virtually unlimited incoming and outgoing payload sizes
-- Readable and understandable code
-- Fully async clients available via [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) or [ESPAsnycTCP](https://github.com/me-no-dev/ESPAsyncTCP) (no TLS supported).
-- Supported platforms:
- - Espressif ESP8266 and ESP32 using the Arduino framework
- - Espressif ESP32 using the ESP IDF, see [esp idf component](https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html)
-- Basic Linux compatibility*. This includes WSL on Windows
-
- > Linux compatibility is mainly for automatic testing. It relies on a quick and dirty Arduino-style `Client` with a POSIX TCP client underneath and Arduino-style `IPAddress` class. These are lacking many features needed for proper Linux support.
-
-## Dependencies
-
-This libraries requires [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) and [ESPAsnycTCP](https://github.com/me-no-dev/ESPAsyncTCP). These libraries are not actively maintained and have some bugs. There are alternatives available on Github but make sure these alternatives fit in your project.
-
-Because of this, I have removed the explicit dependency. You will have to manually add the libraries so you can choose the version which best suites your code.
-
-# Contents
-
-1. [Runtime behaviour](#runtime-behaviour)
-2. [API Reference](#api-reference)
-3. [Compile-time configuration](#compile-time-configuration)
-4. [Code samples](#code-samples)
-
-# Runtime behaviour
-
-A normal operation cycle of an MQTT client goes like this:
-
-1. setup the client
-2. connect to the broker
-3. subscribe/publish/receive
-4. disconnect/reconnect when disconnected
-5. Cleanly disconnect
-
-### Setup
-
-Setting up the client means to tell which host and port to connect to, possible credentials to use and so on. espMqttClient has a set of methods to configure the client. Setup is generally done in the `setup()` function of the Arduino framework.
-One important thing to remember is that there are a number of settings that are not stored inside the library: `username`, `password`, `willTopic`, `willPayload`, `clientId` and `host`. Make sure these variables stay available during the lifetime of the `espMqttClient`.
-
-For TLS secured connections, the relevant methods from `WiFiClientSecure` have been made available to setup the TLS mechanisms.
-
-### Connecting
-
-After setting up the client, you are ready to connect. A simple call to `connect()` does the job. If you set an `OnConnectCallback`, you will be notified when the connection has been made. On failure, `OnDisconnectCallback` will be called. Although good code structure can avoid this, you can call `connect()` multiple times.
-
-### Subscribing, publishing and receiving
-
-Once connected, you can subscribe, publish and receive. The methods to do this return the packetId of the generated packet or `1` for packets without packetId. In case of an error, the method returns `0`. When the client is not connected, you cannot subscribe, unsubscribe or publish (configurable, see [EMC_ALLOW_NOT_CONNECTED_PUBLISH](#EMC_ALLOW_NOT_CONNECTED_PUBLISH)).
-
-Receiving packets is done via the `onMessage`-callback. This callback gives you the topic, properties (qos, dup, retain, packetId) and payload. For the payload, you get a pointer to the data, the index, length and total length. On long payloads it is normal that you get multiple callbacks for the same packet. This way, you can receive payloads longer than what could fit in the microcontroller's memory.
-
- > Beware that MQTT payloads are binary. MQTT payloads are **not** c-strings unless explicitely constructed like that. You therefore can **not** print the payload to your Serial monitor without supporting code.
-
-### Disconnecting
-
-You can disconnect from the broker by calling `disconnect()`. If you do not force-disconnect, the client will first send the remaining messages that are in the queue and disconnect afterwards. During this period however, no new incoming PUBLISH messages will be processed.
-
-# API Reference
-
-```cpp
-espMqttClient()
-espMqttClientSecure()
-espMqttClientAsync()
-```
-
-Instantiate a new espMqttClient or espMqttSecure object.
-On ESP32, three optional parameters are available: `espMqttClient(bool internalTask = true, uint8_t priority = 1, uint8_t core = 1)`. By default, espMqttclient creates its own task to manage TCP. By setting `internalTask` to false, no task will be created and you will be responsible yourself to call `espMqttClient.loop()`. `priority` changes the priority of the MQTT client task and the core on which it runs (higher priority = more cpu-time).
-
-For the asynchronous version, use `espMqttClientAsync`.
-
-### Configuration
-
-```cpp
-espMqttClient& setKeepAlive(uint16_t keepAlive)
-```
-
-Set the keep alive. Defaults to 15 seconds.
-
-* **`keepAlive`**: Keep alive in seconds
-
-```cpp
-espMqttClient& setClientId(const char* clientId)
-```
-
-Set the client ID. Defaults to `esp8266123456` or `esp32123456` where `123456` is the chip ID.
-The library only stores a pointer to the client ID. Make sure the variable pointed to stays available throughout the lifetime of espMqttClient.
-
-- **`clientId`**: Client ID, expects a null-terminated char array (c-string)
-
-```cpp
-espMqttClient& setCleanSession(bool cleanSession)
-```
-
-Set the CleanSession flag. Defaults to `true`.
-
-- **`cleanSession`**: clean session wanted or not
-
-```cpp
-espMqttClient& setCredentials(const char* username, const char* password)
-```
-
-Set the username/password. Defaults to non-auth.
-The library only stores a pointer to the username and password. Make sure the variable to pointed stays available throughout the lifetime of espMqttClient.
-
-- **`username`**: Username, expects a null-terminated char array (c-string)
-- **`password`**: Password, expects a null-terminated char array (c-string)
-
-```cpp
-espMqttClient& setWill(const char* topic, uint8_t qos, bool retain, const uint8_t* payload, size_t length)
-```
-
-Set the Last Will. Defaults to none.
-The library only stores a pointer to the topic and payload. Make sure the variable pointed to stays available throughout the lifetime of espMqttClient.
-
-- **`topic`**: Topic of the LWT, expects a null-terminated char array (c-string)
-- **`qos`**: QoS of the LWT
-- **`retain`**: Retain flag of the LWT
-- **`payload`**: Payload of the LWT.
-- **`length`**: Payload length
-
-```cpp
-espMqttClient& setWill(const char* topic, uint8_t qos, bool retain, const char* payload)
-```
-
-Set the Last Will. Defaults to none.
-The library only stores a pointer to the topic and payload. Make sure the variable pointed to stays available throughout the lifetime of espMqttClient.
-
-- **`topic`**: Topic of the LWT, expects a null-terminated char array (c-string)
-- **`qos`**: QoS of the LWT
-- **`retain`**: Retain flag of the LWT
-- **`payload`**: Payload of the LWT, expects a null-terminated char array (c-string). Its lenght will be calculated using `strlen(payload)`
-
-```cpp
-espMqttClient& setServer(IPAddress ip, uint16_t port)
-```
-
-Set the server. Mind that when using `espMqttClientSecure` with a certificate, the hostname will be chacked against the certificate. Often IP-addresses are not valid and the connection will fail.
-
-- **`ip`**: IP of the server
-- **`port`**: Port of the server
-
-```cpp
-espMqttClient& setServer(const char* host, uint16_t port)
-```
-
-Set the server.
-
-- **`host`**: Host of the server, expects a null-terminated char array (c-string)
-- **`port`**: Port of the server
-
-```cpp
-espMqttClient& setTimeout(uint16_t timeout)
-```
-
-Set the timeout for packets that need acknowledgement. Defaults to 10 seconds.
-When no acknowledgement has been received from the broker after sending a packet, the client will retransmit **all** the packets in the queue.
-
-* **`timeout`**: Timeout in seconds
-
-#### Options for TLS connections
-
-All common options from WiFiClientSecure to setup an encrypted connection are made available. These include:
-
-- `espMqttClientSecure& setInsecure()`
-- `espMqttClientSecure& setCACert(const char* rootCA)` (ESP32 only)
-- `espMqttClientSecure& setCertificate(const char* clientCa)` (ESP32 only)
-- `espMqttClientSecure& setPrivateKey(const char* privateKey)` (ESP32 only)
-- `espMqttClientSecure& setPreSharedKey(const char* pskIdent, const char* psKey)` (ESP32 only)
-- `espMqttClientSecure& setFingerprint(const uint8_t fingerprint[20])` (ESP8266 only)
-- `espMqttClientSecure& setTrustAnchors(const X509List *ta)` (ESP8266 only)
-- `espMqttClientSecure& setClientRSACert(const X509List *cert, const PrivateKey *sk)` (ESP8266 only)
-- `espMqttClientSecure& setClientECCert(const X509List *cert, const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type)` (ESP8266 only)
-- `espMqttClientSecure& setCertStore(CertStoreBase *certStore)` (ESP8266 only)
-
-For documenation, please visit [ESP8266's documentation](https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#bearssl-client-secure-and-server-secure) or [ESP32's documentation](https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFiClientSecure).
-
-### Events handlers
-
-```cpp
-espMqttClient& onConnect(espMqttClientTypes::OnConnectCallback callback)
-```
-
-Add a connect event handler. Function signature: `void(bool sessionPresent)`
-
-- **`callback`**: Function to call
-
-```cpp
-espMqttClient& onDisconnect(espMqttClientTypes::OnDisconnectCallback callback)
-```
-
-Add a disconnect event handler. Function signature: `void(espMqttClientTypes::DisconnectReason reason)`
-
-- **`callback`**: Function to call
-
-```cpp
-espMqttClient& onSubscribe(espMqttClientTypes::OnSubscribeCallback callback)
-```
-
-Add a subscribe acknowledged event handler. Function signature: `void(uint16_t packetId, const espMqttClientTypes::SubscribeReturncode* returncodes, size_t len)`
-
-- **`callback`**: Function to call
-
-```cpp
-espMqttClient& onUnsubscribe(espMqttClientTypes::OnUnsubscribeCallback callback)
-```
-
-Add an unsubscribe acknowledged event handler. Function signature: `void(uint16_t packetId)`
-
-- **`callback`**: Function to call
-
-```cpp
-espMqttClient& onMessage(espMqttClientTypes::OnMessageCallback callback)
-```
-
-Add a publish received event handler. Function signature: `void(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total)`
-
-- **`callback`**: Function to call
-
-```cpp
-espMqttClient& onPublish(espMqttClientTypes::OnPublishCallback callback)
-```
-
-Add a publish acknowledged event handler. Function signature: `void(uint16_t packetId)`
-
-- **`callback`**: Function to call
-
-### Operational functions
-
-```cpp
-bool connected()
-```
-
-Returns `true` if the client is currently fully connected to the broker. During connecting or disconnecting, it will return `false`.
-
-```cpp
-bool disconnected()
-```
-
-Returns `true` if the client is currently disconnected from the broker. During disconnecting or connecting, it will return `false`.
-
-```cpp
-bool connect()
-```
-
-Start the connect procedure. Returns `true` if successful. A positive return value doesn not mean the client is already connected.
-
-```cpp
-bool disconnect(bool force = false)
-```
-
-Start the disconnect procedure, return `true` if successful. A positive return value doesn not mean the client is already disconnected.
-When disconnecting with `force` false, the client first tries to handle all the outgoing messages in the queue and disconnect cleanly afterwards. During this time, no incoming PUBLISH messages are handled.
-
-- **`force`**: Whether to force the disconnection. Defaults to `false` (clean disconnection).
-
-```cpp
-uint16_t subscribe(const char* topic, uint8_t qos)
-```
-
-Subscribe to the given topic at the given QoS. Return the packet ID or 0 if failed.
-
-- **`topic`**: Topic, expects a null-terminated char array (c-string)
-- **`qos`**: QoS
-
-It is also possible to subscribe to multiple topics at once. Just add the topic/qos pairs to the parameters:
-
-```cpp
-uint16_t packetId = yourclient.subscribe(topic1, qos1, topic2, qos2, topic3, qos3); // add as many topics as you like*
-```
-
-```cpp
-uint16_t unsubscribe(const char* topic)
-```
-
-Unsubscribe from the given topic. Return the packet ID or 0 if failed.
-
-- **`topic`**: Topic, expects a null-terminated char array (c-string)
-
-It is also possible to unsubscribe to multiple topics at once. Just add the topics to the parameters:
-
-```cpp
-uint16_t packetId = yourclient.unsubscribe(topic1, topic2, topic3); // add as many topics as you like*
-```
-
-```cpp
-uint16_t publish(const char* topic, uint8_t qos, bool retain, const uint8* payload, size_t length)
-```
-
-Publish a packet. Return the packet ID (or 1 if QoS 0) or 0 if failed. The topic and payload will be buffered by the library.
-
-- **`topic`**: Topic, expects a null-terminated char array (c-string)
-- **`qos`**: QoS
-- **`retain`**: Retain flag
-- **`payload`**: Payload
-- **`length`**: Payload length
-
-```cpp
-uint16_t publish(const char* topic, uint8_t qos, bool retain, const char* payload)
-```
-
-Publish a packet. Return the packet ID (or 1 if QoS 0) or 0 if failed. The topic and payload will be buffered by the library.
-
-- **`topic`**: Topic, expects a null-terminated char array (c-string)
-- **`qos`**: QoS
-- **`retain`**: Retain flag
-- **`payload`**: Payload, expects a null-terminated char array (c-string). Its lenght will be calculated using `strlen(payload)`
-
-```cpp
-uint16_t publish(const char* topic, uint8_t qos, bool retain, espMqttClientTypes::PayloadCallback callback, size_t length)
-```
-
-Publish a packet with a callback for payload handling. Return the packet ID (or 1 if QoS 0) or 0 if failed. The topic will be buffered by the library.
-
-- **`topic`**: Topic, expects a null-terminated char array (c-string)
-- **`qos`**: QoS
-- **`retain`**: Retain flag
-- **`callback`**: callback to fetch the payload.
-
-The callback has the following signature: `size_t callback(uint8_t* data, size_t maxSize, size_t index)`. When the library needs payload data, the callback will be invoked. It is the callback's job to write data indo `data` with a maximum of `maxSize` bytes, according the `index` and return the amount of bytes written.
-
-```cpp
-void clearQueue(bool deleteSessionData = false)
-```
-
-Clears all queued messages.
-Keep in mind that this may also delete any session data and therefore is not MQTT compliant.
-
-- **`deleteSessionData`**: When true, delete all outgoing messages. Not MQTT compliant!
-
-```cpp
-void loop()
-```
-
-This is the worker function of the MQTT client. For ESP8266 you must call this function in the Arduino loop. For ESP32 you have to call this function yourself **only if you have disabled the internal task** (see the constructors).
-
-```cpp
-const char* getClientId() const
-```
-
-Retuns the client ID.
-
-```cpp
-size_t queueSize();
-```
-
-Returns the amount of elements, regardless of type, in the queue.
-
-# Compile time configuration
-
-A number of constants which influence the behaviour of the client can be set at compile time. You can set these options in the `Config.h` file or pass the values as compiler flags. Because these options are compile-time constants, they are used for all instances of `espMqttClient` you create in your program.
-
-### EMC_TX_TIMEOUT 10000
-
-Timeout in milliseconds before a (qos > 0) message will be retransmitted.
-
-### EMC_RX_BUFFER_SIZE 1440
-
-The client copies incoming data into a buffer before parsing. This sets the buffer size.
-
-### EMC_TX_BUFFER_SIZE 1440
-
-When publishing using the callback, the client fetches data in chunks of EMC_TX_BUFFER_SIZE size. This is not necessarily the same as the actual outging TCP packets.
-
-### EMC_MAX_TOPIC_LENGTH 128
-
-For **incoming** messages, a maximum topic length is set. Topics longer than this will be truncated.
-
-### EMC_PAYLOAD_BUFFER_SIZE 32
-
-Set the incoming payload buffer size for SUBACK messages. When subscribing to multiple topics at once, the acknowledgement contains all the return codes in its payload. The detault of 32 means you can theoretically subscribe to 32 topics at once.
-
-### EMC_MIN_FREE_MEMORY 4096
-
-The client keeps all outgoing packets in a queue which stores its data in heap memory. With this option, you can set the minimum available (contiguous) heap memory that needs to be available for adding a message to the queue.
-
-### EMC_ESP8266_MULTITHREADING 0
-
-Set this to 1 if you use the async version on ESP8266. For the regular client this setting can be kept disabled because the ESP8266 doesn't use multithreading and is only single-core.
-
-### EMC_ALLOW_NOT_CONNECTED_PUBLISH 1
-
-By default, you can publish when the client is not connected. If you don't want this, set this to 0.
-Regardless of this setting, after you called `disconnect()`, no messages can be published until fully disconnected.
-
-### EMC_WAIT_FOR_CONNACK 1
-
-espMqttClient waits for the CONNACK (connection acknowledge) packet before starting to send other packets.
-The MQTT specification allows to start sending before the broker acknowledges the connection but some brokers
-don't allow this (AWS for example doesn't).
-
-### EMC_CLIENTID_LENGTH 18 + 1
-
-The (maximum) length of the client ID. (Keep in mind that this is a c-string. You need to have 1 position available for the null-termination.)
-
-### EMC_TASK_STACK_SIZE 5120
-
-Only used on ESP32. Sets the stack size (in words) of the MQTT client worker task.
-
-### EMC_MULTIPLE_CALLBACKS
-
-This macro is by default not enabled so you can add a single callbacks to an event. Assigning a second will overwrite the existing callback. When enabling multiple callbacks, multiple callbacks (with uint32_t id) can be assigned. Removing is done by referencing the id.
-
-### EMC_USE_WATCHDOG 0
-
-(ESP32 only)
-
-**Experimental**
-
-You can enable a watchdog on the MQTT task. This is experimental and will probably result in resets because some (framework) function calls block without feeding the dog.
-
-### EMC_USE_MEMPOOL 0
-
-**Experimental**
-
-When set to `1`, (outgoing) MQTT packets and the outbox data is stored in a memory pool. The memory pool is part of the espMqttClient object and is thus allocated in the same memory type. There are two pools: one to hold the outgoing packets (dynamic size elements) and one for the outbox itself (fixed-size elements).
-
-#### EMC_NUM_POOL_ELEMENTS 32
-
-This config variable is only used when enabling the memory pool. It defines
-- the number of elements in the outbox-pool
-- the number of blocks that will be allocated in the packet-pool
-
-#### EMC_SIZE_POOL_ELEMENTS 128
-
-This defines the size of one packet-pool element. Together with `EMC_NUM_POOL_ELEMENTS`, you get the total packet-pool size.
-The packet-pool can hold any size of element. The configuration only guarantees a minimum of `EMC_NUM_POOL_ELEMENTS` of size `EMC_SIZE_POOL_ELEMENTS` can fit in the pool.
-
-### Logging
-
-If needed, you have to enable logging at compile time. This is done differently on ESP32 and ESP8266.
-
-ESP8266:
-
-- Enable logging for Arduino [see docs](https://arduino-esp8266.readthedocs.io/en/latest/Troubleshooting/debugging.html)
-- Pass the `DEBUG_ESP_MQTT_CLIENT` flag to the compiler
-
-ESP32
-
-- Enable logging for Arduino [see docs](https://docs.espressif.com/projects/arduino-esp32/en/latest/guides/tools_menu.html?#core-debug-level)
-
-# Code samples
-
-A number of examples are in the [examples](/examples) directory. These include basic operation on ESP8266 and ESP32. Please examine these to understand the basic operation of the MQTT client.
-
-Below are examples on specific points for working with this library.
-
-### Printing payloads
-
-MQTT 3.1.1 defines no special format for the payload so it is treated as binary. If you want to print a payload to the Arduino serial console, you have to make sure that the payload is null-terminated (c-string).
-
-```cpp
-// option one: print the payload char by char
-void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
- Serial.println("Publish received:");
- Serial.printf(" topic: %s\n payload:", topic);
- const char* p = reinterpret_cast(payload);
- for (size_t i = 0; i < len; ++i) {
- Serial.print(p[i]);
- }
- Serial.print("\n");
-}
-```
-
-```cpp
-// option two: copy the payload into a c-string
-// you cannot just do payload[len] = 0 because you do not own this memory location!
-void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
- Serial.println("Publish received:");
- Serial.printf(" topic: %s\n payload:", topic);
- char* strval = new char[len + 1];
- memcpy(strval, payload, len);
- strval[len] = "\0";
- Serial.println(strval);
- delete[] strval;
-}
-```
-
-### Assembling chunked messages
-
-The `onMessage`-callback is called as data comes in. So if the data comes in partially, the callback will be called on every receipt of a chunk, with the proper `index`, (chunk)`size` and `total` set. With little code, you can reassemble chunked messages yourself.
-
-```cpp
-const size_t maxPayloadSize = 8192;
-uint8_t* payloadbuffer = nullptr;
-size_t payloadbufferSize = 0;
-size_t payloadbufferIndex = 0;
-
-void onOversizedMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
- // handle oversized messages
-}
-
-void onCompleteMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
- // handle assembled messages
-}
-
-void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
- // payload is bigger then max: return chunked
- if (total > maxPayloadSize) {
- onOversizedMqttMessage(properties, topic, payload, len, index, total);
- return;
- }
-
- // start new packet, increase buffer size if neccesary
- if (index == 0) {
- if (total > payloadbufferSize) {
- delete[] payloadbuffer;
- payloadbufferSize = total;
- payloadbuffer = new (std::nothrow) uint8_t[payloadbufferSize];
- if (!payloadbuffer) {
- // no buffer could be created. you might want to log this somewhere
- return;
- }
- }
- payloadbufferIndex = 0;
- }
-
- // add data and dispatch when done
- if (payloadBuffer) {
- memcpy(&payloadbuffer[payloadbufferIndex], payload, len);
- payloadbufferIndex += len;
- if (payloadbufferIndex == total) {
- // message is complete here
- onCompleteMqttMessage(properties, topic, payloadBuffer, total, 0, total);
- // optionally:
- delete[] payloadBuffer;
- payloadBuffer = nullptr;
- payloadbufferSize = 0;
- }
- }
-}
-
-// attach callback to MQTT client
-mqttClient.onMessage(onMqttMessage);
-```
-
-### onMessage callbacks per topic
-
-espMqttClient allows only one callback for incoming messages. You might want to have specific ones per topic. This example shows one way on how to achieve this.
-
-Limitations of this code sample: only the first match is served and no wildcard topics allowed.
-
-```cpp
-#include