mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #9309 from VeijoPesonen/bugfix-esp8266_send_busy
ESP8266 - fix send buffer exhaustion handlingpull/9335/head
commit
e25611aad8
|
@ -557,6 +557,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 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
|
// +CIPSEND supports up to 2048 bytes at a time
|
||||||
// Data stream can be truncated
|
// Data stream can be truncated
|
||||||
if (amount > 2048 && _sock_i[id].proto == NSAPI_TCP) {
|
if (amount > 2048 && _sock_i[id].proto == NSAPI_TCP) {
|
||||||
|
@ -570,31 +571,50 @@ nsapi_error_t ESP8266::send(int id, const void *data, uint32_t amount)
|
||||||
_smutex.lock();
|
_smutex.lock();
|
||||||
set_timeout(ESP8266_SEND_TIMEOUT);
|
set_timeout(ESP8266_SEND_TIMEOUT);
|
||||||
_busy = false;
|
_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;
|
|
||||||
}
|
|
||||||
if (_error) {
|
|
||||||
_error = false;
|
_error = false;
|
||||||
|
if (!_parser.send("AT+CIPSEND=%d,%lu", id, amount)) {
|
||||||
|
tr_debug("ESP8266::send(): AT+CIPSEND failed");
|
||||||
|
goto END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
if (_busy) {
|
||||||
set_timeout();
|
ret = NSAPI_ERROR_WOULD_BLOCK;
|
||||||
_smutex.unlock();
|
tr_debug("ESP8266::send(): modem busy");
|
||||||
tr_debug("returning WOULD_BLOCK");
|
}
|
||||||
return NSAPI_ERROR_WOULD_BLOCK;
|
|
||||||
|
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();
|
set_timeout();
|
||||||
_smutex.unlock();
|
_smutex.unlock();
|
||||||
|
|
||||||
return NSAPI_ERROR_DEVICE_ERROR;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESP8266::_oob_packet_hdlr()
|
void ESP8266::_oob_packet_hdlr()
|
||||||
|
|
Loading…
Reference in New Issue