Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions library.json
Original file line number Diff line number Diff line change
@@ -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
}
Expand Down
70 changes: 48 additions & 22 deletions src/AsyncTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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){
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -870,7 +877,6 @@ int8_t AsyncClient::_connected(void* pcb, int8_t err){
_pcb = reinterpret_cast<tcp_pcb*>(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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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(){
Expand Down Expand Up @@ -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() {
Expand All @@ -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() {
Expand Down Expand Up @@ -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) {
Expand Down
22 changes: 18 additions & 4 deletions src/AsyncTCP.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,33 @@
#define ASYNCTCP_H_

#include "IPAddress.h"
#include "sdkconfig.h"
#include <functional>

#ifndef LIBRETINY
#include "sdkconfig.h"
extern "C" {
#include "freertos/semphr.h"
#include "lwip/pbuf.h"
}
#else
extern "C" {
#include <semphr.h>
#include <lwip/pbuf.h>
}
#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

class AsyncClient;

#define ASYNC_MAX_ACK_TIME 5000
Expand Down Expand Up @@ -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;

Expand Down