From 26980b39e35151117720220ef1d57f56a0a51acf Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 17 Dec 2017 17:16:41 +0100 Subject: [PATCH] fix #1002 ::Flush() wait for empty send buffer (#3967) * fix #1002 ::Flush() wait for empty send buffer * WiFiClient::Flush() guarantees that the data has been delivered option 1 of https://github.com/esp8266/Arduino/pull/3967#discussion_r156901071 10ms max wait according to loaded tcp echo/reply scheme --- libraries/ESP8266WiFi/src/WiFiClient.cpp | 2 +- libraries/ESP8266WiFi/src/WiFiUdp.cpp | 3 +-- .../ESP8266WiFi/src/include/ClientContext.h | 20 +++++++++++++++++-- libraries/Ethernet/src/EthernetUdp.cpp | 9 +++++++-- libraries/Ethernet/src/EthernetUdp.h | 3 +++ 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index 576201c68..e4b2d1d73 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -259,7 +259,7 @@ size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) { void WiFiClient::flush() { if (_client) - _client->flush(); + _client->wait_until_sent(); } void WiFiClient::stop() diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/libraries/ESP8266WiFi/src/WiFiUdp.cpp index c163ccef9..5e4247308 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -243,8 +243,7 @@ int WiFiUDP::peek() void WiFiUDP::flush() { - if (_ctx) - _ctx->flush(); + endPacket(); } IPAddress WiFiUDP::remoteIP() diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 639b3587c..b3784d25e 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -107,7 +107,7 @@ public: if(this != 0) { DEBUGV(":ur %d\r\n", _refcnt); if(--_refcnt == 0) { - flush(); + discard_received(); close(); if(_discard_cb) { _discard_cb(_discard_cb_arg, this); @@ -277,7 +277,7 @@ public: return copy_size; } - void flush() + void discard_received() { if(!_rx_buf) { return; @@ -290,6 +290,22 @@ public: _rx_buf_offset = 0; } + void wait_until_sent() + { + // fix option 1 in + // https://github.com/esp8266/Arduino/pull/3967#pullrequestreview-83451496 + // TODO: option 2 + + #define WAIT_TRIES_MS 10 // at most 10ms + + int tries = 1+ WAIT_TRIES_MS; + + while (state() == ESTABLISHED && tcp_sndbuf(_pcb) != TCP_SND_BUF && --tries) { + _write_some(); + delay(1); // esp_ schedule+yield + } + } + uint8_t state() const { if(!_pcb) { diff --git a/libraries/Ethernet/src/EthernetUdp.cpp b/libraries/Ethernet/src/EthernetUdp.cpp index b5dcb78cc..b9a2c867a 100644 --- a/libraries/Ethernet/src/EthernetUdp.cpp +++ b/libraries/Ethernet/src/EthernetUdp.cpp @@ -118,7 +118,7 @@ size_t EthernetUDP::write(const uint8_t *buffer, size_t size) int EthernetUDP::parsePacket() { // discard any remaining bytes in the last packet - flush(); + clear_remaining(); if (recvAvailable(_sock) > 0) { @@ -204,7 +204,7 @@ int EthernetUDP::peek() return b; } -void EthernetUDP::flush() +void EthernetUDP::clear_remaining() { // could this fail (loop endlessly) if _remaining > 0 and recv in read fails? // should only occur if recv fails after telling us the data is there, lets @@ -216,3 +216,8 @@ void EthernetUDP::flush() } } +void EthernetUDP::flush() +{ + endPacket(); +} + diff --git a/libraries/Ethernet/src/EthernetUdp.h b/libraries/Ethernet/src/EthernetUdp.h index 8a6b7ab5a..1e928d88a 100644 --- a/libraries/Ethernet/src/EthernetUdp.h +++ b/libraries/Ethernet/src/EthernetUdp.h @@ -49,6 +49,9 @@ private: uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed uint16_t _offset; // offset into the packet being sent uint16_t _remaining; // remaining bytes of incoming packet yet to be processed + +protected: + void clear_remaining(); public: EthernetUDP(); // Constructor