From 8c5cc7108172f23f48943f22332465f45a6e5c90 Mon Sep 17 00:00:00 2001 From: Michal Paszta Date: Tue, 31 Dec 2019 15:00:10 +0200 Subject: [PATCH] ESP8266: Introduce single send_status instead of two flags --- .../wifi/esp8266-driver/ESP8266/ESP8266.cpp | 59 +++++++++++++------ .../wifi/esp8266-driver/ESP8266/ESP8266.h | 15 ++++- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp b/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp index 9c6b73543d..942b01d5df 100644 --- a/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp +++ b/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp @@ -58,8 +58,7 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts) _error(false), _busy(false), _reset_done(false), - _prev_send_ok_pending(false), - _send_fail_received(false), + _send_status(SEND_STATUS_OK), _conn_status(NSAPI_STATUS_DISCONNECTED) { _serial.set_baud(MBED_CONF_ESP8266_SERIAL_BAUDRATE); @@ -290,6 +289,9 @@ bool ESP8266::reset(void) tr_debug("reset(): Done: %s.", done ? "OK" : "FAIL"); _clear_socket_packets(ESP8266_ALL_SOCKET_IDS); + _send_status = SEND_STATUS_OK; + _parser.remove_oob("SEND OK"); + _parser.remove_oob("SEND FAIL"); set_timeout(); _smutex.unlock(); @@ -616,13 +618,18 @@ bool ESP8266::dns_lookup(const char *name, char *ip) nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount) { - if (_prev_send_ok_pending && _sock_i[id].proto == NSAPI_TCP) { - tr_debug("send(): Previous packet was not ACK-ed with SEND OK."); - return NSAPI_ERROR_WOULD_BLOCK; + if (_sock_i[id].proto == NSAPI_TCP) { + if (_send_status == SEND_STATUS_PENDING) { + tr_debug("send(): Previous packet was not yet ACK-ed with SEND OK."); + return NSAPI_ERROR_WOULD_BLOCK; + } else if (_send_status == SEND_STATUS_FAILED) { + tr_debug("send(): Previous packet failed."); + _send_status = SEND_STATUS_OK; + return NSAPI_ERROR_DEVICE_ERROR; + } } nsapi_error_t ret = NSAPI_ERROR_DEVICE_ERROR; - _send_fail_received = false; int bytes_confirmed = 0; constexpr unsigned int send_ack_retries = 3; @@ -666,7 +673,6 @@ nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount) // The "Recv X bytes" is not documented. if (!_parser.recv("Recv %d bytes", &bytes_confirmed)) { tr_debug("send(): Bytes not confirmed."); - ret = NSAPI_ERROR_DEVICE_ERROR; if (_sock_i[id].proto == NSAPI_TCP) { ret = NSAPI_ERROR_WOULD_BLOCK; } else if (_sock_i[id].proto == NSAPI_UDP) { @@ -683,15 +689,13 @@ nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount) _parser.oob("SEND FAIL", callback(this, &ESP8266::_oob_send_fail_received)); for (unsigned int i = send_ack_retries; i > 0; i--) { if (!_parser.recv("SEND OK")) { - if (_error || _send_fail_received) { + if (_error || _send_status == SEND_STATUS_FAILED) { _parser.remove_oob("SEND FAIL"); goto END; } if (_busy) { _busy = false; tr_debug("send(): Busy, %d retries left...", i - 1); - } else { - tr_debug("send(): Not busy, but no SEND OK. %d retries left...", i - 1); } } else { ret = amount; // Got "SEND OK" - return number of bytes. @@ -699,8 +703,8 @@ nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount) } } - // ESP8266 ACKed data over serial, but did not ACK over TCP or report any error. - _prev_send_ok_pending = true; + // ESP8266 ACKed data over serial, but did not ACK with SEND OK or report any error. + _send_status = SEND_STATUS_PENDING; _parser.oob("SEND OK", callback(this, &ESP8266::_oob_send_ok_received)); ret = amount; @@ -718,7 +722,7 @@ END: tr_debug("send(): Connection disrupted."); } - if (_send_fail_received) { + if (_send_status == SEND_STATUS_FAILED) { if (_sock_i[id].proto == NSAPI_TCP) { ret = NSAPI_ERROR_DEVICE_ERROR; } else { @@ -1001,6 +1005,14 @@ void ESP8266::_clear_socket_packets(int id) _sock_i[id].tcp_data_avbl = 0; } } +void ESP8266::_clear_send_status(void) +{ + _smutex.lock(); // remove_oob doesn't use serial, but we don't want to race against it. + _send_status = SEND_STATUS_OK; + _parser.remove_oob("SEND OK"); + _parser.remove_oob("SEND FAIL"); + _smutex.unlock(); +} bool ESP8266::close(int id) { @@ -1204,6 +1216,7 @@ void ESP8266::_oob_socket0_closed() { static const int id = 0; _sock_i[id].open = false; + _clear_send_status(); tr_debug("_oob_socket0_closed(): Socket %d closed.", id); } @@ -1211,6 +1224,7 @@ void ESP8266::_oob_socket1_closed() { static const int id = 1; _sock_i[id].open = false; + _clear_send_status(); tr_debug("_oob_socket1_closed(): Socket %d closed.", id); } @@ -1218,6 +1232,7 @@ void ESP8266::_oob_socket2_closed() { static const int id = 2; _sock_i[id].open = false; + _clear_send_status(); tr_debug("_oob_socket2_closed(): Socket %d closed.", id); } @@ -1225,6 +1240,7 @@ void ESP8266::_oob_socket3_closed() { static const int id = 3; _sock_i[id].open = false; + _clear_send_status(); tr_debug("_oob_socket3_closed(): %d closed.", id); } @@ -1232,6 +1248,7 @@ void ESP8266::_oob_socket4_closed() { static const int id = 4; _sock_i[id].open = false; + _clear_send_status(); tr_debug("_oob_socket0_closed(): Socket %d closed.", id); } @@ -1271,14 +1288,22 @@ void ESP8266::_oob_connection_status() void ESP8266::_oob_send_ok_received() { - tr_debug("_oob_send_ok_received called"); - _prev_send_ok_pending = false; + tr_debug("_oob_send_ok_received called with _send_status %d", _send_status); + if (_send_status == SEND_STATUS_PENDING) { + _send_status = SEND_STATUS_OK; + } + _parser.remove_oob("SEND OK"); + _parser.remove_oob("SEND FAIL"); } void ESP8266::_oob_send_fail_received() { - tr_debug("_oob_send_fail_received called"); - _send_fail_received = true; + tr_debug("_oob_send_fail_received called with _send_status %d", _send_status); + if (_send_status == SEND_STATUS_PENDING) { + _send_status = SEND_STATUS_FAILED; + } + _parser.remove_oob("SEND FAIL"); + _parser.remove_oob("SEND OK"); } int8_t ESP8266::default_wifi_mode() diff --git a/components/wifi/esp8266-driver/ESP8266/ESP8266.h b/components/wifi/esp8266-driver/ESP8266/ESP8266.h index babb929e6e..10a19f0590 100644 --- a/components/wifi/esp8266-driver/ESP8266/ESP8266.h +++ b/components/wifi/esp8266-driver/ESP8266/ESP8266.h @@ -250,6 +250,17 @@ public: */ nsapi_error_t open_tcp(int id, const char *addr, int port, int keepalive = 0); + /** ESP8266 send status. + * + * There is one send status per device, because the ACKs are just simple "SEND OK/FAIL" + * with no way to tell which socket is reporting back. + */ + enum send_status { + SEND_STATUS_OK = 0, /*!< device is able to send */ + SEND_STATUS_PENDING = 1, /*!< previous send is pending for OK/FAIL */ + SEND_STATUS_FAILED = 2 /*!< previous send FAILed */ + }; + /** * Sends data to an open socket * @@ -444,6 +455,7 @@ private: // data follows } *_packets, * *_packets_end; void _clear_socket_packets(int id); + void _clear_send_status(void); int _sock_active_id; // Memory statistics @@ -481,8 +493,7 @@ private: bool _error; bool _busy; bool _reset_done; - bool _prev_send_ok_pending; - bool _send_fail_received; + send_status _send_status; // Modem's address info char _ip_buffer[16];