chore: import local project into Gitea
This commit is contained in:
1
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/.piopm
Normal file
1
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/.piopm
Normal file
@@ -0,0 +1 @@
|
||||
{"type": "library", "name": "AsyncTCP", "version": "3.4.9", "spec": {"owner": "esp32async", "id": 18273, "name": "AsyncTCP", "requirements": null, "uri": null}}
|
||||
165
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/LICENSE
Normal file
165
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/LICENSE
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
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.
|
||||
55
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/README.md
Normal file
55
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||

|
||||
|
||||
# AsyncTCP
|
||||
|
||||
[](https://opensource.org/license/lgpl-3-0/)
|
||||
[](https://github.com/ESP32Async/AsyncTCP/actions/workflows/ci.yml)
|
||||
[](https://registry.platformio.org/libraries/ESP32Async/AsyncTCP)
|
||||
|
||||
Discord Server: [https://discord.gg/X7zpGdyUcY](https://discord.gg/X7zpGdyUcY)
|
||||
|
||||
## Async TCP Library for ESP32 Arduino
|
||||
|
||||
This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs.
|
||||
|
||||
This library is the base for [ESPAsyncWebServer](https://github.com/ESP32Async/ESPAsyncWebServer)
|
||||
|
||||
## How to install
|
||||
|
||||
The library can be downloaded from the releases page at [https://github.com/ESP32Async/AsyncTCP/releases](https://github.com/ESP32Async/AsyncTCP/releases).
|
||||
|
||||
It is also deployed in these registries:
|
||||
|
||||
- Arduino Library Registry: [https://github.com/arduino/library-registry](https://github.com/arduino/library-registry)
|
||||
|
||||
- ESP Component Registry [https://components.espressif.com/components/esp32async/asynctcp/](https://components.espressif.com/components/esp32async/asynctcp/)
|
||||
|
||||
- PlatformIO Registry: [https://registry.platformio.org/libraries/esp32async/AsyncTCP](https://registry.platformio.org/libraries/esp32async/AsyncTCP)
|
||||
|
||||
- Use: `lib_deps=ESP32Async/AsyncTCP` to point to latest version
|
||||
- Use: `lib_deps=ESP32Async/AsyncTCP @ ^<x.y.z>` to point to latest version with the same major version
|
||||
- Use: `lib_deps=ESP32Async/AsyncTCP @ <x.y.z>` to always point to the same version (reproductible build)
|
||||
|
||||
## 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.
|
||||
|
||||
## Important recommendations
|
||||
|
||||
Most of the crashes are caused by improper configuration of the library for the project.
|
||||
Here are some recommendations to avoid them.
|
||||
|
||||
I personally use the following configuration in my projects:
|
||||
|
||||
```c++
|
||||
-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 // (keep default)
|
||||
-D CONFIG_ASYNC_TCP_PRIORITY=10 // (keep default)
|
||||
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=64 // (keep default)
|
||||
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1 // force async_tcp task to be on same core as the app (default is core 0)
|
||||
-D CONFIG_ASYNC_TCP_STACK_SIZE=4096 // reduce the stack size (default is 16K)
|
||||
```
|
||||
|
||||
## Compatibility
|
||||
|
||||
- ESP32
|
||||
- Arduino Core 2.x and 3.x
|
||||
@@ -0,0 +1,169 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||
|
||||
/*
|
||||
This example demonstrates how to send data to a remote server asynchronously.
|
||||
Run on the remote computer: nc -l -p 1234
|
||||
|
||||
You should see in the logs:
|
||||
|
||||
Connected!
|
||||
Will send 5760 bytes...
|
||||
Acked 1436 bytes in 19 ms
|
||||
Will send 1436 bytes...
|
||||
Acked 1436 bytes in 2 ms
|
||||
Will send 996 bytes...
|
||||
Waiting for acks...
|
||||
Acked 1436 bytes in 1 ms
|
||||
Acked 1436 bytes in 5 ms
|
||||
Acked 1452 bytes in 17 ms
|
||||
Acked 996 bytes in 28 ms
|
||||
Buffer received - next send in 2 sec
|
||||
Will send 5760 bytes...
|
||||
Acked 1436 bytes in 14 ms
|
||||
Will send 1436 bytes...
|
||||
Acked 1436 bytes in 2 ms
|
||||
Acked 1436 bytes in 0 ms
|
||||
Acked 1452 bytes in 1 ms
|
||||
Will send 996 bytes...
|
||||
Waiting for acks...
|
||||
Acked 1436 bytes in 3 ms
|
||||
Acked 996 bytes in 18 ms
|
||||
Buffer received - next send in 2 sec
|
||||
|
||||
And in the remote terminal 3072 characters sent [......... ...........] and so on.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include <StreamString.h>
|
||||
#include <WiFi.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#define WIFI_SSID "IoT"
|
||||
#define WIFI_PASSWORD ""
|
||||
|
||||
#define REMOTE_IP "192.168.125.116"
|
||||
#define REMOTE_PORT 1234
|
||||
|
||||
#define BUFFER_SIZE 8 * 1024
|
||||
|
||||
static char buffer[BUFFER_SIZE] = {0};
|
||||
static size_t bufferPos = 0;
|
||||
|
||||
// 0 == disconnected
|
||||
// 1 == connecting
|
||||
// 2 == connected
|
||||
static uint8_t state = 0;
|
||||
|
||||
// number of bytes waiting for a ack
|
||||
static size_t waitingAck = 0;
|
||||
|
||||
static AsyncClient client;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// connect to WiFi
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
}
|
||||
Serial.println("Connected to WiFi!");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
// fill buffer
|
||||
buffer[0] = '[';
|
||||
for (size_t i = 1; i < BUFFER_SIZE - 1; i++) {
|
||||
buffer[i] = '.';
|
||||
}
|
||||
buffer[BUFFER_SIZE - 1] = ']';
|
||||
|
||||
// register a callback when the client disconnects
|
||||
client.onDisconnect([](void *arg, AsyncClient *client) {
|
||||
Serial.printf("Disconnected.\n");
|
||||
state = 0;
|
||||
});
|
||||
|
||||
// register a callback when an error occurs
|
||||
client.onError([](void *arg, AsyncClient *client, int8_t error) {
|
||||
Serial.printf("Error: %s\n", client->errorToString(error));
|
||||
});
|
||||
|
||||
// register a callback when data arrives, to accumulate it
|
||||
client.onData([](void *arg, AsyncClient *client, void *data, size_t len) {
|
||||
Serial.printf("Received %u bytes...\n", len);
|
||||
Serial.write((uint8_t *)data, len);
|
||||
});
|
||||
|
||||
// register a callback when we are connected
|
||||
client.onConnect([](void *arg, AsyncClient *client) {
|
||||
Serial.printf("Connected!\n");
|
||||
state = 2;
|
||||
});
|
||||
|
||||
client.onAck([](void *arg, AsyncClient *client, size_t len, uint32_t time) {
|
||||
Serial.printf("Acked %u bytes in %" PRIu32 " ms\n", len, time);
|
||||
assert(waitingAck >= len);
|
||||
waitingAck -= len;
|
||||
});
|
||||
|
||||
client.setRxTimeout(20000);
|
||||
client.setNoDelay(true);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
switch (state) {
|
||||
case 0:
|
||||
{
|
||||
Serial.printf("Connecting...\n");
|
||||
if (!client.connect(REMOTE_IP, REMOTE_PORT)) {
|
||||
Serial.printf("Failed to connect!\n");
|
||||
delay(1000); // to not flood logs
|
||||
} else {
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
Serial.printf("Still connecting...\n");
|
||||
delay(500); // to not flood logs
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
// fill PCB space until we can
|
||||
size_t willSend;
|
||||
while (bufferPos < BUFFER_SIZE && (willSend = client.write(buffer + bufferPos, BUFFER_SIZE - bufferPos))) {
|
||||
Serial.printf("Will send %u bytes...\n", willSend);
|
||||
bufferPos += willSend;
|
||||
waitingAck += willSend;
|
||||
}
|
||||
|
||||
// we have sent the whole buffer ?
|
||||
if (bufferPos >= BUFFER_SIZE) {
|
||||
// wait for acks, or send again after 2 sec
|
||||
if (waitingAck) {
|
||||
Serial.printf("Waiting for acks...\n");
|
||||
delay(100);
|
||||
} else {
|
||||
Serial.printf("Buffer received - next send in 2 sec\n");
|
||||
delay(2000);
|
||||
bufferPos = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
// Run a server at the root of the project with:
|
||||
// > python3 -m http.server 3333
|
||||
// Now you can open a browser and test it works by visiting http://192.168.125.122:3333/ or http://192.168.125.122:3333/README.md
|
||||
#define HOST "192.168.125.122"
|
||||
#define PORT 3333
|
||||
|
||||
// WiFi SSID to connect to
|
||||
#define WIFI_SSID "IoT"
|
||||
|
||||
// 16 slots on esp32 (CONFIG_LWIP_MAX_ACTIVE_TCP)
|
||||
#define MAX_CLIENTS CONFIG_LWIP_MAX_ACTIVE_TCP
|
||||
// #define MAX_CLIENTS 1
|
||||
|
||||
size_t permits = MAX_CLIENTS;
|
||||
|
||||
void makeRequest() {
|
||||
if (!permits) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.printf("** permits: %d\n", permits);
|
||||
|
||||
AsyncClient *client = new AsyncClient;
|
||||
|
||||
client->onError([](void *arg, AsyncClient *client, int8_t error) {
|
||||
Serial.printf("** error occurred %s \n", client->errorToString(error));
|
||||
client->close(true);
|
||||
delete client;
|
||||
});
|
||||
|
||||
client->onConnect([](void *arg, AsyncClient *client) {
|
||||
permits--;
|
||||
Serial.printf("** client has been connected: %" PRIu16 "\n", client->localPort());
|
||||
|
||||
client->onDisconnect([](void *arg, AsyncClient *client) {
|
||||
Serial.printf("** client has been disconnected: %" PRIu16 "\n", client->localPort());
|
||||
client->close(true);
|
||||
delete client;
|
||||
|
||||
permits++;
|
||||
makeRequest();
|
||||
});
|
||||
|
||||
client->onData([](void *arg, AsyncClient *client, void *data, size_t len) {
|
||||
Serial.printf("** data received by client: %" PRIu16 ": len=%u\n", client->localPort(), len);
|
||||
});
|
||||
|
||||
client->write("GET /README.md HTTP/1.1\r\nHost: " HOST "\r\nUser-Agent: ESP\r\nConnection: close\r\n\r\n");
|
||||
});
|
||||
|
||||
if (client->connect(HOST, PORT)) {
|
||||
} else {
|
||||
Serial.println("** connection failed");
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(WIFI_SSID);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("** connected to WiFi");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
for (size_t i = 0; i < MAX_CLIENTS; i++) {
|
||||
makeRequest();
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(1000);
|
||||
Serial.printf("** free heap: %" PRIu32 "\n", ESP.getFreeHeap());
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include <StreamString.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#define WIFI_SSID "IoT"
|
||||
#define WIFI_PASSWORD ""
|
||||
|
||||
void fetchAsync(const char *host, std::function<void(const StreamString *)> onDone) {
|
||||
Serial.printf("[%s] Fetching: http://%s...\n", host, host);
|
||||
|
||||
// buffer where we will accumulate the received data
|
||||
StreamString *content = new StreamString();
|
||||
|
||||
// reserve enough space to avoid reallocations
|
||||
content->reserve(32 * 1024);
|
||||
|
||||
// create a new client
|
||||
AsyncClient *client = new AsyncClient();
|
||||
|
||||
// register a callback when the client disconnects
|
||||
client->onDisconnect([content, host, onDone](void *arg, AsyncClient *client) {
|
||||
Serial.printf("[%s] Disconnected.\n", host);
|
||||
onDone(content);
|
||||
delete client;
|
||||
delete content;
|
||||
});
|
||||
|
||||
// register a callback when an error occurs
|
||||
client->onError([host, onDone](void *arg, AsyncClient *client, int8_t error) {
|
||||
Serial.printf("[%s] Error: %s\n", host, client->errorToString(error));
|
||||
});
|
||||
|
||||
// register a callback when data arrives, to accumulate it
|
||||
client->onData([host, content](void *arg, AsyncClient *client, void *data, size_t len) {
|
||||
Serial.printf("[%s] Received %u bytes...\n", host, len);
|
||||
content->write((const uint8_t *)data, len);
|
||||
});
|
||||
|
||||
// register a callback when we are connected
|
||||
client->onConnect([host](void *arg, AsyncClient *client) {
|
||||
Serial.printf("[%s] Connected!\n", host);
|
||||
|
||||
// send request
|
||||
client->write("GET / HTTP/1.1\r\n");
|
||||
client->write("Host: ");
|
||||
client->write(host);
|
||||
client->write("\r\n");
|
||||
client->write("User-Agent: ESP32\r\n");
|
||||
client->write("Connection: close\r\n");
|
||||
client->write("\r\n");
|
||||
});
|
||||
|
||||
Serial.printf("[%s] Connecting...\n", host);
|
||||
|
||||
if (!client->connect(host, 80)) {
|
||||
Serial.printf("[%s] Failed to connect!\n", host);
|
||||
delete client;
|
||||
delete content;
|
||||
onDone(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// connect to WiFi
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
}
|
||||
Serial.println("Connected to WiFi!");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
// fetch asynchronously 2 websites:
|
||||
|
||||
// equivalent to curl -v --raw http://www.time.org/
|
||||
fetchAsync("www.time.org", [](const StreamString *content) {
|
||||
if (content) {
|
||||
Serial.printf("[www.time.org] Fetched website:\n%s\n", content->c_str());
|
||||
} else {
|
||||
Serial.println("[www.time.org] Failed to fetch website!");
|
||||
}
|
||||
});
|
||||
|
||||
// equivalent to curl -v --raw http://www.google.com/
|
||||
fetchAsync("www.google.com", [](const StreamString *content) {
|
||||
if (content) {
|
||||
Serial.printf("[www.google.com] Fetched website:\n%s\n", content->c_str());
|
||||
} else {
|
||||
Serial.println("[www.google.com] Failed to fetch website!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(100);
|
||||
}
|
||||
31
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/library.json
Normal file
31
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/library.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "AsyncTCP",
|
||||
"version": "3.4.9",
|
||||
"description": "Asynchronous TCP Library for ESP32",
|
||||
"keywords": "async,tcp",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ESP32Async/AsyncTCP.git"
|
||||
},
|
||||
"authors":
|
||||
{
|
||||
"name": "ESP32Async",
|
||||
"maintainer": true
|
||||
},
|
||||
"license": "LGPL-3.0",
|
||||
"frameworks": "arduino",
|
||||
"platforms": [
|
||||
"espressif32",
|
||||
"libretiny"
|
||||
],
|
||||
"export": {
|
||||
"include": [
|
||||
"examples",
|
||||
"src",
|
||||
"library.json",
|
||||
"library.properties",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
name=Async TCP
|
||||
includes=AsyncTCP.h
|
||||
version=3.4.9
|
||||
author=ESP32Async
|
||||
maintainer=ESP32Async
|
||||
sentence=Async TCP Library for ESP32
|
||||
paragraph=Async TCP Library for ESP32
|
||||
category=Other
|
||||
url=https://github.com/ESP32Async/AsyncTCP.git
|
||||
architectures=*
|
||||
license=LGPL-3.0
|
||||
1612
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/src/AsyncTCP.cpp
Normal file
1612
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/src/AsyncTCP.cpp
Normal file
File diff suppressed because it is too large
Load Diff
335
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/src/AsyncTCP.h
Normal file
335
WiFiX-Enhanced/.pio/libdeps/esp32_main/AsyncTCP/src/AsyncTCP.h
Normal file
@@ -0,0 +1,335 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||
|
||||
#ifndef ASYNCTCP_H_
|
||||
#define ASYNCTCP_H_
|
||||
|
||||
#include "AsyncTCPVersion.h"
|
||||
#define ASYNCTCP_FORK_ESP32Async
|
||||
|
||||
#ifdef ARDUINO
|
||||
#include "IPAddress.h"
|
||||
#if __has_include(<IPv6Address.h>)
|
||||
#include "IPv6Address.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "lwip/ip6_addr.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include <functional>
|
||||
|
||||
#ifndef LIBRETINY
|
||||
#include "sdkconfig.h"
|
||||
extern "C" {
|
||||
#include "freertos/semphr.h"
|
||||
#include "lwip/pbuf.h"
|
||||
}
|
||||
#else
|
||||
extern "C" {
|
||||
#include <lwip/pbuf.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <semphr.h>
|
||||
}
|
||||
#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
|
||||
#endif
|
||||
|
||||
// guard AsyncTCP task with watchdog
|
||||
#ifndef CONFIG_ASYNC_TCP_USE_WDT
|
||||
#define CONFIG_ASYNC_TCP_USE_WDT 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ASYNC_TCP_STACK_SIZE
|
||||
#define CONFIG_ASYNC_TCP_STACK_SIZE 8192 * 2
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ASYNC_TCP_PRIORITY
|
||||
#define CONFIG_ASYNC_TCP_PRIORITY 10
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ASYNC_TCP_QUEUE_SIZE
|
||||
#define CONFIG_ASYNC_TCP_QUEUE_SIZE 64
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ASYNC_TCP_MAX_ACK_TIME
|
||||
#define CONFIG_ASYNC_TCP_MAX_ACK_TIME 5000
|
||||
#endif
|
||||
|
||||
class AsyncClient;
|
||||
|
||||
#define ASYNC_WRITE_FLAG_COPY 0x01 // will allocate new buffer to hold the data while sending (else will hold reference to the data given)
|
||||
#define ASYNC_WRITE_FLAG_MORE 0x02 // will not send PSH flag, meaning that there should be more data to be sent before the application should react.
|
||||
|
||||
typedef std::function<void(void *, AsyncClient *)> AcConnectHandler;
|
||||
typedef std::function<void(void *, AsyncClient *, size_t len, uint32_t time)> AcAckHandler;
|
||||
typedef std::function<void(void *, AsyncClient *, int8_t error)> AcErrorHandler;
|
||||
typedef std::function<void(void *, AsyncClient *, void *data, size_t len)> AcDataHandler;
|
||||
typedef std::function<void(void *, AsyncClient *, struct pbuf *pb)> AcPacketHandler;
|
||||
typedef std::function<void(void *, AsyncClient *, uint32_t time)> AcTimeoutHandler;
|
||||
|
||||
struct tcp_pcb;
|
||||
class AsyncTCP_detail;
|
||||
|
||||
class AsyncClient {
|
||||
public:
|
||||
AsyncClient(tcp_pcb *pcb = 0);
|
||||
~AsyncClient();
|
||||
|
||||
// Noncopyable
|
||||
AsyncClient(const AsyncClient &) = delete;
|
||||
AsyncClient &operator=(const AsyncClient &) = delete;
|
||||
|
||||
// Nonmovable
|
||||
AsyncClient(AsyncClient &&) = delete;
|
||||
AsyncClient &operator=(AsyncClient &&) = delete;
|
||||
|
||||
bool operator==(const AsyncClient &other) const;
|
||||
|
||||
bool operator!=(const AsyncClient &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
bool connect(ip_addr_t addr, uint16_t port);
|
||||
#ifdef ARDUINO
|
||||
bool connect(const IPAddress &ip, uint16_t port);
|
||||
#if __has_include(<IPv6Address.h>)
|
||||
bool connect(const IPv6Address &ip, uint16_t port);
|
||||
#endif
|
||||
#endif
|
||||
bool connect(const char *host, uint16_t port);
|
||||
/**
|
||||
* @brief close connection
|
||||
*
|
||||
* @param now - ignored
|
||||
*/
|
||||
void close(bool now = false);
|
||||
// same as close()
|
||||
void stop() {
|
||||
close(false);
|
||||
};
|
||||
int8_t abort();
|
||||
bool free();
|
||||
|
||||
// ack is not pending
|
||||
bool canSend() const;
|
||||
// TCP buffer space available
|
||||
size_t space() const;
|
||||
|
||||
/**
|
||||
* @brief add data to be send (but do not send yet)
|
||||
* @note add() would call lwip's tcp_write()
|
||||
By default apiflags=ASYNC_WRITE_FLAG_COPY
|
||||
You could try to use apiflags with this flag unset to pass data by reference and avoid copy to socket buffer,
|
||||
but looks like it does not work for Arduino's lwip in ESP32/IDF at least
|
||||
it is enforced in https://github.com/espressif/esp-lwip/blob/0606eed9d8b98a797514fdf6eabb4daf1c8c8cd9/src/core/tcp_out.c#L422C5-L422C30
|
||||
if LWIP_NETIF_TX_SINGLE_PBUF is set, and it is set indeed in IDF
|
||||
https://github.com/espressif/esp-idf/blob/a0f798cfc4bbd624aab52b2c194d219e242d80c1/components/lwip/port/include/lwipopts.h#L744
|
||||
*
|
||||
* @param data
|
||||
* @param size
|
||||
* @param apiflags
|
||||
* @return size_t amount of data that has been copied
|
||||
*/
|
||||
size_t add(const char *data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY);
|
||||
|
||||
/**
|
||||
* @brief send data previously add()'ed
|
||||
*
|
||||
* @return true on success
|
||||
* @return false on error
|
||||
*/
|
||||
bool send();
|
||||
|
||||
/**
|
||||
* @brief add and enqueue data for sending
|
||||
* @note it is same as add() + send()
|
||||
* @note only make sense when canSend() == true
|
||||
*
|
||||
* @param data
|
||||
* @param size
|
||||
* @param apiflags
|
||||
* @return size_t
|
||||
*/
|
||||
size_t write(const char *data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY);
|
||||
|
||||
/**
|
||||
* @brief add and enqueue data for sending
|
||||
* @note treats data as null-terminated string
|
||||
*
|
||||
* @param data
|
||||
* @return size_t
|
||||
*/
|
||||
size_t write(const char *data) {
|
||||
return data == NULL ? 0 : write(data, strlen(data));
|
||||
};
|
||||
|
||||
uint8_t state() const;
|
||||
bool connecting() const;
|
||||
bool connected() const;
|
||||
bool disconnecting() const;
|
||||
bool disconnected() const;
|
||||
|
||||
// disconnected or disconnecting
|
||||
bool freeable() const;
|
||||
|
||||
uint16_t getMss() const;
|
||||
|
||||
uint32_t getRxTimeout() const;
|
||||
// no RX data timeout for the connection in seconds
|
||||
void setRxTimeout(uint32_t timeout);
|
||||
|
||||
uint32_t getAckTimeout() const;
|
||||
// no ACK timeout for the last sent packet in milliseconds
|
||||
void setAckTimeout(uint32_t timeout);
|
||||
|
||||
void setNoDelay(bool nodelay) const;
|
||||
bool getNoDelay();
|
||||
|
||||
void setKeepAlive(uint32_t ms, uint8_t cnt);
|
||||
|
||||
uint32_t getRemoteAddress() const;
|
||||
uint16_t getRemotePort() const;
|
||||
uint16_t remotePort() const {
|
||||
return getRemotePort();
|
||||
}
|
||||
|
||||
uint32_t getLocalAddress() const;
|
||||
uint16_t getLocalPort() const;
|
||||
uint16_t localPort() const {
|
||||
return getLocalPort();
|
||||
}
|
||||
|
||||
ip4_addr_t getRemoteAddress4() const;
|
||||
ip4_addr_t getLocalAddress4() const;
|
||||
|
||||
#if LWIP_IPV6
|
||||
ip6_addr_t getRemoteAddress6() const;
|
||||
ip6_addr_t getLocalAddress6() const;
|
||||
#ifdef ARDUINO
|
||||
#if __has_include(<IPv6Address.h>)
|
||||
IPv6Address remoteIP6() const;
|
||||
IPv6Address localIP6() const;
|
||||
#else
|
||||
IPAddress remoteIP6() const;
|
||||
IPAddress localIP6() const;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO
|
||||
IPAddress remoteIP() const;
|
||||
IPAddress localIP() const;
|
||||
#endif
|
||||
|
||||
// set callback - on successful connect
|
||||
void onConnect(AcConnectHandler cb, void *arg = 0);
|
||||
// set callback - disconnected
|
||||
void onDisconnect(AcConnectHandler cb, void *arg = 0);
|
||||
// set callback - ack received
|
||||
void onAck(AcAckHandler cb, void *arg = 0);
|
||||
// set callback - unsuccessful connect or error
|
||||
void onError(AcErrorHandler cb, void *arg = 0);
|
||||
// set callback - data received (called if onPacket is not used)
|
||||
void onData(AcDataHandler cb, void *arg = 0);
|
||||
// set callback - data received
|
||||
// !!! You MUST call ackPacket() or free the pbuf yourself to prevent memory leaks
|
||||
void onPacket(AcPacketHandler cb, void *arg = 0);
|
||||
// set callback - ack timeout
|
||||
void onTimeout(AcTimeoutHandler cb, void *arg = 0);
|
||||
// set callback - every 125ms when connected
|
||||
void onPoll(AcConnectHandler cb, void *arg = 0);
|
||||
|
||||
// ack pbuf from onPacket
|
||||
void ackPacket(struct pbuf *pb);
|
||||
// ack data that you have not acked using the method below
|
||||
size_t ack(size_t len);
|
||||
// will not ack the current packet. Call from onData
|
||||
void ackLater() {
|
||||
_ack_pcb = false;
|
||||
}
|
||||
|
||||
static const char *errorToString(int8_t error);
|
||||
const char *stateToString() const;
|
||||
|
||||
int8_t _recv(tcp_pcb *pcb, pbuf *pb, int8_t err);
|
||||
tcp_pcb *pcb() {
|
||||
return _pcb;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class AsyncTCP_detail;
|
||||
friend class AsyncServer;
|
||||
|
||||
tcp_pcb *_pcb;
|
||||
|
||||
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();
|
||||
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(ip_addr_t *ipaddr);
|
||||
};
|
||||
|
||||
class AsyncServer {
|
||||
public:
|
||||
AsyncServer(ip_addr_t addr, uint16_t port);
|
||||
#ifdef ARDUINO
|
||||
AsyncServer(IPAddress addr, uint16_t port);
|
||||
#if __has_include(<IPv6Address.h>)
|
||||
AsyncServer(IPv6Address addr, uint16_t port);
|
||||
#endif
|
||||
#endif
|
||||
AsyncServer(uint16_t port);
|
||||
~AsyncServer();
|
||||
void onClient(AcConnectHandler cb, void *arg);
|
||||
void begin();
|
||||
void end();
|
||||
void setNoDelay(bool nodelay);
|
||||
bool getNoDelay() const;
|
||||
uint8_t status() const;
|
||||
|
||||
protected:
|
||||
friend class AsyncTCP_detail;
|
||||
|
||||
uint16_t _port;
|
||||
ip_addr_t _addr;
|
||||
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_ */
|
||||
@@ -0,0 +1,66 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef CONFIG_ASYNC_TCP_LOG_CUSTOM
|
||||
// The user must provide the following macros in AsyncTCPLoggingCustom.h:
|
||||
// async_tcp_log_e, async_tcp_log_w, async_tcp_log_i, async_tcp_log_d, async_tcp_log_v
|
||||
#include <AsyncTCPLoggingCustom.h>
|
||||
|
||||
#elif defined(CONFIG_ASYNC_TCP_DEBUG)
|
||||
// Local Debug logging
|
||||
#include <HardwareSerial.h>
|
||||
#define async_tcp_log_e(format, ...) Serial.printf("E async_tcp %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);
|
||||
#define async_tcp_log_w(format, ...) Serial.printf("W async_tcp %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);
|
||||
#define async_tcp_log_i(format, ...) Serial.printf("I async_tcp %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);
|
||||
#define async_tcp_log_d(format, ...) Serial.printf("D async_tcp %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);
|
||||
#define async_tcp_log_v(format, ...) Serial.printf("V async_tcp %s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__);
|
||||
|
||||
#else
|
||||
// Framework-based logging
|
||||
|
||||
/**
|
||||
* LibreTiny specific configurations
|
||||
*/
|
||||
#if defined(LIBRETINY)
|
||||
#include <Arduino.h>
|
||||
#define async_tcp_log_e(format, ...) log_e(format, ##__VA_ARGS__)
|
||||
#define async_tcp_log_w(format, ...) log_w(format, ##__VA_ARGS__)
|
||||
#define async_tcp_log_i(format, ...) log_i(format, ##__VA_ARGS__)
|
||||
#define async_tcp_log_d(format, ...) log_d(format, ##__VA_ARGS__)
|
||||
#define async_tcp_log_v(format, ...) log_v(format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Arduino specific configurations
|
||||
*/
|
||||
#elif defined(ARDUINO)
|
||||
#if defined(USE_ESP_IDF_LOG)
|
||||
#include <esp_log.h>
|
||||
#define async_tcp_log_e(format, ...) ESP_LOGE("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define async_tcp_log_w(format, ...) ESP_LOGW("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define async_tcp_log_i(format, ...) ESP_LOGI("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define async_tcp_log_d(format, ...) ESP_LOGD("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define async_tcp_log_v(format, ...) ESP_LOGV("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#include <esp32-hal-log.h>
|
||||
#define async_tcp_log_e(format, ...) log_e(format, ##__VA_ARGS__)
|
||||
#define async_tcp_log_w(format, ...) log_w(format, ##__VA_ARGS__)
|
||||
#define async_tcp_log_i(format, ...) log_i(format, ##__VA_ARGS__)
|
||||
#define async_tcp_log_d(format, ...) log_d(format, ##__VA_ARGS__)
|
||||
#define async_tcp_log_v(format, ...) log_v(format, ##__VA_ARGS__)
|
||||
#endif // USE_ESP_IDF_LOG
|
||||
|
||||
/**
|
||||
* ESP-IDF specific configurations
|
||||
*/
|
||||
#else
|
||||
#include <esp_log.h>
|
||||
#define async_tcp_log_e(format, ...) ESP_LOGE("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define async_tcp_log_w(format, ...) ESP_LOGW("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define async_tcp_log_i(format, ...) ESP_LOGI("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define async_tcp_log_d(format, ...) ESP_LOGD("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#define async_tcp_log_v(format, ...) ESP_LOGV("async_tcp", "%s() %d: " format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#endif // !LIBRETINY && !ARDUINO
|
||||
|
||||
#endif // CONFIG_ASYNC_TCP_LOG_CUSTOM
|
||||
@@ -0,0 +1,134 @@
|
||||
// Simple intrusive list class
|
||||
#pragma once
|
||||
|
||||
template<typename T> class SimpleIntrusiveList {
|
||||
static_assert(std::is_same<decltype(std::declval<T>().next), T *>::value, "Template type must have public 'T* next' member");
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef value_type *value_ptr_type;
|
||||
typedef value_ptr_type *value_ptr_ptr_type;
|
||||
|
||||
// Static utility methods
|
||||
static size_t list_size(value_ptr_type chain) {
|
||||
size_t count = 0;
|
||||
for (auto c = chain; c != nullptr; c = c->next) {
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void delete_list(value_ptr_type chain) {
|
||||
while (chain) {
|
||||
auto t = chain;
|
||||
chain = chain->next;
|
||||
delete t;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// Object methods
|
||||
|
||||
SimpleIntrusiveList() : _head(nullptr), _tail(&_head) {}
|
||||
~SimpleIntrusiveList() {
|
||||
clear();
|
||||
}
|
||||
|
||||
// Noncopyable, nonmovable
|
||||
SimpleIntrusiveList(const SimpleIntrusiveList<T> &) = delete;
|
||||
SimpleIntrusiveList(SimpleIntrusiveList<T> &&) = delete;
|
||||
SimpleIntrusiveList<T> &operator=(const SimpleIntrusiveList<T> &) = delete;
|
||||
SimpleIntrusiveList<T> &operator=(SimpleIntrusiveList<T> &&) = delete;
|
||||
|
||||
inline void push_back(value_ptr_type obj) {
|
||||
if (obj) {
|
||||
*_tail = obj;
|
||||
_tail = &obj->next;
|
||||
++_size;
|
||||
}
|
||||
}
|
||||
|
||||
inline void push_front(value_ptr_type obj) {
|
||||
if (obj) {
|
||||
if (_head == nullptr) {
|
||||
_tail = &obj->next;
|
||||
}
|
||||
obj->next = _head;
|
||||
_head = obj;
|
||||
++_size;
|
||||
}
|
||||
}
|
||||
|
||||
inline value_ptr_type pop_front() {
|
||||
auto rv = _head;
|
||||
if (_head) {
|
||||
if (_tail == &_head->next) {
|
||||
_tail = &_head;
|
||||
}
|
||||
_head = _head->next;
|
||||
--_size;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline void clear() {
|
||||
// Assumes all elements were allocated with "new"
|
||||
delete_list(_head);
|
||||
_head = nullptr;
|
||||
_tail = &_head;
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
inline size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
template<typename function_type> inline value_ptr_type remove_if(const function_type &condition) {
|
||||
value_ptr_type removed = nullptr;
|
||||
value_ptr_ptr_type current_ptr = &_head;
|
||||
while (*current_ptr != nullptr) {
|
||||
value_ptr_type current = *current_ptr;
|
||||
if (condition(*current)) {
|
||||
// Remove this item from the list by moving the next item in
|
||||
*current_ptr = current->next;
|
||||
// If we were the last item, reset tail
|
||||
if (current->next == nullptr) {
|
||||
_tail = current_ptr;
|
||||
}
|
||||
--_size;
|
||||
// Prepend this item to the removed list
|
||||
current->next = removed;
|
||||
removed = current;
|
||||
// do not advance current_ptr
|
||||
} else {
|
||||
// advance current_ptr
|
||||
current_ptr = &(*current_ptr)->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the removed entries
|
||||
return removed;
|
||||
}
|
||||
|
||||
inline value_ptr_type begin() const {
|
||||
return _head;
|
||||
}
|
||||
|
||||
bool validate_tail() const {
|
||||
if (_head == nullptr) {
|
||||
return (_tail == &_head);
|
||||
}
|
||||
auto p = _head;
|
||||
while (p->next != nullptr) {
|
||||
p = p->next;
|
||||
}
|
||||
return _tail == &p->next;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
value_ptr_type _head;
|
||||
value_ptr_ptr_type _tail;
|
||||
size_t _size;
|
||||
|
||||
}; // class simple_intrusive_list
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Major version number (X.x.x) */
|
||||
#define ASYNCTCP_VERSION_MAJOR 3
|
||||
/** Minor version number (x.X.x) */
|
||||
#define ASYNCTCP_VERSION_MINOR 4
|
||||
/** Patch version number (x.x.X) */
|
||||
#define ASYNCTCP_VERSION_PATCH 9
|
||||
|
||||
/**
|
||||
* Macro to convert version number into an integer
|
||||
*
|
||||
* To be used in comparisons, such as ASYNCTCP_VERSION >= ASYNCTCP_VERSION_VAL(2, 0, 0)
|
||||
*/
|
||||
#define ASYNCTCP_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
|
||||
|
||||
/**
|
||||
* Current version, as an integer
|
||||
*
|
||||
* To be used in comparisons, such as ASYNCTCP_VERSION_NUM >= ASYNCTCP_VERSION_VAL(2, 0, 0)
|
||||
*/
|
||||
#define ASYNCTCP_VERSION_NUM ASYNCTCP_VERSION_VAL(ASYNCTCP_VERSION_MAJOR, ASYNCTCP_VERSION_MINOR, ASYNCTCP_VERSION_PATCH)
|
||||
|
||||
/**
|
||||
* Current version, as string
|
||||
*/
|
||||
#define df2xstr(s) #s
|
||||
#define df2str(s) df2xstr(s)
|
||||
#define ASYNCTCP_VERSION df2str(ASYNCTCP_VERSION_MAJOR) "." df2str(ASYNCTCP_VERSION_MINOR) "." df2str(ASYNCTCP_VERSION_PATCH)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user