@@ -73,10 +73,15 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
73
73
// https://github.com/esp8266/Arduino/blob/4897e0006b5b0123a2fa31f67b14a3fff65ce561/doc/faq/a02-my-esp-crashes.md#watchdog
74
74
_parser.oob (" Soft WDT reset" , callback (this , &ESP8266::_oob_watchdog_reset));
75
75
_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));
76
78
77
79
for (int i = 0 ; i < SOCKET_COUNT; i++) {
78
80
_sock_i[i].open = false ;
79
81
_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 ;
80
85
}
81
86
}
82
87
@@ -552,16 +557,12 @@ void ESP8266::_oob_packet_hdlr()
552
557
if (!_parser.recv (" ,%d," , &id)) {
553
558
return ;
554
559
}
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
562
564
}
563
565
return ;
564
- // Amount required in active mode
565
566
} else if (!_parser.recv (" %d:" , &amount)) {
566
567
return ;
567
568
}
@@ -614,15 +615,13 @@ void ESP8266::bg_process_oob(uint32_t timeout, bool all)
614
615
615
616
int32_t ESP8266::_recv_tcp_passive (int id, void *data, uint32_t amount, uint32_t timeout)
616
617
{
617
- int32_t len;
618
- int32_t ret = (int32_t )NSAPI_ERROR_WOULD_BLOCK;
618
+ int32_t ret;
619
619
620
620
_smutex.lock ();
621
621
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;
626
625
627
626
// +CIPRECVDATA supports up to 2048 bytes at a time
628
627
if (amount > 2048 ) {
@@ -631,29 +630,18 @@ int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t
631
630
632
631
// NOTE: documentation v3.0 says '+CIPRECVDATA:<data_len>,' but it's not how the FW responds...
633
632
bool done = _parser.send (" AT+CIPRECVDATA=%d,%lu" , id, amount)
634
- && _parser.recv (" +CIPRECVDATA,%ld:" , &len)
635
- && _parser.read ((char *)data, len)
636
633
&& _parser.recv (" OK\n " );
637
634
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 ;
642
638
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 ;
649
640
650
- ret = done ? len : 0 ;
641
+ if (!_sock_i[id].open && ret == NSAPI_ERROR_WOULD_BLOCK) {
642
+ ret = 0 ;
651
643
}
652
644
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
- }
657
645
_smutex.unlock ();
658
646
return ret;
659
647
}
@@ -780,6 +768,13 @@ void ESP8266::_clear_socket_packets(int id)
780
768
p = &(*p)->next ;
781
769
}
782
770
}
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
+ }
783
778
}
784
779
785
780
bool ESP8266::close (int id)
@@ -884,6 +879,23 @@ void ESP8266::_oob_busy()
884
879
_busy = true ;
885
880
}
886
881
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
+
887
899
void ESP8266::_oob_connect_err ()
888
900
{
889
901
_fail = false ;
0 commit comments