diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dcc560e3..f86d7f7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,6 +78,11 @@ jobs: - env: ci-arduino-3-latest board: esp32-c6-devkitc-1 + - env: ci-arduino-libretiny + board: generic-bk7231n-qfn32-tuya + - env: ci-arduino-libretiny + board: generic-rtl8710bn-2mb-788k + steps: - name: Checkout uses: actions/checkout@v4 diff --git a/platformio.ini b/platformio.ini index 5ae31c8b..689e6a0f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -43,3 +43,12 @@ board = ${sysenv.PIO_BOARD} [env:ci-arduino-3-latest] platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20-rc2/platform-espressif32.zip board = ${sysenv.PIO_BOARD} + +[env:ci-arduino-libretiny] +platform = libretiny +board = ${sysenv.PIO_BOARD} +build_flags = + ${env.build_flags} + -Wno-unused-parameter + -Wno-unused-variable + -Wno-missing-field-initializers diff --git a/src/AsyncTCP.cpp b/src/AsyncTCP.cpp index 011318ae..e9839e72 100644 --- a/src/AsyncTCP.cpp +++ b/src/AsyncTCP.cpp @@ -3,6 +3,7 @@ #include "AsyncTCP.h" +#ifndef LIBRETINY #include #ifdef ARDUINO @@ -22,6 +23,18 @@ static unsigned long millis() { return (unsigned long)(esp_timer_get_time() / 1000ULL); } #endif +#endif + +#ifdef LIBRETINY +#include +// LibreTiny does not support IDF - disable code that expects it to be available +#define ESP_IDF_VERSION_MAJOR (0) +// xTaskCreatePinnedToCore is not available, force single-core operation +#define CONFIG_FREERTOS_UNICORE 1 +// ESP watchdog is not available +#undef CONFIG_ASYNC_TCP_USE_WDT +#define CONFIG_ASYNC_TCP_USE_WDT 0 +#endif extern "C" { #include "lwip/dns.h" @@ -837,7 +850,11 @@ bool AsyncClient::connect(ip_addr_t addr, uint16_t port) { tcp_pcb *pcb; { tcp_core_guard tcg; +#if LWIP_IPV4 && LWIP_IPV6 pcb = tcp_new_ip_type(addr.type); +#else + pcb = tcp_new_ip_type(IPADDR_TYPE_V4); +#endif if (!pcb) { log_e("pcb == NULL"); return false; @@ -857,8 +874,13 @@ bool AsyncClient::connect(ip_addr_t addr, uint16_t port) { bool AsyncClient::connect(const IPAddress &ip, uint16_t port) { ip_addr_t addr; #if ESP_IDF_VERSION_MAJOR < 5 +#if LWIP_IPV4 && LWIP_IPV6 + // if both IPv4 and IPv6 are enabled, ip_addr_t has a union field and the address type addr.u_addr.ip4.addr = ip; addr.type = IPADDR_TYPE_V4; +#else + addr.addr = ip; +#endif #else ip.to_ip_addr_t(&addr); #endif @@ -1343,9 +1365,16 @@ uint16_t AsyncClient::getLocalPort() const { } ip4_addr_t AsyncClient::getRemoteAddress4() const { +#if LWIP_IPV4 && LWIP_IPV6 if (_pcb && _pcb->remote_ip.type == IPADDR_TYPE_V4) { return _pcb->remote_ip.u_addr.ip4; - } else { + } +#else + if (_pcb) { + return _pcb->remote_ip; + } +#endif + else { ip4_addr_t nulladdr; ip4_addr_set_zero(&nulladdr); return nulladdr; @@ -1353,9 +1382,16 @@ ip4_addr_t AsyncClient::getRemoteAddress4() const { } ip4_addr_t AsyncClient::getLocalAddress4() const { +#if LWIP_IPV4 && LWIP_IPV6 if (_pcb && _pcb->local_ip.type == IPADDR_TYPE_V4) { return _pcb->local_ip.u_addr.ip4; - } else { + } +#else + if (_pcb) { + return _pcb->local_ip; + } +#endif + else { ip4_addr_t nulladdr; ip4_addr_set_zero(&nulladdr); return nulladdr; @@ -1486,15 +1522,21 @@ AsyncServer::AsyncServer(ip_addr_t addr, uint16_t port) #ifdef ARDUINO AsyncServer::AsyncServer(IPAddress addr, uint16_t port) : _port(port), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) { #if ESP_IDF_VERSION_MAJOR < 5 +#if LWIP_IPV4 && LWIP_IPV6 _addr.type = IPADDR_TYPE_V4; _addr.u_addr.ip4.addr = addr; +#else + _addr.addr = addr; +#endif #else addr.to_ip_addr_t(&_addr); #endif } -#if ESP_IDF_VERSION_MAJOR < 5 +#if ESP_IDF_VERSION_MAJOR < 5 && __has_include() && LWIP_IPV6 AsyncServer::AsyncServer(IPv6Address addr, uint16_t port) : _port(port), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) { +#if LWIP_IPV4 && LWIP_IPV6 _addr.type = IPADDR_TYPE_V6; +#endif auto ipaddr = static_cast(addr); _addr = IPADDR6_INIT(ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); } @@ -1502,8 +1544,12 @@ AsyncServer::AsyncServer(IPv6Address addr, uint16_t port) : _port(port), _noDela #endif AsyncServer::AsyncServer(uint16_t port) : _port(port), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) { +#if LWIP_IPV4 && LWIP_IPV6 _addr.type = IPADDR_TYPE_ANY; _addr.u_addr.ip4.addr = INADDR_ANY; +#else + _addr.addr = INADDR_ANY; +#endif } AsyncServer::~AsyncServer() { @@ -1527,7 +1573,11 @@ void AsyncServer::begin() { int8_t err; { tcp_core_guard tcg; +#if LWIP_IPV4 && LWIP_IPV6 _pcb = tcp_new_ip_type(_addr.type); +#else + _pcb = tcp_new_ip_type(IPADDR_TYPE_ANY); +#endif } if (!_pcb) { log_e("_pcb == NULL"); diff --git a/src/AsyncTCP.h b/src/AsyncTCP.h index 0bc7b9df..9d098734 100644 --- a/src/AsyncTCP.h +++ b/src/AsyncTCP.h @@ -7,7 +7,9 @@ #include "AsyncTCPVersion.h" #define ASYNCTCP_FORK_ESP32Async +#ifndef LIBRETINY #include +#endif #ifdef ARDUINO #include "IPAddress.h" @@ -29,9 +31,9 @@ extern "C" { #else extern "C" { #include +#include #include } -#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 // any available core #endif // If core is not defined, then we are running in Arduino or PIO