@@ -78,7 +78,9 @@ typedef struct {
78
78
79
79
static xQueueHandle _async_queue;
80
80
static TaskHandle_t _async_service_task_handle = NULL ;
81
- static tcp_pcb * pcb_recently_closed = NULL ;
81
+ const int _number_of_closed_slots = 16 ;
82
+ static int _closed_index = 1 ;
83
+ static int _closed_slots[_number_of_closed_slots] = { 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 };
82
84
83
85
static inline bool _init_async_event_queue (){
84
86
if (!_async_queue){
@@ -328,6 +330,7 @@ static int8_t _tcp_accept(void * arg, AsyncClient * client) {
328
330
typedef struct {
329
331
struct tcpip_api_call_data call;
330
332
tcp_pcb * pcb;
333
+ int8_t closed_slot;
331
334
int8_t err;
332
335
union {
333
336
struct {
@@ -352,39 +355,39 @@ typedef struct {
352
355
static err_t _tcp_output_api (struct tcpip_api_call_data *api_call_msg){
353
356
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
354
357
msg->err = ERR_CONN;
355
- if (msg->pcb != pcb_recently_closed ) {
358
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
356
359
msg->err = tcp_output (msg->pcb );
357
360
}
358
- pcb_recently_closed = NULL ;
359
361
return msg->err ;
360
362
}
361
363
362
- static esp_err_t _tcp_output (tcp_pcb * pcb) {
364
+ static esp_err_t _tcp_output (tcp_pcb * pcb, int8_t closed_slot ) {
363
365
if (!pcb){
364
366
return ERR_CONN;
365
367
}
366
368
tcp_api_call_t msg;
367
369
msg.pcb = pcb;
370
+ msg.closed_slot = closed_slot;
368
371
tcpip_api_call (_tcp_output_api, (struct tcpip_api_call_data *)&msg);
369
372
return msg.err ;
370
373
}
371
374
372
375
static err_t _tcp_write_api (struct tcpip_api_call_data *api_call_msg){
373
376
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
374
377
msg->err = ERR_CONN;
375
- if (msg->pcb != pcb_recently_closed ) {
378
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
376
379
msg->err = tcp_write (msg->pcb , msg->write .data , msg->write .size , msg->write .apiflags );
377
380
}
378
- pcb_recently_closed = NULL ;
379
381
return msg->err ;
380
382
}
381
383
382
- static esp_err_t _tcp_write (tcp_pcb * pcb, const char * data, size_t size, uint8_t apiflags) {
384
+ static esp_err_t _tcp_write (tcp_pcb * pcb, int8_t closed_slot, const char * data, size_t size, uint8_t apiflags) {
383
385
if (!pcb){
384
386
return ERR_CONN;
385
387
}
386
388
tcp_api_call_t msg;
387
389
msg.pcb = pcb;
390
+ msg.closed_slot = closed_slot;
388
391
msg.write .data = data;
389
392
msg.write .size = size;
390
393
msg.write .apiflags = apiflags;
@@ -395,20 +398,20 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, const char* data, size_t size, uint8_
395
398
static err_t _tcp_recved_api (struct tcpip_api_call_data *api_call_msg){
396
399
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
397
400
msg->err = ERR_CONN;
398
- if (msg->pcb != pcb_recently_closed ) {
401
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
399
402
msg->err = 0 ;
400
403
tcp_recved (msg->pcb , msg->received );
401
404
}
402
- pcb_recently_closed = NULL ;
403
405
return msg->err ;
404
406
}
405
407
406
- static esp_err_t _tcp_recved (tcp_pcb * pcb, size_t len) {
408
+ static esp_err_t _tcp_recved (tcp_pcb * pcb, int8_t closed_slot, size_t len) {
407
409
if (!pcb){
408
410
return ERR_CONN;
409
411
}
410
412
tcp_api_call_t msg;
411
413
msg.pcb = pcb;
414
+ msg.closed_slot = closed_slot;
412
415
msg.received = len;
413
416
tcpip_api_call (_tcp_recved_api, (struct tcpip_api_call_data *)&msg);
414
417
return msg.err ;
@@ -417,39 +420,39 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, size_t len) {
417
420
static err_t _tcp_close_api (struct tcpip_api_call_data *api_call_msg){
418
421
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
419
422
msg->err = ERR_CONN;
420
- if (msg->pcb != pcb_recently_closed ) {
423
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
421
424
msg->err = tcp_close (msg->pcb );
422
425
}
423
- pcb_recently_closed = NULL ;
424
426
return msg->err ;
425
427
}
426
428
427
- static esp_err_t _tcp_close (tcp_pcb * pcb) {
429
+ static esp_err_t _tcp_close (tcp_pcb * pcb, int8_t closed_slot ) {
428
430
if (!pcb){
429
431
return ERR_CONN;
430
432
}
431
433
tcp_api_call_t msg;
432
434
msg.pcb = pcb;
435
+ msg.closed_slot = closed_slot;
433
436
tcpip_api_call (_tcp_close_api, (struct tcpip_api_call_data *)&msg);
434
437
return msg.err ;
435
438
}
436
439
437
440
static err_t _tcp_abort_api (struct tcpip_api_call_data *api_call_msg){
438
441
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
439
442
msg->err = ERR_CONN;
440
- if (msg->pcb != pcb_recently_closed ) {
443
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
441
444
tcp_abort (msg->pcb );
442
445
}
443
- pcb_recently_closed = NULL ;
444
446
return msg->err ;
445
447
}
446
448
447
- static esp_err_t _tcp_abort (tcp_pcb * pcb) {
449
+ static esp_err_t _tcp_abort (tcp_pcb * pcb, int8_t closed_slot ) {
448
450
if (!pcb){
449
451
return ERR_CONN;
450
452
}
451
453
tcp_api_call_t msg;
452
454
msg.pcb = pcb;
455
+ msg.closed_slot = closed_slot;
453
456
tcpip_api_call (_tcp_abort_api, (struct tcpip_api_call_data *)&msg);
454
457
return msg.err ;
455
458
}
@@ -460,12 +463,13 @@ static err_t _tcp_connect_api(struct tcpip_api_call_data *api_call_msg){
460
463
return msg->err ;
461
464
}
462
465
463
- static esp_err_t _tcp_connect (tcp_pcb * pcb, ip_addr_t * addr, uint16_t port, tcp_connected_fn cb) {
466
+ static esp_err_t _tcp_connect (tcp_pcb * pcb, int8_t closed_slot, ip_addr_t * addr, uint16_t port, tcp_connected_fn cb) {
464
467
if (!pcb){
465
468
return ESP_FAIL;
466
469
}
467
470
tcp_api_call_t msg;
468
471
msg.pcb = pcb;
472
+ msg.closed_slot = closed_slot;
469
473
msg.connect .addr = addr;
470
474
msg.connect .port = port;
471
475
msg.connect .cb = cb;
@@ -485,6 +489,7 @@ static esp_err_t _tcp_bind(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port) {
485
489
}
486
490
tcp_api_call_t msg;
487
491
msg.pcb = pcb;
492
+ msg.closed_slot = -1 ;
488
493
msg.bind .addr = addr;
489
494
msg.bind .port = port;
490
495
tcpip_api_call (_tcp_bind_api, (struct tcpip_api_call_data *)&msg);
@@ -504,6 +509,7 @@ static tcp_pcb * _tcp_listen_with_backlog(tcp_pcb * pcb, uint8_t backlog) {
504
509
}
505
510
tcp_api_call_t msg;
506
511
msg.pcb = pcb;
512
+ msg.closed_slot = -1 ;
507
513
msg.backlog = backlog?backlog:0xFF ;
508
514
tcpip_api_call (_tcp_listen_api, (struct tcpip_api_call_data *)&msg);
509
515
return msg.pcb ;
@@ -541,7 +547,18 @@ AsyncClient::AsyncClient(tcp_pcb* pcb)
541
547
, next(NULL )
542
548
{
543
549
_pcb = pcb;
550
+ _closed_slot = -1 ;
544
551
if (_pcb){
552
+ _closed_slot = 0 ;
553
+ int closed_slot_min_index = _closed_slots[0 ];
554
+ for (int i = 0 ; i < _number_of_closed_slots; ++ i) {
555
+ if (_closed_slots[i] <= closed_slot_min_index && _closed_slots[i] != 0 ) {
556
+ closed_slot_min_index = _closed_slots[i];
557
+ _closed_slot = i;
558
+ }
559
+ }
560
+ _closed_slots[_closed_slot] = 0 ;
561
+
545
562
_rx_last_packet = millis ();
546
563
tcp_arg (_pcb, this );
547
564
tcp_recv (_pcb, &_tcp_recv);
@@ -567,6 +584,7 @@ AsyncClient& AsyncClient::operator=(const AsyncClient& other){
567
584
}
568
585
569
586
_pcb = other._pcb ;
587
+ _closed_slot = other._closed_slot ;
570
588
if (_pcb) {
571
589
_rx_last_packet = millis ();
572
590
tcp_arg (_pcb, this );
@@ -671,7 +689,7 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
671
689
tcp_sent (pcb, &_tcp_sent);
672
690
tcp_poll (pcb, &_tcp_poll, 1 );
673
691
// _tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected);
674
- _tcp_connect (pcb, &addr, port,(tcp_connected_fn)&_tcp_connected);
692
+ _tcp_connect (pcb, _closed_slot, &addr, port,(tcp_connected_fn)&_tcp_connected);
675
693
return true ;
676
694
}
677
695
@@ -697,14 +715,14 @@ bool AsyncClient::connect(const char* host, uint16_t port){
697
715
698
716
void AsyncClient::close (bool now){
699
717
if (_pcb){
700
- _tcp_recved (_pcb, _rx_ack_len);
718
+ _tcp_recved (_pcb, _closed_slot, _rx_ack_len);
701
719
}
702
720
_close ();
703
721
}
704
722
705
723
int8_t AsyncClient::abort (){
706
724
if (_pcb) {
707
- _tcp_abort (_pcb);
725
+ _tcp_abort (_pcb, _closed_slot );
708
726
_pcb = NULL ;
709
727
}
710
728
return ERR_ABRT;
@@ -727,7 +745,7 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
727
745
}
728
746
size_t will_send = (room < size) ? room : size;
729
747
int8_t err = ERR_OK;
730
- err = _tcp_write (_pcb, data, will_send, apiflags);
748
+ err = _tcp_write (_pcb, _closed_slot, data, will_send, apiflags);
731
749
if (err != ERR_OK) {
732
750
return 0 ;
733
751
}
@@ -736,7 +754,7 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
736
754
737
755
bool AsyncClient::send (){
738
756
int8_t err = ERR_OK;
739
- err = _tcp_output (_pcb);
757
+ err = _tcp_output (_pcb, _closed_slot );
740
758
if (err == ERR_OK){
741
759
_pcb_busy = true ;
742
760
_pcb_sent_at = millis ();
@@ -749,7 +767,7 @@ size_t AsyncClient::ack(size_t len){
749
767
if (len > _rx_ack_len)
750
768
len = _rx_ack_len;
751
769
if (len){
752
- _tcp_recved (_pcb, len);
770
+ _tcp_recved (_pcb, _closed_slot, len);
753
771
}
754
772
_rx_ack_len -= len;
755
773
return len;
@@ -759,7 +777,7 @@ void AsyncClient::ackPacket(struct pbuf * pb){
759
777
if (!pb){
760
778
return ;
761
779
}
762
- _tcp_recved (_pcb, pb->len );
780
+ _tcp_recved (_pcb, _closed_slot, pb->len );
763
781
pbuf_free (pb);
764
782
}
765
783
@@ -778,7 +796,7 @@ int8_t AsyncClient::_close(){
778
796
tcp_err (_pcb, NULL );
779
797
tcp_poll (_pcb, NULL , 0 );
780
798
_tcp_clear_events (this );
781
- err = _tcp_close (_pcb);
799
+ err = _tcp_close (_pcb, _closed_slot );
782
800
if (err != ERR_OK) {
783
801
err = abort ();
784
802
}
@@ -840,7 +858,8 @@ int8_t AsyncClient::_lwip_fin(tcp_pcb* pcb, int8_t err) {
840
858
if (tcp_close (_pcb) != ERR_OK) {
841
859
tcp_abort (_pcb);
842
860
}
843
- pcb_recently_closed = _pcb;
861
+ _closed_slots[_closed_slot] = _closed_index;
862
+ ++ _closed_index;
844
863
_pcb = NULL ;
845
864
return ERR_OK;
846
865
}
@@ -881,7 +900,7 @@ int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) {
881
900
if (!_ack_pcb) {
882
901
_rx_ack_len += b->len ;
883
902
} else if (_pcb) {
884
- _tcp_recved (_pcb, b->len );
903
+ _tcp_recved (_pcb, _closed_slot, b->len );
885
904
}
886
905
pbuf_free (b);
887
906
}
@@ -1228,7 +1247,7 @@ void AsyncServer::begin(){
1228
1247
err = _tcp_bind (_pcb, &local_addr, _port);
1229
1248
1230
1249
if (err != ERR_OK) {
1231
- _tcp_close (_pcb);
1250
+ _tcp_close (_pcb, - 1 );
1232
1251
log_e (" bind error: %d" , err);
1233
1252
return ;
1234
1253
}
@@ -1247,7 +1266,7 @@ void AsyncServer::end(){
1247
1266
if (_pcb){
1248
1267
tcp_arg (_pcb, NULL );
1249
1268
tcp_accept (_pcb, NULL );
1250
- _tcp_abort (_pcb);
1269
+ _tcp_abort (_pcb, - 1 );
1251
1270
_pcb = NULL ;
1252
1271
}
1253
1272
}
0 commit comments