@@ -30,14 +30,14 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
30
30
_serial_rts(rts),
31
31
_serial_cts(cts),
32
32
_parser(&_serial),
33
+ _tcp_passive(false ),
33
34
_packets(0 ),
34
35
_packets_end(&_packets),
35
36
_sdk_v(-1 ,-1 ,-1 ),
36
37
_at_v(-1 ,-1 ,-1 ),
37
38
_connect_error(0 ),
38
39
_fail(false ),
39
40
_closed(false ),
40
- _socket_open(),
41
41
_connection_status(NSAPI_STATUS_DISCONNECTED),
42
42
_heap_usage(0 )
43
43
{
@@ -57,6 +57,11 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
57
57
_parser.oob (" 4,CLOSED" , callback (this , &ESP8266::_oob_socket4_closed_handler));
58
58
_parser.oob (" WIFI " , callback (this , &ESP8266::_connection_status_handler));
59
59
_parser.oob (" UNLINK" , callback (this , &ESP8266::_oob_socket_close_error));
60
+
61
+ for (int i= 0 ; i < SOCKET_COUNT; i++) {
62
+ _socket_open[i].id = -1 ;
63
+ _socket_open[i].proto = NSAPI_UDP;
64
+ }
60
65
}
61
66
62
67
bool ESP8266::at_available ()
@@ -76,9 +81,9 @@ struct ESP8266::fw_sdk_version ESP8266::sdk_version()
76
81
int patch;
77
82
78
83
_smutex.lock ();
79
- bool done = _parser.send (" AT+GMR" );
80
- done &= _parser.recv (" SDK version:%d.%d.%d" , &major, &minor, &patch);
81
- done &= _parser.recv (" OK\n " );
84
+ bool done = _parser.send (" AT+GMR" )
85
+ && _parser.recv (" SDK version:%d.%d.%d" , &major, &minor, &patch)
86
+ && _parser.recv (" OK\n " );
82
87
_smutex.unlock ();
83
88
84
89
if (done) {
@@ -97,9 +102,9 @@ struct ESP8266::fw_at_version ESP8266::at_version()
97
102
int nused;
98
103
99
104
_smutex.lock ();
100
- bool done = _parser.send (" AT+GMR" );
101
- done &= _parser.recv (" AT version:%d.%d.%d.%d" , &major, &minor, &patch, &nused);
102
- done &= _parser.recv (" OK\n " );
105
+ bool done = _parser.send (" AT+GMR" )
106
+ && _parser.recv (" AT version:%d.%d.%d.%d" , &major, &minor, &patch, &nused)
107
+ && _parser.recv (" OK\n " );
103
108
_smutex.unlock ();
104
109
105
110
if (done) {
@@ -210,6 +215,23 @@ bool ESP8266::dhcp(bool enabled, int mode)
210
215
return done;
211
216
}
212
217
218
+ bool ESP8266::cond_enable_tcp_passive_mode ()
219
+ {
220
+ bool done = true ;
221
+
222
+ if (FW_AT_LEAST_VERSION (_at_v.major , _at_v.minor , _at_v.patch , 0 , ESP8266_AT_VERSION_TCP_PASSIVE_MODE)) {
223
+ _smutex.lock ();
224
+ done = _parser.send (" AT+CIPRECVMODE=1" )
225
+ && _parser.recv (" OK\n " );
226
+ _smutex.unlock ();
227
+
228
+ _tcp_passive = done ? true : false ;
229
+ }
230
+
231
+ return done;
232
+ }
233
+
234
+
213
235
nsapi_error_t ESP8266::connect (const char *ap, const char *passPhrase)
214
236
{
215
237
_smutex.lock ();
@@ -376,7 +398,7 @@ nsapi_error_t ESP8266::open_udp(int id, const char* addr, int port, int local_po
376
398
377
399
if (id >= SOCKET_COUNT) {
378
400
return NSAPI_ERROR_PARAMETER;
379
- } else if (_socket_open[id]) {
401
+ } else if (_socket_open[id]. id == id ) {
380
402
return NSAPI_ERROR_IS_CONNECTED;
381
403
}
382
404
@@ -390,7 +412,8 @@ nsapi_error_t ESP8266::open_udp(int id, const char* addr, int port, int local_po
390
412
}
391
413
392
414
if (done) {
393
- _socket_open[id] = 1 ;
415
+ _socket_open[id].id = id;
416
+ _socket_open[id].proto = NSAPI_UDP;
394
417
}
395
418
396
419
_clear_socket_packets (id);
@@ -405,7 +428,7 @@ bool ESP8266::open_tcp(int id, const char* addr, int port, int keepalive)
405
428
static const char *type = " TCP" ;
406
429
bool done = false ;
407
430
408
- if (id >= SOCKET_COUNT || _socket_open[id]) {
431
+ if (id >= SOCKET_COUNT || _socket_open[id]. id == id ) {
409
432
return false ;
410
433
}
411
434
@@ -419,7 +442,8 @@ bool ESP8266::open_tcp(int id, const char* addr, int port, int keepalive)
419
442
}
420
443
421
444
if (done) {
422
- _socket_open[id] = 1 ;
445
+ _socket_open[id].id = id;
446
+ _socket_open[id].proto = NSAPI_TCP;
423
447
}
424
448
425
449
_clear_socket_packets (id);
@@ -467,8 +491,21 @@ void ESP8266::_packet_handler()
467
491
int amount;
468
492
int pdu_len;
469
493
470
- // parse out the packet
471
- if (!_parser.recv (" ,%d,%d:" , &id, &amount)) {
494
+ // Get socket id
495
+ if (!_parser.recv (" ,%d," , &id)) {
496
+ return ;
497
+ }
498
+ // In passive mode amount not used...
499
+ if (_tcp_passive
500
+ && _socket_open[id].id == id
501
+ && _socket_open[id].proto == NSAPI_TCP) {
502
+ if (!_parser.recv (" %d\n " , &amount)) {
503
+ MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENODATA), \
504
+ " ESP8266::_packet_handler(): Data length missing" );
505
+ }
506
+ return ;
507
+ // Amount required in active mode
508
+ } else if (!_parser.recv (" %d:" , &amount)) {
472
509
return ;
473
510
}
474
511
@@ -512,8 +549,41 @@ void ESP8266::process_oob(uint32_t timeout, bool all) {
512
549
setTimeout ();
513
550
}
514
551
552
+ int32_t ESP8266::_recv_tcp_passive (int id, void *data, uint32_t amount, uint32_t timeout)
553
+ {
554
+ int32_t len;
555
+ int32_t ret;
556
+
557
+ _smutex.lock ();
558
+
559
+ bool done = _parser.send (" AT+CIPRECVDATA=%d,%lu" , id, amount);
560
+ if (!done) {
561
+ _smutex.unlock ();
562
+ return NSAPI_ERROR_DEVICE_ERROR;
563
+ }
564
+ // NOTE: documentation v3.0 says '+CIPRECVDATA:<data_len>,' but it's not how the FW responds...
565
+ done = _parser.recv (" +CIPRECVDATA,%ld:" , &len)
566
+ && _parser.read ((char *)data, len)
567
+ && _parser.recv (" OK\n " );
568
+
569
+ // Got data?
570
+ if (done) {
571
+ ret = len;
572
+ } else {
573
+ // Socket still open?
574
+ ret = _socket_open[id].id != id ? 0 : (int32_t )NSAPI_ERROR_WOULD_BLOCK;
575
+ }
576
+
577
+ _smutex.unlock ();
578
+ return ret;
579
+ }
580
+
515
581
int32_t ESP8266::recv_tcp (int id, void *data, uint32_t amount, uint32_t timeout)
516
582
{
583
+ if (_tcp_passive) {
584
+ return _recv_tcp_passive (id, data, amount, timeout);
585
+ }
586
+
517
587
_smutex.lock ();
518
588
519
589
// No flow control, drain the USART receive register ASAP to avoid data overrun
@@ -552,7 +622,7 @@ int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
552
622
}
553
623
}
554
624
}
555
- if (! _socket_open[id]) {
625
+ if (_socket_open[id]. id < 0 ) {
556
626
_smutex.unlock ();
557
627
return 0 ;
558
628
}
@@ -634,7 +704,7 @@ bool ESP8266::close(int id)
634
704
if (!_parser.recv (" OK\n " )) {
635
705
if (_closed) { // UNLINK ERROR
636
706
_closed = false ;
637
- _socket_open[id] = 0 ;
707
+ _socket_open[id]. id = - 1 ;
638
708
_clear_socket_packets (id);
639
709
_smutex.unlock ();
640
710
// ESP8266 has a habit that it might close a socket on its own.
@@ -717,27 +787,27 @@ void ESP8266::_oob_socket_close_error()
717
787
718
788
void ESP8266::_oob_socket0_closed_handler ()
719
789
{
720
- _socket_open[0 ] = 0 ;
790
+ _socket_open[0 ]. id = - 1 ;
721
791
}
722
792
723
793
void ESP8266::_oob_socket1_closed_handler ()
724
794
{
725
- _socket_open[1 ] = 0 ;
795
+ _socket_open[1 ]. id = - 1 ;
726
796
}
727
797
728
798
void ESP8266::_oob_socket2_closed_handler ()
729
799
{
730
- _socket_open[2 ] = 0 ;
800
+ _socket_open[2 ]. id = - 1 ;
731
801
}
732
802
733
803
void ESP8266::_oob_socket3_closed_handler ()
734
804
{
735
- _socket_open[3 ] = 0 ;
805
+ _socket_open[3 ]. id = - 1 ;
736
806
}
737
807
738
808
void ESP8266::_oob_socket4_closed_handler ()
739
809
{
740
- _socket_open[4 ] = 0 ;
810
+ _socket_open[4 ]. id = - 1 ;
741
811
}
742
812
743
813
void ESP8266::_connection_status_handler ()
0 commit comments