diff --git a/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp b/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp index 61ae9839bc..249e33f33a 100644 --- a/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp +++ b/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp @@ -563,6 +563,7 @@ bool ESP8266::dns_lookup(const char *name, char *ip) nsapi_error_t ESP8266::send(int id, const void *data, uint32_t amount) { + nsapi_error_t ret = NSAPI_ERROR_DEVICE_ERROR; // +CIPSEND supports up to 2048 bytes at a time // Data stream can be truncated if (amount > 2048 && _sock_i[id].proto == NSAPI_TCP) { @@ -576,31 +577,50 @@ nsapi_error_t ESP8266::send(int id, const void *data, uint32_t amount) _smutex.lock(); set_timeout(ESP8266_SEND_TIMEOUT); _busy = false; - if (_parser.send("AT+CIPSEND=%d,%lu", id, amount) - && _parser.recv(">") - && _parser.write((char *)data, (int)amount) >= 0 - && _parser.recv("SEND OK")) { - // No flow control, data overrun is possible - if (_serial_rts == NC) { - while (_parser.process_oob()); // Drain USART receive register - } - _smutex.unlock(); - return NSAPI_ERROR_OK; + _error = false; + if (!_parser.send("AT+CIPSEND=%d,%lu", id, amount)) { + tr_debug("ESP8266::send(): AT+CIPSEND failed"); + goto END; } - if (_error) { - _error = false; + + if(!_parser.recv(">")) { + tr_debug("ESP8266::send(): didn't get \">\""); + ret = NSAPI_ERROR_WOULD_BLOCK; + goto END; } + + if (_parser.write((char *)data, (int)amount) >= 0 && _parser.recv("SEND OK")) { + ret = NSAPI_ERROR_OK; + } + +END: + _process_oob(ESP8266_RECV_TIMEOUT, true); // Drain USART receive register to avoid data overrun + + // error hierarchy, from low to high if (_busy) { - set_timeout(); - _smutex.unlock(); - tr_debug("returning WOULD_BLOCK"); - return NSAPI_ERROR_WOULD_BLOCK; + ret = NSAPI_ERROR_WOULD_BLOCK; + tr_debug("ESP8266::send(): modem busy"); + } + + if (ret == NSAPI_ERROR_DEVICE_ERROR) { + ret = NSAPI_ERROR_WOULD_BLOCK; + tr_debug("ESP8266::send(): send failed"); + } + + if (_error) { + ret = NSAPI_ERROR_CONNECTION_LOST; + tr_debug("ESP8266::send(): connection disrupted"); + } + + if (!_sock_i[id].open && ret != NSAPI_ERROR_OK) { + ret = NSAPI_ERROR_CONNECTION_LOST; + tr_debug("ESP8266::send(): socket closed abruptly"); } set_timeout(); _smutex.unlock(); - return NSAPI_ERROR_DEVICE_ERROR; + return ret; } void ESP8266::_oob_packet_hdlr()