Skip to content

Commit 5acacfc

Browse files
gnalbandianmathieucarbou
authored andcommitted
Adapt library for compatibility with both ESP-IDF and Arduino framework
- Added preprocessor macros to detect and separate ESP-IDF vs Arduino
1 parent cca8bec commit 5acacfc

File tree

6 files changed

+110
-90
lines changed

6 files changed

+110
-90
lines changed

CMakeLists.txt

-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ set(COMPONENT_ADD_INCLUDEDIRS
66
"src"
77
)
88

9-
set(COMPONENT_REQUIRES
10-
"arduino-esp32"
11-
)
12-
139
register_component()
1410

1511
target_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti)

idf_component.yml

-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
description: "Async TCP Library for ESP32 Arduino"
22
url: "https://github.com/ESP32Async/AsyncTCP"
33
license: "LGPL-3.0-or-later"
4-
tags:
5-
- arduino
64
files:
75
exclude:
86
- "idf_component_examples/"
@@ -24,9 +22,5 @@ files:
2422
- "library.properties"
2523
- "platformio.ini"
2624
- "pre-commit.requirements.txt"
27-
dependencies:
28-
espressif/arduino-esp32:
29-
version: "^3.1.1"
30-
require: public
3125
examples:
3226
- path: ./idf_component_examples/client
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
idf_component_register(SRCS "main.cpp"
2-
INCLUDE_DIRS ".")
2+
INCLUDE_DIRS "."
3+
PRIV_REQUIRES esp_timer)

idf_component_examples/client/main/idf_component.yml

+3
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ dependencies:
44
version: "*"
55
override_path: "../../../"
66
pre_release: true
7+
espressif/arduino-esp32:
8+
version: ">=3.0.5"
9+
require: public

src/AsyncTCP.cpp

+78-68
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
11
// SPDX-License-Identifier: LGPL-3.0-or-later
22
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
33

4-
#include "Arduino.h"
5-
64
#include "AsyncTCP.h"
75

