Skip to content

Commit 32f8d11

Browse files
author
Veijo Pesonen
committed
For AT firmware >= 1.7.0 - handle incoming data as OOB
When trying to pull data from the ESP8266 handle it as OOB to prevent timeouts.
1 parent 672d1c8 commit 32f8d11

File tree

2 files changed

+48
-32
lines changed

2 files changed

+48
-32
lines changed

ESP8266/ESP8266.cpp

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,15 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
7373
//https://github.com/esp8266/Arduino/blob/4897e0006b5b0123a2fa31f67b14a3fff65ce561/doc/faq/a02-my-esp-crashes.md#watchdog
7474
_parser.oob("Soft WDT reset", callback(this, &ESP8266::_oob_watchdog_reset));
7575
_parser.oob("busy ", callback(this, &ESP8266::_oob_busy));
76+
// NOTE: documentation v3.0 says '+CIPRECVDATA:<data_len>,' but it's not how the FW responds...
77+
_parser.oob("+CIPRECVDATA,", callback(this, &ESP8266::_oob_tcp_data_hdlr));
7678

7779
for (int i = 0; i < SOCKET_COUNT; i++) {
7880
_sock_i[i].open = false;
7981
_sock_i[i].proto = NSAPI_UDP;
82+
_sock_i[i].tcp_data = NULL;
83+
_sock_i[i].tcp_data_avbl = 0;
84+
_sock_i[i].tcp_data_rcvd = 0;
8085
}
8186
}
8287

@@ -552,16 +557,12 @@ void ESP8266::_oob_packet_hdlr()
552557
if (!_parser.recv(",%d,", &id)) {
553558
return;
554559
}
555-
// In passive mode amount not used...
556-
if (_tcp_passive
557-
&& _sock_i[id].open == true
558-
&& _sock_i[id].proto == NSAPI_TCP) {
559-
if (!_parser.recv("%d\n", &amount)) {
560-
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENODATA), \
561-
"ESP8266::_packet_handler(): Data length missing");
560+
561+
if(_tcp_passive && _sock_i[id].open == true && _sock_i[id].proto == NSAPI_TCP) {
562+
if (_parser.recv("%d\n", &amount)) {
563+
_sock_i[id].tcp_data_avbl = amount; // Not used but stored for the sake of visibility
562564
}
563565
return;
564-
// Amount required in active mode
565566
} else if (!_parser.recv("%d:", &amount)) {
566567
return;
567568
}
@@ -614,41 +615,27 @@ void ESP8266::bg_process_oob(uint32_t timeout, bool all)
614615

615616
int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t timeout)
616617
{
617-
int32_t len;
618-
int32_t ret = (int32_t)NSAPI_ERROR_WOULD_BLOCK;
618+
int32_t ret;
619619

620620
_smutex.lock();
621621

622-
// No flow control, drain the USART receive register ASAP to avoid data overrun
623-
if (_serial_rts == NC) {
624-
_process_oob(timeout, true);
625-
}
622+
_sock_i[id].tcp_data = (char*)data;
623+
_sock_i[id].tcp_data_rcvd = NSAPI_ERROR_WOULD_BLOCK;
624+
_sock_active_id = id;
626625

627-
// NOTE: documentation v3.0 says '+CIPRECVDATA:<data_len>,' but it's not how the FW responds...
628626
bool done = _parser.send("AT+CIPRECVDATA=%d,%lu", id, amount)
629-
&& _parser.recv("+CIPRECVDATA,%ld:", &len)
630-
&& _parser.read((char *)data, len)
631627
&& _parser.recv("OK\n");
632628

633-
if (done) {
634-
_smutex.unlock();
635-
return len;
636-
}
629+
(void)done;
630+
_sock_i[id].tcp_data = NULL;
631+
_sock_active_id = -1;
637632

638-
// Socket closed, doesn't mean there couldn't be data left
639-
if (!_sock_i[id].open) {
640-
done = _parser.send("AT+CIPRECVDATA=%d,%lu", id, amount)
641-
&& _parser.recv("+CIPRECVDATA,%ld:", &len)
642-
&& _parser.read((char *)data, len)
643-
&& _parser.recv("OK\n");
633+
ret = _sock_i[id].tcp_data_rcvd;
644634

645-
ret = done ? len : 0;
635+
if (!_sock_i[id].open && ret == NSAPI_ERROR_WOULD_BLOCK) {
636+
ret = 0;
646637
}
647638

648-
// Flow control, read from USART receive register only when no more data is buffered, and as little as possible
649-
if (_serial_rts != NC) {
650-
_process_oob(timeout, false);
651-
}
652639
_smutex.unlock();
653640
return ret;
654641
}
@@ -775,6 +762,13 @@ void ESP8266::_clear_socket_packets(int id)
775762
p = &(*p)->next;
776763
}
777764
}
765+
if (id < 5) {
766+
_sock_i[id].tcp_data_avbl = 0;
767+
} else {
768+
for (int id = 0; id < 5; id++) {
769+
_sock_i[id].tcp_data_avbl = 0;
770+
}
771+
}
778772
}
779773

780774
bool ESP8266::close(int id)
@@ -879,6 +873,23 @@ void ESP8266::_oob_busy()
879873
_busy = true;
880874
}
881875

876+
void ESP8266::_oob_tcp_data_hdlr()
877+
{
878+
int32_t len;
879+
880+
MBED_ASSERT(_sock_active_id >= 0 && _sock_active_id < 5);
881+
882+
if (!_parser.recv("%ld:", &len)) {
883+
return;
884+
}
885+
886+
if (!_parser.read(_sock_i[_sock_active_id].tcp_data, len)) {
887+
return;
888+
}
889+
890+
_sock_i[_sock_active_id].tcp_data_rcvd = len;
891+
}
892+
882893
void ESP8266::_oob_connect_err()
883894
{
884895
_fail = false;

ESP8266/ESP8266.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ class ESP8266 {
393393
// data follows
394394
} *_packets, * *_packets_end;
395395
void _clear_socket_packets(int id);
396+
int _sock_active_id;
396397

397398
// Memory statistics
398399
size_t _heap_usage; // (Socket data buffer usage)
@@ -414,6 +415,7 @@ class ESP8266 {
414415
void _oob_socket_close_err();
415416
void _oob_watchdog_reset();
416417
void _oob_busy();
418+
void _oob_tcp_data_hdlr();
417419

418420
// OOB state variables
419421
int _connect_error;
@@ -433,6 +435,9 @@ class ESP8266 {
433435
struct _sock_info {
434436
bool open;
435437
nsapi_protocol_t proto;
438+
char *tcp_data;
439+
int32_t tcp_data_avbl; // Data waiting on modem
440+
int32_t tcp_data_rcvd;
436441
};
437442
struct _sock_info _sock_i[SOCKET_COUNT];
438443

0 commit comments

Comments
 (0)