Skip to content

Commit c9bba6f

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 ec3d113 commit c9bba6f

File tree

2 files changed

+48
-31
lines changed

2 files changed

+48
-31
lines changed

ESP8266/ESP8266.cpp

Lines changed: 43 additions & 31 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,15 +615,13 @@ 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

627626
// +CIPRECVDATA supports up to 2048 bytes at a time
628627
if (amount > 2048) {
@@ -631,29 +630,18 @@ int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t
631630

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

638-
if (done) {
639-
_smutex.unlock();
640-
return len;
641-
}
635+
(void)done;
636+
_sock_i[id].tcp_data = NULL;
637+
_sock_active_id = -1;
642638

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

650-
ret = done ? len : 0;
641+
if (!_sock_i[id].open && ret == NSAPI_ERROR_WOULD_BLOCK) {
642+
ret = 0;
651643
}
652644

653-
// Flow control, read from USART receive register only when no more data is buffered, and as little as possible
654-
if (_serial_rts != NC) {
655-
_process_oob(timeout, false);
656-
}
657645
_smutex.unlock();
658646
return ret;
659647
}
@@ -780,6 +768,13 @@ void ESP8266::_clear_socket_packets(int id)
780768
p = &(*p)->next;
781769
}
782770
}
771+
if (id == ESP8266_ALL_SOCKET_IDS) {
772+
for (int id = 0; id < 5; id++) {
773+
_sock_i[id].tcp_data_avbl = 0;
774+
}
775+
} else {
776+
_sock_i[id].tcp_data_avbl = 0;
777+
}
783778
}
784779

785780
bool ESP8266::close(int id)
@@ -884,6 +879,23 @@ void ESP8266::_oob_busy()
884879
_busy = true;
885880
}
886881

882+
void ESP8266::_oob_tcp_data_hdlr()
883+
{
884+
int32_t len;
885+
886+
MBED_ASSERT(_sock_active_id >= 0 && _sock_active_id < 5);
887+
888+
if (!_parser.recv("%ld:", &len)) {
889+
return;
890+
}
891+
892+
if (!_parser.read(_sock_i[_sock_active_id].tcp_data, len)) {
893+
return;
894+
}
895+
896+
_sock_i[_sock_active_id].tcp_data_rcvd = len;
897+
}
898+
887899
void ESP8266::_oob_connect_err()
888900
{
889901
_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)