6+
#include <esp_log.h>
7+
8+
#ifdef ARDUINO
9+
#include <esp32-hal.h>
10+
#include <esp32-hal-log.h>
11+
#if (ESP_IDF_VERSION_MAJOR >= 5)
12+
#include <NetworkInterface.h>
13+
#endif
14+
#else
15+
#include "esp_timer.h"
16+
#define log_e(...) ESP_LOGE(__FILE__, __VA_ARGS__)
17+
#define log_w(...) ESP_LOGW(__FILE__, __VA_ARGS__)
18+
#define log_i(...) ESP_LOGI(__FILE__, __VA_ARGS__)
19+
#define log_d(...) ESP_LOGD(__FILE__, __VA_ARGS__)
20+
#define log_v(...) ESP_LOGV(__FILE__, __VA_ARGS__)
21+
static unsigned long millis() {
22+
return (unsigned long)(esp_timer_get_time() / 1000ULL);
23+
}
24+
#endif
25+
826
extern "C" {
927
#include "lwip/dns.h"
1028
#include "lwip/err.h"
@@ -19,9 +37,6 @@ extern "C" {
1937

2038
// Required for:
2139
// https://github.com/espressif/arduino-esp32/blob/3.0.3/libraries/Network/src/NetworkInterface.cpp#L37-L47
22-
#if ESP_IDF_VERSION_MAJOR >= 5
23-
#include <NetworkInterface.h>
24-
#endif
2540

2641
// https://github.com/espressif/arduino-esp32/issues/10526
2742
#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING
@@ -829,7 +844,7 @@ void AsyncClient::onPoll(AcConnectHandler cb, void *arg) {
829844
* Main Public Methods
830845
* */
831846

832-
bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) {
847+
bool AsyncClient::connect(ip_addr_t addr, uint16_t port) {
833848
if (_pcb) {
834849
log_d("already connected, state %d", _pcb->state);
835850
return false;
@@ -862,6 +877,7 @@ bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) {
862877
return err == ESP_OK;
863878
}
864879

880+
#ifdef ARDUINO
865881
bool AsyncClient::connect(const IPAddress &ip, uint16_t port) {
866882
ip_addr_t addr;
867883
#if ESP_IDF_VERSION_MAJOR < 5
@@ -871,15 +887,16 @@ bool AsyncClient::connect(const IPAddress &ip, uint16_t port) {
871887
ip.to_ip_addr_t(&addr);
872888
#endif
873889

874-
return _connect(addr, port);
890+
return connect(addr, port);
875891
}
892+
#endif
876893

877894
#if LWIP_IPV6 && ESP_IDF_VERSION_MAJOR < 5
878895
bool AsyncClient::connect(const IPv6Address &ip, uint16_t port) {
879896
auto ipaddr = static_cast<const uint32_t *>(ip);
880897
ip_addr_t addr = IPADDR6_INIT(ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
881898

882-
return _connect(addr, port);
899+
return connect(addr, port);
883900
}
884901
#endif
885902

@@ -905,7 +922,7 @@ bool AsyncClient::connect(const char *host, uint16_t port) {
905922
return connect(IPAddress(addr.addr), port);
906923
#endif
907924
#else
908-
return _connect(addr, port);
925+
return connect(addr, port);
909926
#endif
910927
} else if (err == ERR_INPROGRESS) {
911928
_connect_port = port;
@@ -1073,7 +1090,7 @@ void AsyncClient::_error(int8_t err) {
10731090
// In LwIP Thread
10741091
int8_t AsyncClient::_lwip_fin(tcp_pcb *pcb, int8_t err) {
10751092
if (!_pcb || pcb != _pcb) {
1076-
log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
1093+
log_d("0x%08" PRIx32 " != 0x%08" PRIx32, (uint32_t)pcb, (uint32_t)_pcb);
10771094
return ERR_OK;
10781095
}
10791096
tcp_arg(_pcb, NULL);
@@ -1139,7 +1156,7 @@ int8_t AsyncClient::_poll(tcp_pcb *pcb) {
11391156
return ERR_OK;
11401157
}
11411158
if (pcb != _pcb) {
1142-
log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
1159+
log_d("0x%08" PRIx32 " != 0x%08" PRIx32, (uint32_t)pcb, (uint32_t)_pcb);
11431160
return ERR_OK;
11441161
}
11451162

@@ -1171,19 +1188,8 @@ int8_t AsyncClient::_poll(tcp_pcb *pcb) {
11711188
}
11721189

11731190
void AsyncClient::_dns_found(struct ip_addr *ipaddr) {
1174-
#if ESP_IDF_VERSION_MAJOR < 5
1175-
if (ipaddr && IP_IS_V4(ipaddr)) {
1176-
connect(IPAddress(ip_addr_get_ip4_u32(ipaddr)), _connect_port);
1177-
#if LWIP_IPV6
1178-
} else if (ipaddr && ipaddr->u_addr.ip6.addr) {
1179-
connect(IPv6Address(ipaddr->u_addr.ip6.addr), _connect_port);
1180-
#endif
1181-
#else
11821191
if (ipaddr) {
1183-
IPAddress ip;
1184-
ip.from_ip_addr_t(ipaddr);
1185-
connect(ip, _connect_port);
1186-
#endif
1192+
connect(*ipaddr, _connect_port);
11871193
} else {
11881194
if (_error_cb) {
11891195
_error_cb(_error_cb_arg, this, -55);
@@ -1282,22 +1288,25 @@ uint32_t AsyncClient::getRemoteAddress() const {
12821288

12831289
#if LWIP_IPV6
12841290
ip6_addr_t AsyncClient::getRemoteAddress6() const {
1285-
if (!_pcb) {
1291+
if (_pcb && _pcb->remote_ip.type == IPADDR_TYPE_V6) {
1292+
return _pcb->remote_ip.u_addr.ip6;
1293+
} else {
12861294
ip6_addr_t nulladdr;
12871295
ip6_addr_set_zero(&nulladdr);
12881296
return nulladdr;
12891297
}
1290-
return _pcb->remote_ip.u_addr.ip6;
12911298
}
12921299

12931300
ip6_addr_t AsyncClient::getLocalAddress6() const {
1294-
if (!_pcb) {
1301+
if (_pcb && _pcb->local_ip.type == IPADDR_TYPE_V6) {
1302+
return _pcb->local_ip.u_addr.ip6;
1303+
} else {
12951304
ip6_addr_t nulladdr;
12961305
ip6_addr_set_zero(&nulladdr);
12971306
return nulladdr;
12981307
}
1299-
return _pcb->local_ip.u_addr.ip6;
13001308
}
1309+
#ifdef ARDUINO
13011310
#if ESP_IDF_VERSION_MAJOR < 5
13021311
IPv6Address AsyncClient::remoteIP6() const {
13031312
return IPv6Address(getRemoteAddress6().addr);
@@ -1326,6 +1335,7 @@ IPAddress AsyncClient::localIP6() const {
13261335
}
13271336
#endif
13281337
#endif
1338+
#endif
13291339

13301340
uint16_t AsyncClient::getRemotePort() const {
13311341
if (!_pcb) {
@@ -1352,6 +1362,27 @@ uint16_t AsyncClient::getLocalPort() const {
13521362
return _pcb->local_port;
13531363
}
13541364

1365+
ip4_addr_t AsyncClient::getRemoteAddress4() const {
1366+
if (_pcb && _pcb->remote_ip.type == IPADDR_TYPE_V4) {
1367+
return _pcb->remote_ip.u_addr.ip4;
1368+
} else {
1369+
ip4_addr_t nulladdr;
1370+
ip4_addr_set_zero(&nulladdr);
1371+
return nulladdr;
1372+
}
1373+
}
1374+
1375+
ip4_addr_t AsyncClient::getLocalAddress4() const {
1376+
if (_pcb && _pcb->local_ip.type == IPADDR_TYPE_V4) {
1377+
return _pcb->local_ip.u_addr.ip4;
1378+
} else {
1379+
ip4_addr_t nulladdr;
1380+
ip4_addr_set_zero(&nulladdr);
1381+
return nulladdr;
1382+
}
1383+
}
1384+
1385+
#ifdef ARDUINO
13551386
IPAddress AsyncClient::remoteIP() const {
13561387
#if ESP_IDF_VERSION_MAJOR < 5
13571388
return IPAddress(getRemoteAddress());
@@ -1365,10 +1396,6 @@ IPAddress AsyncClient::remoteIP() const {
13651396
#endif
13661397
}
13671398

1368-
uint16_t AsyncClient::remotePort() const {
1369-
return getRemotePort();
1370-
}
1371-
13721399
IPAddress AsyncClient::localIP() const {
13731400
#if ESP_IDF_VERSION_MAJOR < 5
13741401
return IPAddress(getLocalAddress());
@@ -1381,10 +1408,7 @@ IPAddress AsyncClient::localIP() const {
13811408
return ip;
13821409
#endif
13831410
}
1384-
1385-
uint16_t AsyncClient::localPort() const {
1386-
return getLocalPort();
1387-
}
1411+
#endif
13881412

13891413
uint8_t AsyncClient::state() const {
13901414
if (!_pcb) {
@@ -1512,32 +1536,30 @@ int8_t AsyncClient::_s_connected(void *arg, struct tcp_pcb *pcb, int8_t err) {
15121536
Async TCP Server
15131537
*/
15141538

1515-
AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
1516-
: _port(port)
1539+
AsyncServer::AsyncServer(ip_addr_t addr, uint16_t port)
1540+
: _port(port), _addr(addr), _noDelay(false), _pcb(nullptr), _connect_cb(nullptr), _connect_cb_arg(nullptr) {}
1541+
1542+
#ifdef ARDUINO
1543+
AsyncServer::AsyncServer(IPAddress addr, uint16_t port) : _port(port), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) {
15171544
#if ESP_IDF_VERSION_MAJOR < 5
1518-
,
1519-
_bind4(true), _bind6(false)
1545+
_addr.type = IPADDR_TYPE_V4;
1546+
_addr.u_addr.ip4.addr = addr;
15201547
#else
1521-
,
1522-
_bind4(addr.type() != IPType::IPv6), _bind6(addr.type() == IPType::IPv6)
1548+
addr.to_ip_addr_t(&_addr);
15231549
#endif
1524-
,
1525-
_addr(addr), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) {
15261550
}
1527-
15281551
#if ESP_IDF_VERSION_MAJOR < 5
1529-
AsyncServer::AsyncServer(IPv6Address addr, uint16_t port)
1530-
: _port(port), _bind4(false), _bind6(true), _addr6(addr), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) {}
1552+
AsyncServer::AsyncServer(IPv6Address addr, uint16_t port) : _port(port), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) {
1553+
_addr.type = IPADDR_TYPE_V6;
1554+
auto ipaddr = static_cast<const uint32_t *>(addr);
1555+
_addr = IPADDR6_INIT(ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
1556+
}
15311557
#endif
1532-
1533-
AsyncServer::AsyncServer(uint16_t port)
1534-
: _port(port), _bind4(true), _bind6(false), _addr((uint32_t)IPADDR_ANY)
1535-
#if ESP_IDF_VERSION_MAJOR < 5
1536-
,
1537-
_addr6()
15381558
#endif
1539-
,
1540-
_noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) {
1559+
1560+
AsyncServer::AsyncServer(uint16_t port) : _port(port), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) {
1561+
_addr.type = IPADDR_TYPE_V4;
1562+
_addr.u_addr.ip4.addr = INADDR_ANY;
15411563
}
15421564

15431565
AsyncServer::~AsyncServer() {
@@ -1560,26 +1582,14 @@ void AsyncServer::begin() {
15601582
}
15611583
int8_t err;
15621584
TCP_MUTEX_LOCK();
1563-
_pcb = tcp_new_ip_type(_bind4 && _bind6 ? IPADDR_TYPE_ANY : (_bind6 ? IPADDR_TYPE_V6 : IPADDR_TYPE_V4));
1585+
_pcb = tcp_new_ip_type(_addr.type);
15641586
TCP_MUTEX_UNLOCK();
15651587
if (!_pcb) {
15661588
log_e("_pcb == NULL");
15671589
return;
15681590
}
15691591

1570-
ip_addr_t local_addr;
1571-
#if ESP_IDF_VERSION_MAJOR < 5
1572-
if (_bind6) { // _bind6 && _bind4 both at the same time is not supported on Arduino 2 in this lib API
1573-
local_addr.type = IPADDR_TYPE_V6;
1574-
memcpy(local_addr.u_addr.ip6.addr, static_cast<const uint32_t *>(_addr6), sizeof(uint32_t) * 4);
1575-
} else {
1576-
local_addr.type = IPADDR_TYPE_V4;
1577-
local_addr.u_addr.ip4.addr = _addr;
1578-
}
1579-
#else
1580-
_addr.to_ip_addr_t(&local_addr);
1581-
#endif
1582-
err = _tcp_bind(_pcb, &local_addr, _port);
1592+
err = _tcp_bind(_pcb, &_addr, _port);
15831593

15841594
if (err != ERR_OK) {
15851595
_tcp_close(_pcb, -1);

0 commit comments

Comments
 (0)