Skip to content

Commit d23d55c

Browse files
ESP8266: Introduce single send_status instead of two flags
1 parent 902fedd commit d23d55c

File tree

2 files changed

+55
-19
lines changed

2 files changed

+55
-19
lines changed

components/wifi/esp8266-driver/ESP8266/ESP8266.cpp

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
5858
_error(false),
5959
_busy(false),
6060
_reset_done(false),
61-
_prev_send_ok_pending(false),
62-
_send_fail_received(false),
61+
_send_status(SEND_STATUS_OK),
6362
_conn_status(NSAPI_STATUS_DISCONNECTED)
6463
{
6564
_serial.set_baud(MBED_CONF_ESP8266_SERIAL_BAUDRATE);
@@ -290,6 +289,9 @@ bool ESP8266::reset(void)
290289
tr_debug("reset(): Done: %s.", done ? "OK" : "FAIL");
291290

292291
_clear_socket_packets(ESP8266_ALL_SOCKET_IDS);
292+
_send_status = SEND_STATUS_OK;
293+
_parser.remove_oob("SEND OK");
294+
_parser.remove_oob("SEND FAIL");
293295
set_timeout();
294296
_smutex.unlock();
295297

@@ -616,13 +618,18 @@ bool ESP8266::dns_lookup(const char *name, char *ip)
616618

617619
nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount)
618620
{
619-
if (_prev_send_ok_pending && _sock_i[id].proto == NSAPI_TCP) {
620-
tr_debug("send(): Previous packet was not ACK-ed with SEND OK.");
621-
return NSAPI_ERROR_WOULD_BLOCK;
621+
if (_sock_i[id].proto == NSAPI_TCP) {
622+
if (_send_status == SEND_STATUS_PENDING) {
623+
tr_debug("send(): Previous packet was not yet ACK-ed with SEND OK.");
624+
return NSAPI_ERROR_WOULD_BLOCK;
625+
} else if (_send_status == SEND_STATUS_FAILED) {
626+
tr_debug("send(): Previous packet failed.");
627+
_send_status = SEND_STATUS_OK;
628+
return NSAPI_ERROR_DEVICE_ERROR;
629+
}
622630
}
623631

624632
nsapi_error_t ret = NSAPI_ERROR_DEVICE_ERROR;
625-
_send_fail_received = false;
626633
int bytes_confirmed = 0;
627634
constexpr unsigned int send_ack_retries = 3;
628635

@@ -666,7 +673,6 @@ nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount)
666673
// The "Recv X bytes" is not documented.
667674
if (!_parser.recv("Recv %d bytes", &bytes_confirmed)) {
668675
tr_debug("send(): Bytes not confirmed.");
669-
ret = NSAPI_ERROR_DEVICE_ERROR;
670676
if (_sock_i[id].proto == NSAPI_TCP) {
671677
ret = NSAPI_ERROR_WOULD_BLOCK;
672678
} else if (_sock_i[id].proto == NSAPI_UDP) {
@@ -683,24 +689,22 @@ nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount)
683689
_parser.oob("SEND FAIL", callback(this, &ESP8266::_oob_send_fail_received));
684690
for (unsigned int i = send_ack_retries; i > 0; i--) {
685691
if (!_parser.recv("SEND OK")) {
686-
if (_error || _send_fail_received) {
692+
if (_error || _send_status == SEND_STATUS_FAILED) {
687693
_parser.remove_oob("SEND FAIL");
688694
goto END;
689695
}
690696
if (_busy) {
691697
_busy = false;
692698
tr_debug("send(): Busy, %d retries left...", i - 1);
693-
} else {
694-
tr_debug("send(): Not busy, but no SEND OK. %d retries left...", i - 1);
695699
}
696700
} else {
697701
ret = amount; // Got "SEND OK" - return number of bytes.
698702
goto END;
699703
}
700704
}
701705

702-
// ESP8266 ACKed data over serial, but did not ACK over TCP or report any error.
703-
_prev_send_ok_pending = true;
706+
// ESP8266 ACKed data over serial, but did not ACK with SEND OK or report any error.
707+
_send_status = SEND_STATUS_PENDING;
704708
_parser.oob("SEND OK", callback(this, &ESP8266::_oob_send_ok_received));
705709
ret = amount;
706710

@@ -718,7 +722,7 @@ nsapi_size_or_error_t ESP8266::send(int id, const void *data, uint32_t amount)
718722
tr_debug("send(): Connection disrupted.");
719723
}
720724

721-
if (_send_fail_received) {
725+
if (_send_status == SEND_STATUS_FAILED) {
722726
if (_sock_i[id].proto == NSAPI_TCP) {
723727
ret = NSAPI_ERROR_DEVICE_ERROR;
724728
} else {
@@ -1001,6 +1005,14 @@ void ESP8266::_clear_socket_packets(int id)
10011005
_sock_i[id].tcp_data_avbl = 0;
10021006
}
10031007
}
1008+
void ESP8266::_clear_send_status(void)
1009+
{
1010+
_smutex.lock(); // remove_oob doesn't use serial, but we don't want to race against it.
1011+
_send_status = SEND_STATUS_OK;
1012+
_parser.remove_oob("SEND OK");
1013+
_parser.remove_oob("SEND FAIL");
1014+
_smutex.unlock();
1015+
}
10041016

10051017
bool ESP8266::close(int id)
10061018
{
@@ -1203,34 +1215,39 @@ void ESP8266::_oob_socket0_closed()
12031215
{
12041216
static const int id = 0;
12051217
_sock_i[id].open = false;
1218+
_clear_send_status();
12061219
tr_debug("_oob_socket0_closed(): Socket %d closed.", id);
12071220
}
12081221

12091222
void ESP8266::_oob_socket1_closed()
12101223
{
12111224
static const int id = 1;
12121225
_sock_i[id].open = false;
1226+
_clear_send_status();
12131227
tr_debug("_oob_socket1_closed(): Socket %d closed.", id);
12141228
}
12151229

12161230
void ESP8266::_oob_socket2_closed()
12171231
{
12181232
static const int id = 2;
12191233
_sock_i[id].open = false;
1234+
_clear_send_status();
12201235
tr_debug("_oob_socket2_closed(): Socket %d closed.", id);
12211236
}
12221237

12231238
void ESP8266::_oob_socket3_closed()
12241239
{
12251240
static const int id = 3;
12261241
_sock_i[id].open = false;
1242+
_clear_send_status();
12271243
tr_debug("_oob_socket3_closed(): %d closed.", id);
12281244
}
12291245

12301246
void ESP8266::_oob_socket4_closed()
12311247
{
12321248
static const int id = 4;
12331249
_sock_i[id].open = false;
1250+
_clear_send_status();
12341251
tr_debug("_oob_socket0_closed(): Socket %d closed.", id);
12351252
}
12361253

@@ -1270,14 +1287,22 @@ void ESP8266::_oob_connection_status()
12701287

12711288
void ESP8266::_oob_send_ok_received()
12721289
{
1273-
tr_debug("_oob_send_ok_received called");
1274-
_prev_send_ok_pending = false;
1290+
tr_debug("_oob_send_ok_received called with _send_status %d", _send_status);
1291+
if (_send_status == SEND_STATUS_PENDING) {
1292+
_send_status = SEND_STATUS_OK;
1293+
}
1294+
_parser.remove_oob("SEND OK");
1295+
_parser.remove_oob("SEND FAIL");
12751296
}
12761297

12771298
void ESP8266::_oob_send_fail_received()
12781299
{
1279-
tr_debug("_oob_send_fail_received called");
1280-
_send_fail_received = true;
1300+
tr_debug("_oob_send_fail_received called with _send_status %d", _send_status);
1301+
if (_send_status == SEND_STATUS_PENDING) {
1302+
_send_status = SEND_STATUS_FAILED;
1303+
}
1304+
_parser.remove_oob("SEND FAIL");
1305+
_parser.remove_oob("SEND OK");
12811306
}
12821307

12831308
int8_t ESP8266::default_wifi_mode()

components/wifi/esp8266-driver/ESP8266/ESP8266.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,17 @@ class ESP8266 {
250250
*/
251251
nsapi_error_t open_tcp(int id, const char *addr, int port, int keepalive = 0);
252252

253+
/** ESP8266 send status.
254+
*
255+
* There is one send status per device, because the ACKs are just simple "SEND OK/FAIL"
256+
* with no way to tell which socket is reporting back.
257+
*/
258+
enum send_status {
259+
SEND_STATUS_OK = 0, /*!< device is able to send */
260+
SEND_STATUS_PENDING = 1, /*!< previous send is pending for OK/FAIL */
261+
SEND_STATUS_FAILED = 2 /*!< previous send FAILed */
262+
};
263+
253264
/**
254265
* Sends data to an open socket
255266
*
@@ -444,6 +455,7 @@ class ESP8266 {
444455
// data follows
445456
} *_packets, * *_packets_end;
446457
void _clear_socket_packets(int id);
458+
void _clear_send_status(void);
447459
int _sock_active_id;
448460

449461
// Memory statistics
@@ -481,8 +493,7 @@ class ESP8266 {
481493
bool _error;
482494
bool _busy;
483495
bool _reset_done;
484-
bool _prev_send_ok_pending;
485-
bool _send_fail_received;
496+
send_status _send_status;
486497

487498
// Modem's address info
488499
char _ip_buffer[16];

0 commit comments

Comments
 (0)