diff --git a/library.json b/library.json index c5e1f447..957bd197 100644 --- a/library.json +++ b/library.json @@ -1,21 +1,19 @@ { - "name":"AsyncTCP-esphome", - "description":"Asynchronous TCP Library for ESP32", - "keywords":"async,tcp", - "authors": - { + "name": "AsyncTCP-esphome", + "description": "Asynchronous TCP Library for ESP32", + "keywords": "async,tcp", + "authors": { "name": "Hristo Gochkov", "maintainer": true }, - "repository": - { + "repository": { "type": "git", - "url": "https://github.com/OttoWinter/AsyncTCP.git" + "url": "https://github.com/esphome/AsyncTCP.git" }, - "version": "1.2.1", + "version": "2.0.1", "license": "LGPL-3.0", "frameworks": "arduino", - "platforms": "espressif32", + "platforms": ["espressif32", "libretiny"], "build": { "libCompatMode": 2 } diff --git a/src/AsyncTCP.cpp b/src/AsyncTCP.cpp index 471e8fcf..ff82593b 100644 --- a/src/AsyncTCP.cpp +++ b/src/AsyncTCP.cpp @@ -29,7 +29,9 @@ extern "C"{ #include "lwip/dns.h" #include "lwip/err.h" } +#if CONFIG_ASYNC_TCP_USE_WDT #include "esp_task_wdt.h" +#endif /* * TCP/IP Event Task @@ -238,7 +240,7 @@ static bool _start_async_task(){ return false; } if(!_async_service_task_handle){ - customTaskCreateUniversal(_async_service_task, "async_tcp", 8192 * 2, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); + customTaskCreateUniversal(_async_service_task, "async_tcp", CONFIG_ASYNC_TCP_STACK_SIZE, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); if(!_async_service_task_handle){ return false; } @@ -575,11 +577,10 @@ AsyncClient::AsyncClient(tcp_pcb* pcb) , _pb_cb_arg(0) , _timeout_cb(0) , _timeout_cb_arg(0) -, _pcb_busy(0) -, _pcb_sent_at(0) , _ack_pcb(true) -, _rx_last_packet(0) -, _rx_since_timeout(0) +, _tx_last_packet(0) +, _rx_timeout(0) +, _rx_last_ack(0) , _ack_timeout(ASYNC_MAX_ACK_TIME) , _connect_port(0) , prev(NULL) @@ -705,8 +706,12 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){ } ip_addr_t addr; +#if LWIP_IPV4 && LWIP_IPV6 addr.type = IPADDR_TYPE_V4; addr.u_addr.ip4.addr = ip; +#else + addr.addr = ip; +#endif tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4); if (!pcb){ @@ -734,7 +739,11 @@ bool AsyncClient::connect(const char* host, uint16_t port){ err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this); if(err == ERR_OK) { +#if LWIP_IPV4 && LWIP_IPV6 return connect(IPAddress(addr.u_addr.ip4.addr), port); +#else + return connect(IPAddress(addr.addr), port); +#endif } else if(err == ERR_INPROGRESS) { _connect_port = port; return true; @@ -783,14 +792,12 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) { } bool AsyncClient::send(){ - auto pcb_sent_at_backup = _pcb_sent_at; - _pcb_sent_at = millis(); - _pcb_busy++; + auto backup = _tx_last_packet; + _tx_last_packet = millis(); if (_tcp_output(_pcb, _closed_slot) == ERR_OK) { return true; } - _pcb_sent_at = pcb_sent_at_backup; - _pcb_busy--; + _tx_last_packet = backup; return false; } @@ -870,7 +877,6 @@ int8_t AsyncClient::_connected(void* pcb, int8_t err){ _pcb = reinterpret_cast(pcb); if(_pcb){ _rx_last_packet = millis(); - _pcb_busy = 0; // tcp_recv(_pcb, &_tcp_recv); // tcp_sent(_pcb, &_tcp_sent); // tcp_poll(_pcb, &_tcp_poll, 1); @@ -932,10 +938,10 @@ int8_t AsyncClient::_fin(tcp_pcb* pcb, int8_t err) { int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) { _rx_last_packet = millis(); + _rx_last_ack = millis(); //log_i("%u", len); - _pcb_busy--; if(_sent_cb) { - _sent_cb(_sent_cb_arg, this, len, (millis() - _pcb_sent_at)); + _sent_cb(_sent_cb_arg, this, len, (millis() - _tx_last_packet)); } return ERR_OK; } @@ -978,15 +984,18 @@ int8_t AsyncClient::_poll(tcp_pcb* pcb){ uint32_t now = millis(); // ACK Timeout - if(_pcb_busy > 0 && _ack_timeout && (now - _pcb_sent_at) >= _ack_timeout){ - _pcb_busy = 0; - log_w("ack timeout %d", pcb->state); - if(_timeout_cb) - _timeout_cb(_timeout_cb_arg, this, (now - _pcb_sent_at)); - return ERR_OK; + 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_w("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_since_timeout && (now - _rx_last_packet) >= (_rx_since_timeout * 1000)){ + if(_rx_timeout && (now - _rx_last_packet) >= (_rx_timeout * 1000)) { log_w("rx timeout %d", pcb->state); _close(); return ERR_OK; @@ -999,8 +1008,13 @@ int8_t AsyncClient::_poll(tcp_pcb* pcb){ } void AsyncClient::_dns_found(struct ip_addr *ipaddr){ +#if LWIP_IPV4 && LWIP_IPV6 if(ipaddr && ipaddr->u_addr.ip4.addr){ connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port); +#else + if (ipaddr && ipaddr->addr){ + connect(IPAddress(ipaddr->addr), _connect_port); +#endif } else { if(_error_cb) { _error_cb(_error_cb_arg, this, -55); @@ -1045,11 +1059,11 @@ size_t AsyncClient::write(const char* data, size_t size, uint8_t apiflags) { } void AsyncClient::setRxTimeout(uint32_t timeout){ - _rx_since_timeout = timeout; + _rx_timeout = timeout; } uint32_t AsyncClient::getRxTimeout(){ - return _rx_since_timeout; + return _rx_timeout; } uint32_t AsyncClient::getAckTimeout(){ @@ -1089,7 +1103,11 @@ 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 } uint16_t AsyncClient::getRemotePort() { @@ -1103,7 +1121,11 @@ 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() { @@ -1299,8 +1321,12 @@ void AsyncServer::begin(){ } ip_addr_t local_addr; +#if LWIP_IPV4 && LWIP_IPV6 local_addr.type = IPADDR_TYPE_V4; local_addr.u_addr.ip4.addr = (uint32_t) _addr; +#else + local_addr.addr = (uint32_t) _addr; +#endif err = _tcp_bind(_pcb, &local_addr, _port); if (err != ERR_OK) { diff --git a/src/AsyncTCP.h b/src/AsyncTCP.h index fcd511bb..1e781b37 100644 --- a/src/AsyncTCP.h +++ b/src/AsyncTCP.h @@ -23,12 +23,22 @@ #define ASYNCTCP_H_ #include "IPAddress.h" -#include "sdkconfig.h" #include + +#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 @@ -36,6 +46,10 @@ extern "C" { #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 + class AsyncClient; #define ASYNC_MAX_ACK_TIME 5000 @@ -160,12 +174,12 @@ class AsyncClient { AcConnectHandler _poll_cb; void* _poll_cb_arg; - uint32_t _pcb_busy; - uint32_t _pcb_sent_at; bool _ack_pcb; + uint32_t _tx_last_packet; uint32_t _rx_ack_len; uint32_t _rx_last_packet; - uint32_t _rx_since_timeout; + uint32_t _rx_timeout; + uint32_t _rx_last_ack; uint32_t _ack_timeout; uint16_t _connect_port;