update asyncTCP to threadsafe 3.2.14, ems-esp v3.7.2-dev.4

This commit is contained in:
MichaelDvP
2024-12-05 12:52:29 +01:00
parent 5ec0f657a0
commit 5f42709eab
4 changed files with 183 additions and 96 deletions

View File

@@ -8,6 +8,7 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
- change enum_heatingtype for remote control [#2268](https://github.com/emsesp/EMS-ESP32/issues/2268)
- system service commands [#2182](https://github.com/emsesp/EMS-ESP32/issues/2282)
- read 0x02A5 for thermostat CT200 [#2277](https://github.com/emsesp/EMS-ESP32/issues/2277)
## Fixed
@@ -19,3 +20,4 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
- show operation in pretty telegram between src and dst [#2263](https://github.com/emsesp/EMS-ESP32/discussions/2263)
- update eModbus to 1.7.2 [#2254](https://github.com/emsesp/EMS-ESP32/issues/2254)
- modbus timeout default to 300 sec, change setting from ms to sec [#2254](https://github.com/emsesp/EMS-ESP32/issues/2254)
- update AsyncTCP to v3.2.14

View File

@@ -33,6 +33,32 @@ extern "C" {
#include "esp_task_wdt.h"
#endif
// Required for:
// https://github.com/espressif/arduino-esp32/blob/3.0.3/libraries/Network/src/NetworkInterface.cpp#L37-L47
#if ESP_IDF_VERSION_MAJOR >= 5
// #include <NetworkInterface.h>
#endif
#define TAG "AsyncTCP"
// https://github.com/espressif/arduino-esp32/issues/10526
#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING
#define TCP_MUTEX_LOCK() \
if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \
LOCK_TCPIP_CORE(); \
}
#define TCP_MUTEX_UNLOCK() \
if (sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \
UNLOCK_TCPIP_CORE(); \
}
#else // CONFIG_LWIP_TCPIP_CORE_LOCKING
#define TCP_MUTEX_LOCK()
#define TCP_MUTEX_UNLOCK()
#endif // CONFIG_LWIP_TCPIP_CORE_LOCKING
#define INVALID_CLOSED_SLOT -1
/*
* TCP/IP Event Task
* */
@@ -54,8 +80,8 @@ typedef struct {
void * arg;
union {
struct {
void * pcb;
int8_t err;
tcp_pcb * pcb;
int8_t err;
} connected;
struct {
int8_t err;
@@ -105,8 +131,7 @@ static uint32_t _closed_index = []() {
static inline bool _init_async_event_queue() {
if (!_async_queue) {
_async_queue =
xQueueCreate(CONFIG_ASYNC_TCP_QUEUE, sizeof(lwip_event_packet_t *)); // double queue to 128 see https://github.com/emsesp/EMS-ESP32/issues/177
_async_queue = xQueueCreate(CONFIG_ASYNC_TCP_QUEUE_SIZE, sizeof(lwip_event_packet_t *));
if (!_async_queue) {
return false;
}
@@ -252,7 +277,7 @@ static bool _start_async_task() {
"async_tcp",
CONFIG_ASYNC_TCP_STACK_SIZE,
NULL,
CONFIG_ASYNC_TCP_TASK_PRIORITY,
CONFIG_ASYNC_TCP_PRIORITY,
&_async_service_task_handle,
CONFIG_ASYNC_TCP_RUNNING_CORE);
if (!_async_service_task_handle) {
@@ -410,7 +435,7 @@ typedef struct {
static err_t _tcp_output_api(struct tcpip_api_call_data * api_call_msg) {
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
msg->err = ERR_CONN;
if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) {
msg->err = tcp_output(msg->pcb);
}
return msg->err;
@@ -430,7 +455,7 @@ static esp_err_t _tcp_output(tcp_pcb * pcb, int8_t closed_slot) {
static err_t _tcp_write_api(struct tcpip_api_call_data * api_call_msg) {
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
msg->err = ERR_CONN;
if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) {
msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags);
}
return msg->err;
@@ -453,7 +478,9 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, int8_t closed_slot, const char * data
static err_t _tcp_recved_api(struct tcpip_api_call_data * api_call_msg) {
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
msg->err = ERR_CONN;
if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) {
// if(msg->closed_slot != INVALID_CLOSED_SLOT && !_closed_slots[msg->closed_slot]) {
// if(msg->closed_slot != INVALID_CLOSED_SLOT) {
msg->err = 0;
tcp_recved(msg->pcb, msg->received);
}
@@ -475,7 +502,7 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, int8_t closed_slot, size_t len) {
static err_t _tcp_close_api(struct tcpip_api_call_data * api_call_msg) {
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
msg->err = ERR_CONN;
if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) {
msg->err = tcp_close(msg->pcb);
}
return msg->err;
@@ -495,7 +522,7 @@ static esp_err_t _tcp_close(tcp_pcb * pcb, int8_t closed_slot) {
static err_t _tcp_abort_api(struct tcpip_api_call_data * api_call_msg) {
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
msg->err = ERR_CONN;
if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) {
tcp_abort(msg->pcb);
}
return msg->err;
@@ -595,20 +622,22 @@ AsyncClient::AsyncClient(tcp_pcb * pcb)
, _tx_last_packet(0)
, _rx_timeout(0)
, _rx_last_ack(0)
, _ack_timeout(ASYNC_MAX_ACK_TIME)
, _ack_timeout(CONFIG_ASYNC_TCP_MAX_ACK_TIME)
, _connect_port(0)
, prev(NULL)
, next(NULL) {
_pcb = pcb;
_closed_slot = -1;
_closed_slot = INVALID_CLOSED_SLOT;
if (_pcb) {
_allocate_closed_slot();
_rx_last_packet = millis();
tcp_arg(_pcb, this);
tcp_recv(_pcb, &_tcp_recv);
tcp_sent(_pcb, &_tcp_sent);
tcp_err(_pcb, &_tcp_error);
tcp_poll(_pcb, &_tcp_poll, 1);
if (!_allocate_closed_slot()) {
_close();
}
}
}
@@ -710,7 +739,7 @@ void AsyncClient::onPoll(AcConnectHandler cb, void * arg) {
bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) {
if (_pcb) {
log_w("already connected, state %d", _pcb->state);
log_d("already connected, state %d", _pcb->state);
return false;
}
if (!_start_async_task()) {
@@ -718,28 +747,34 @@ bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) {
return false;
}
tcp_pcb * pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
if (!pcb) {
log_e("pcb == NULL");
if (!_allocate_closed_slot()) {
log_e("failed to allocate: closed slot full");
return false;
}
TCP_MUTEX_LOCK();
tcp_pcb * pcb = tcp_new_ip_type(addr.type);
if (!pcb) {
TCP_MUTEX_UNLOCK();
log_e("pcb == NULL");
return false;
}
tcp_arg(pcb, this);
tcp_err(pcb, &_tcp_error);
tcp_recv(pcb, &_tcp_recv);
tcp_sent(pcb, &_tcp_sent);
tcp_poll(pcb, &_tcp_poll, 1);
_tcp_connect(pcb, _closed_slot, &addr, port, (tcp_connected_fn)&_tcp_connected);
return true;
TCP_MUTEX_UNLOCK();
esp_err_t err = _tcp_connect(pcb, _closed_slot, &addr, port, (tcp_connected_fn)&_tcp_connected);
return err == ESP_OK;
}
bool AsyncClient::connect(IPAddress ip, uint16_t port) {
bool AsyncClient::connect(const IPAddress & ip, uint16_t port) {
ip_addr_t addr;
#if ESP_IDF_VERSION_MAJOR < 5
// ip_addr_set_ip4_u32(&addr, ip);
addr.u_addr.ip4.addr = ip;
addr.type = IPADDR_TYPE_V4;
ip_clear_no4(&addr);
#else
ip.to_ip_addr_t(&addr);
#endif
@@ -748,10 +783,9 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port) {
}
#if LWIP_IPV6 && ESP_IDF_VERSION_MAJOR < 5
bool AsyncClient::connect(IPv6Address ip, uint16_t port) {
ip_addr_t addr;
addr.type = IPADDR_TYPE_V6;
memcpy(addr.u_addr.ip6.addr, static_cast<const uint32_t *>(ip), sizeof(uint32_t) * 4);
bool AsyncClient::connect(const IPv6Address & ip, uint16_t port) {
auto ipaddr = static_cast<const uint32_t *>(ip);
ip_addr_t addr = IPADDR6_INIT(ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
return _connect(addr, port);
}
@@ -783,7 +817,7 @@ bool AsyncClient::connect(const char * host, uint16_t port) {
_connect_port = port;
return true;
}
log_e("error: %d", err);
log_d("error: %d", err);
return false;
}
@@ -803,7 +837,7 @@ int8_t AsyncClient::abort() {
}
size_t AsyncClient::space() {
if ((_pcb != NULL) && (_pcb->state == 4)) {
if ((_pcb != NULL) && (_pcb->state == ESTABLISHED)) {
return tcp_sndbuf(_pcb);
}
return 0;
@@ -862,17 +896,19 @@ int8_t AsyncClient::_close() {
//ets_printf("X: 0x%08x\n", (uint32_t)this);
int8_t err = ERR_OK;
if (_pcb) {
//log_i("");
TCP_MUTEX_LOCK();
tcp_arg(_pcb, NULL);
tcp_sent(_pcb, NULL);
tcp_recv(_pcb, NULL);
tcp_err(_pcb, NULL);
tcp_poll(_pcb, NULL, 0);
TCP_MUTEX_UNLOCK();
_tcp_clear_events(this);
err = _tcp_close(_pcb, _closed_slot);
if (err != ERR_OK) {
err = abort();
}
_free_closed_slot();
_pcb = NULL;
if (_discard_cb) {
_discard_cb(_discard_cb_arg, this);
@@ -881,40 +917,43 @@ int8_t AsyncClient::_close() {
return err;
}
void AsyncClient::_allocate_closed_slot() {
bool AsyncClient::_allocate_closed_slot() {
if (_closed_slot != INVALID_CLOSED_SLOT) {
return true;
}
xSemaphoreTake(_slots_lock, portMAX_DELAY);
uint32_t closed_slot_min_index = 0;
for (int i = 0; i < _number_of_closed_slots; ++i) {
if ((_closed_slot == -1 || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) {
if ((_closed_slot == INVALID_CLOSED_SLOT || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) {
closed_slot_min_index = _closed_slots[i];
_closed_slot = i;
}
}
if (_closed_slot != -1) {
if (_closed_slot != INVALID_CLOSED_SLOT) {
_closed_slots[_closed_slot] = 0;
}
xSemaphoreGive(_slots_lock);
return (_closed_slot != INVALID_CLOSED_SLOT);
}
void AsyncClient::_free_closed_slot() {
if (_closed_slot != -1) {
xSemaphoreTake(_slots_lock, portMAX_DELAY);
if (_closed_slot != INVALID_CLOSED_SLOT) {
_closed_slots[_closed_slot] = _closed_index;
_closed_slot = -1;
_closed_slot = INVALID_CLOSED_SLOT;
++_closed_index;
}
xSemaphoreGive(_slots_lock);
}
/*
* Private Callbacks
* */
int8_t AsyncClient::_connected(void * pcb, int8_t err) {
int8_t AsyncClient::_connected(tcp_pcb * pcb, int8_t err) {
_pcb = reinterpret_cast<tcp_pcb *>(pcb);
if (_pcb) {
_rx_last_packet = millis();
// tcp_recv(_pcb, &_tcp_recv);
// tcp_sent(_pcb, &_tcp_sent);
// tcp_poll(_pcb, &_tcp_poll, 1);
}
if (_connect_cb) {
_connect_cb(_connect_cb_arg, this);
@@ -924,6 +963,7 @@ int8_t AsyncClient::_connected(void * pcb, int8_t err) {
void AsyncClient::_error(int8_t err) {
if (_pcb) {
TCP_MUTEX_LOCK();
tcp_arg(_pcb, NULL);
if (_pcb->state == LISTEN) {
tcp_sent(_pcb, NULL);
@@ -931,6 +971,8 @@ void AsyncClient::_error(int8_t err) {
tcp_err(_pcb, NULL);
tcp_poll(_pcb, NULL, 0);
}
TCP_MUTEX_UNLOCK();
_free_closed_slot();
_pcb = NULL;
}
if (_error_cb) {
@@ -944,7 +986,7 @@ void AsyncClient::_error(int8_t err) {
//In LwIP Thread
int8_t AsyncClient::_lwip_fin(tcp_pcb * pcb, int8_t err) {
if (!_pcb || pcb != _pcb) {
log_e("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
return ERR_OK;
}
tcp_arg(_pcb, NULL);
@@ -972,11 +1014,9 @@ 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);
_rx_last_ack = _rx_last_packet = millis();
if (_sent_cb) {
_sent_cb(_sent_cb_arg, this, len, (millis() - _tx_last_packet));
_sent_cb(_sent_cb_arg, this, len, (_rx_last_packet - _tx_last_packet));
}
return ERR_OK;
}
@@ -1000,19 +1040,19 @@ int8_t AsyncClient::_recv(tcp_pcb * pcb, pbuf * pb, int8_t err) {
} else if (_pcb) {
_tcp_recved(_pcb, _closed_slot, b->len);
}
pbuf_free(b);
}
pbuf_free(b);
}
return ERR_OK;
}
int8_t AsyncClient::_poll(tcp_pcb * pcb) {
if (!_pcb) {
log_w("pcb is NULL");
// log_d("pcb is NULL");
return ERR_OK;
}
if (pcb != _pcb) {
log_e("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb);
return ERR_OK;
}
@@ -1023,7 +1063,7 @@ int8_t AsyncClient::_poll(tcp_pcb * pcb) {
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);
log_d("ack timeout %d", pcb->state);
if (_timeout_cb)
_timeout_cb(_timeout_cb_arg, this, (now - _tx_last_packet));
return ERR_OK;
@@ -1031,7 +1071,7 @@ int8_t AsyncClient::_poll(tcp_pcb * pcb) {
}
// RX Timeout
if (_rx_timeout && (now - _rx_last_packet) >= (_rx_timeout * 1000)) {
log_w("rx timeout %d", pcb->state);
log_d("rx timeout %d", pcb->state);
_close();
return ERR_OK;
}
@@ -1052,7 +1092,9 @@ void AsyncClient::_dns_found(struct ip_addr * ipaddr) {
#endif
#else
if (ipaddr) {
connect(IPAddress(ipaddr), _connect_port);
IPAddress ip;
ip.from_ip_addr_t(ipaddr);
connect(ip, _connect_port);
#endif
} else {
if (_error_cb) {
@@ -1076,7 +1118,7 @@ bool AsyncClient::free() {
if (!_pcb) {
return true;
}
if (_pcb->state == 0 || _pcb->state > 4) {
if (_pcb->state == CLOSED || _pcb->state > ESTABLISHED) {
return true;
}
return false;
@@ -1131,6 +1173,18 @@ bool AsyncClient::getNoDelay() {
return tcp_nagle_disabled(_pcb);
}
void AsyncClient::setKeepAlive(uint32_t ms, uint8_t cnt) {
if (ms != 0) {
_pcb->so_options |= SOF_KEEPALIVE; //Turn on TCP Keepalive for the given pcb
// Set the time between keepalive messages in milli-seconds
_pcb->keep_idle = ms;
_pcb->keep_intvl = ms;
_pcb->keep_cnt = cnt; //The number of unanswered probes required to force closure of the socket
} else {
_pcb->so_options &= ~SOF_KEEPALIVE; //Turn off TCP Keepalive for the given pcb
}
}
uint16_t AsyncClient::getMss() {
if (!_pcb) {
return 0;
@@ -1177,11 +1231,21 @@ IPv6Address AsyncClient::localIP6() {
}
#else
IPAddress AsyncClient::remoteIP6() {
return _pcb ? IPAddress(dynamic_cast<const ip_addr_t *>(&_pcb->remote_ip)) : IPAddress(IPType::IPv6);
if (!_pcb) {
return IPAddress(IPType::IPv6);
}
IPAddress ip;
ip.from_ip_addr_t(&(_pcb->remote_ip));
return ip;
}
IPAddress AsyncClient::localIP6() {
return _pcb ? IPAddress(dynamic_cast<const ip_addr_t *>(&_pcb->local_ip)) : IPAddress(IPType::IPv6);
if (!_pcb) {
return IPAddress(IPType::IPv6);
}
IPAddress ip;
ip.from_ip_addr_t(&(_pcb->local_ip));
return ip;
}
#endif
#endif
@@ -1215,7 +1279,12 @@ IPAddress AsyncClient::remoteIP() {
#if ESP_IDF_VERSION_MAJOR < 5
return IPAddress(getRemoteAddress());
#else
return _pcb ? IPAddress(dynamic_cast<const ip_addr_t *>(&_pcb->remote_ip)) : IPAddress();
if (!_pcb) {
return IPAddress();
}
IPAddress ip;
ip.from_ip_addr_t(&(_pcb->remote_ip));
return ip;
#endif
}
@@ -1227,7 +1296,12 @@ IPAddress AsyncClient::localIP() {
#if ESP_IDF_VERSION_MAJOR < 5
return IPAddress(getLocalAddress());
#else
return _pcb ? IPAddress(dynamic_cast<const ip_addr_t *>(&_pcb->local_ip)) : IPAddress();
if (!_pcb) {
return IPAddress();
}
IPAddress ip;
ip.from_ip_addr_t(&(_pcb->local_ip));
return ip;
#endif
}
@@ -1247,35 +1321,35 @@ bool AsyncClient::connected() {
if (!_pcb) {
return false;
}
return _pcb->state == 4;
return _pcb->state == ESTABLISHED;
}
bool AsyncClient::connecting() {
if (!_pcb) {
return false;
}
return _pcb->state > 0 && _pcb->state < 4;
return _pcb->state > CLOSED && _pcb->state < ESTABLISHED;
}
bool AsyncClient::disconnecting() {
if (!_pcb) {
return false;
}
return _pcb->state > 4 && _pcb->state < 10;
return _pcb->state > ESTABLISHED && _pcb->state < TIME_WAIT;
}
bool AsyncClient::disconnected() {
if (!_pcb) {
return true;
}
return _pcb->state == 0 || _pcb->state == 10;
return _pcb->state == CLOSED || _pcb->state == TIME_WAIT;
}
bool AsyncClient::freeable() {
if (!_pcb) {
return true;
}
return _pcb->state == 0 || _pcb->state > 4;
return _pcb->state == CLOSED || _pcb->state > ESTABLISHED;
}
bool AsyncClient::canSend() {
@@ -1384,7 +1458,7 @@ void AsyncClient::_s_error(void * arg, int8_t err) {
reinterpret_cast<AsyncClient *>(arg)->_error(err);
}
int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err) {
int8_t AsyncClient::_s_connected(void * arg, struct tcp_pcb * pcb, int8_t err) {
return reinterpret_cast<AsyncClient *>(arg)->_connected(pcb, err);
}
@@ -1396,6 +1470,7 @@ AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
: _port(port)
#if ESP_IDF_VERSION_MAJOR < 5
, _bind4(true)
, _bind6(false)
#else
, _bind4(addr.type() != IPType::IPv6)
, _bind6(addr.type() == IPType::IPv6)
@@ -1410,6 +1485,7 @@ AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
#if ESP_IDF_VERSION_MAJOR < 5
AsyncServer::AsyncServer(IPv6Address addr, uint16_t port)
: _port(port)
, _bind4(false)
, _bind6(true)
, _addr6(addr)
, _noDelay(false)
@@ -1422,7 +1498,7 @@ AsyncServer::AsyncServer(IPv6Address addr, uint16_t port)
AsyncServer::AsyncServer(uint16_t port)
: _port(port)
, _bind4(true)
, _bind6(true)
, _bind6(false)
, _addr((uint32_t)IPADDR_ANY)
#if ESP_IDF_VERSION_MAJOR < 5
, _addr6()
@@ -1451,17 +1527,10 @@ void AsyncServer::begin() {
log_e("failed to start task");
return;
}
int8_t err, bind_type;
if (_bind4 && _bind6) {
bind_type = IPADDR_TYPE_ANY;
} else if (_bind6) {
bind_type = IPADDR_TYPE_V6;
} else {
bind_type = IPADDR_TYPE_V4;
}
_pcb = tcp_new_ip_type(bind_type);
int8_t err;
TCP_MUTEX_LOCK();
_pcb = tcp_new_ip_type(_bind4 && _bind6 ? IPADDR_TYPE_ANY : (_bind6 ? IPADDR_TYPE_V6 : IPADDR_TYPE_V4));
TCP_MUTEX_UNLOCK();
if (!_pcb) {
log_e("_pcb == NULL");
return;
@@ -1469,13 +1538,13 @@ void AsyncServer::begin() {
ip_addr_t local_addr;
#if ESP_IDF_VERSION_MAJOR < 5
// ip_addr_set_ip4_u32(&local_addr, _addr);
local_addr.u_addr.ip4.addr = _addr;
local_addr.type = IPADDR_TYPE_V4;
ip_clear_no4(&local_addr);
/* local_addr.type = bind_type;
local_addr.u_addr.ip4.addr = (uint32_t) _addr;
memcpy(local_addr.u_addr.ip6.addr, static_cast<const uint32_t*>(_addr6), sizeof(uint32_t) * 4); */
if (_bind6) { // _bind6 && _bind4 both at the same time is not supported on Arduino 2 in this lib API
local_addr.type = IPADDR_TYPE_V6;
memcpy(local_addr.u_addr.ip6.addr, static_cast<const uint32_t *>(_addr6), sizeof(uint32_t) * 4);
} else {
local_addr.type = IPADDR_TYPE_V4;
local_addr.u_addr.ip4.addr = _addr;
}
#else
_addr.to_ip_addr_t(&local_addr);
#endif
@@ -1493,16 +1562,22 @@ void AsyncServer::begin() {
log_e("listen_pcb == NULL");
return;
}
TCP_MUTEX_LOCK();
tcp_arg(_pcb, (void *)this);
tcp_accept(_pcb, &_s_accept);
TCP_MUTEX_UNLOCK();
}
void AsyncServer::end() {
if (_pcb) {
TCP_MUTEX_LOCK();
tcp_arg(_pcb, NULL);
tcp_accept(_pcb, NULL);
if (tcp_close(_pcb) != ERR_OK) {
TCP_MUTEX_UNLOCK();
_tcp_abort(_pcb, -1);
} else {
TCP_MUTEX_UNLOCK();
}
_pcb = NULL;
}
@@ -1521,7 +1596,7 @@ int8_t AsyncServer::_accept(tcp_pcb * pcb, int8_t err) {
if (tcp_close(pcb) != ERR_OK) {
tcp_abort(pcb);
}
log_e("FAIL");
log_d("FAIL");
return ERR_OK;
}

View File

@@ -22,6 +22,12 @@
#ifndef ASYNCTCP_H_
#define ASYNCTCP_H_
#define ASYNCTCP_VERSION "3.2.14"
#define ASYNCTCP_VERSION_MAJOR 3
#define ASYNCTCP_VERSION_MINOR 2
#define ASYNCTCP_VERSION_REVISION 14
#define ASYNCTCP_FORK_mathieucarbou
#include "IPAddress.h"
#if ESP_IDF_VERSION_MAJOR < 5
#include "IPv6Address.h"
@@ -52,24 +58,26 @@ extern "C" {
#define CONFIG_ASYNC_TCP_USE_WDT 1 //if enabled, adds between 33us and 200us per event
#endif
#ifndef CONFIG_ASYNC_TCP_TASK_PRIORITY
#define CONFIG_ASYNC_TCP_TASK_PRIORITY 5
#endif
// EMS-ESP: stack usage measured: ESP32: ~2.3K, ESP32S3: ~3.5k
#ifndef CONFIG_ASYNC_TCP_STACK_SIZE
#define CONFIG_ASYNC_TCP_STACK_SIZE 5120
#define CONFIG_ASYNC_TCP_STACK_SIZE 6144
#endif
#ifndef CONFIG_ASYNC_TCP_PRIORITY
#define CONFIG_ASYNC_TCP_PRIORITY 5
#endif
// EMS-ESP: maybe enlarge queue to 64 or 128 see https://github.com/emsesp/EMS-ESP32/issues/177
#ifndef CONFIG_ASYNC_TCP_QUEUE
#define CONFIG_ASYNC_TCP_QUEUE 32
#ifndef CONFIG_ASYNC_TCP_QUEUE_SIZE
#define CONFIG_ASYNC_TCP_QUEUE_SIZE 32
#endif
#ifndef CONFIG_ASYNC_TCP_MAX_ACK_TIME
#define CONFIG_ASYNC_TCP_MAX_ACK_TIME 5000
#endif
class AsyncClient;
#define ASYNC_MAX_ACK_TIME 5000
#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.
@@ -96,9 +104,9 @@ class AsyncClient {
bool operator!=(const AsyncClient & other) {
return !(*this == other);
}
bool connect(IPAddress ip, uint16_t port);
bool connect(const IPAddress & ip, uint16_t port);
#if ESP_IDF_VERSION_MAJOR < 5
bool connect(IPv6Address ip, uint16_t port);
bool connect(const IPv6Address & ip, uint16_t port);
#endif
bool connect(const char * host, uint16_t port);
void close(bool now = false);
@@ -133,6 +141,8 @@ class AsyncClient {
void setNoDelay(bool nodelay);
bool getNoDelay();
void setKeepAlive(uint32_t ms, uint8_t cnt);
uint32_t getRemoteAddress();
uint16_t getRemotePort();
uint32_t getLocalAddress();
@@ -180,7 +190,7 @@ class AsyncClient {
static int8_t _s_lwip_fin(void * arg, struct tcp_pcb * tpcb, int8_t err);
static void _s_error(void * arg, int8_t err);
static int8_t _s_sent(void * arg, struct tcp_pcb * tpcb, uint16_t len);
static int8_t _s_connected(void * arg, void * tpcb, int8_t err);
static int8_t _s_connected(void * arg, struct tcp_pcb * tpcb, int8_t err);
static void _s_dns_found(const char * name, struct ip_addr * ipaddr, void * arg);
int8_t _recv(tcp_pcb * pcb, pbuf * pb, int8_t err);
@@ -222,8 +232,8 @@ class AsyncClient {
int8_t _close();
void _free_closed_slot();
void _allocate_closed_slot();
int8_t _connected(void * pcb, int8_t err);
bool _allocate_closed_slot();
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);

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.2-dev.3"
#define EMSESP_APP_VERSION "3.7.2-dev.4"