Merge pull request #1 from mmakaay/master

Better fix for "ack timeout 4" client disconnects.
This commit is contained in:
Guillermo Ruffino
2021-05-09 19:10:19 -03:00
committed by GitHub
2 changed files with 23 additions and 24 deletions

View File

@@ -575,11 +575,10 @@ AsyncClient::AsyncClient(tcp_pcb* pcb)
, _pb_cb_arg(0) , _pb_cb_arg(0)
, _timeout_cb(0) , _timeout_cb(0)
, _timeout_cb_arg(0) , _timeout_cb_arg(0)
, _pcb_busy(0)
, _pcb_sent_at(0)
, _ack_pcb(true) , _ack_pcb(true)
, _rx_last_packet(0) , _tx_last_packet(0)
, _rx_since_timeout(0) , _rx_timeout(0)
, _rx_last_ack(0)
, _ack_timeout(ASYNC_MAX_ACK_TIME) , _ack_timeout(ASYNC_MAX_ACK_TIME)
, _connect_port(0) , _connect_port(0)
, prev(NULL) , prev(NULL)
@@ -783,14 +782,12 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
} }
bool AsyncClient::send(){ bool AsyncClient::send(){
auto pcb_sent_at_backup = _pcb_sent_at; auto backup = _tx_last_packet;
_pcb_sent_at = millis(); _tx_last_packet = millis();
_pcb_busy++;
if (_tcp_output(_pcb, _closed_slot) == ERR_OK) { if (_tcp_output(_pcb, _closed_slot) == ERR_OK) {
return true; return true;
} }
_pcb_sent_at = pcb_sent_at_backup; _tx_last_packet = backup;
_pcb_busy--;
return false; return false;
} }
@@ -870,7 +867,6 @@ int8_t AsyncClient::_connected(void* pcb, int8_t err){
_pcb = reinterpret_cast<tcp_pcb*>(pcb); _pcb = reinterpret_cast<tcp_pcb*>(pcb);
if(_pcb){ if(_pcb){
_rx_last_packet = millis(); _rx_last_packet = millis();
_pcb_busy = 0;
// tcp_recv(_pcb, &_tcp_recv); // tcp_recv(_pcb, &_tcp_recv);
// tcp_sent(_pcb, &_tcp_sent); // tcp_sent(_pcb, &_tcp_sent);
// tcp_poll(_pcb, &_tcp_poll, 1); // tcp_poll(_pcb, &_tcp_poll, 1);
@@ -932,10 +928,10 @@ int8_t AsyncClient::_fin(tcp_pcb* pcb, int8_t err) {
int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) { int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) {
_rx_last_packet = millis(); _rx_last_packet = millis();
_rx_last_ack = millis();
//log_i("%u", len); //log_i("%u", len);
_pcb_busy--;
if(_sent_cb) { 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; return ERR_OK;
} }
@@ -978,15 +974,18 @@ int8_t AsyncClient::_poll(tcp_pcb* pcb){
uint32_t now = millis(); uint32_t now = millis();
// ACK Timeout // ACK Timeout
if(_pcb_busy > 0 && _ack_timeout && (now - _pcb_sent_at) >= _ack_timeout){ if(_ack_timeout){
_pcb_busy = 0; const uint32_t one_day = 86400000;
log_w("ack timeout %d", pcb->state); bool last_tx_is_after_last_ack = (_rx_last_ack - _tx_last_packet + one_day) < one_day;
if(_timeout_cb) if(last_tx_is_after_last_ack && (now - _tx_last_packet) >= _ack_timeout) {
_timeout_cb(_timeout_cb_arg, this, (now - _pcb_sent_at)); log_w("ack timeout %d", pcb->state);
return ERR_OK; if(_timeout_cb)
_timeout_cb(_timeout_cb_arg, this, (now - _tx_last_packet));
return ERR_OK;
}
} }
// RX Timeout // 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); log_w("rx timeout %d", pcb->state);
_close(); _close();
return ERR_OK; return ERR_OK;
@@ -1045,11 +1044,11 @@ size_t AsyncClient::write(const char* data, size_t size, uint8_t apiflags) {
} }
void AsyncClient::setRxTimeout(uint32_t timeout){ void AsyncClient::setRxTimeout(uint32_t timeout){
_rx_since_timeout = timeout; _rx_timeout = timeout;
} }
uint32_t AsyncClient::getRxTimeout(){ uint32_t AsyncClient::getRxTimeout(){
return _rx_since_timeout; return _rx_timeout;
} }
uint32_t AsyncClient::getAckTimeout(){ uint32_t AsyncClient::getAckTimeout(){

View File

@@ -160,12 +160,12 @@ class AsyncClient {
AcConnectHandler _poll_cb; AcConnectHandler _poll_cb;
void* _poll_cb_arg; void* _poll_cb_arg;
uint32_t _pcb_busy;
uint32_t _pcb_sent_at;
bool _ack_pcb; bool _ack_pcb;
uint32_t _tx_last_packet;
uint32_t _rx_ack_len; uint32_t _rx_ack_len;
uint32_t _rx_last_packet; uint32_t _rx_last_packet;
uint32_t _rx_since_timeout; uint32_t _rx_timeout;
uint32_t _rx_last_ack;
uint32_t _ack_timeout; uint32_t _ack_timeout;
uint16_t _connect_port; uint16_t _connect_port;