@@ -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 = CONFIG_LWIP_MAX_ACTIVE_TCP;
82
+ static int _closed_index = 0 ;
83
+ static int _closed_slots[_number_of_closed_slots];
82
84
83
85
static inline bool _init_async_event_queue (){
84
86
if (!_async_queue){
@@ -333,6 +335,7 @@ static int8_t _tcp_accept(void * arg, AsyncClient * client) {
333
335
typedef struct {
334
336
struct tcpip_api_call_data call;
335
337
tcp_pcb * pcb;
338
+ int8_t closed_slot;
336
339
int8_t err;
337
340
union {
338
341
struct {
@@ -357,39 +360,39 @@ typedef struct {
357
360
static err_t _tcp_output_api (struct tcpip_api_call_data *api_call_msg){
358
361
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
359
362
msg->err = ERR_CONN;
360
- if (msg->pcb != pcb_recently_closed ) {
363
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
361
364
msg->err = tcp_output (msg->pcb );
362
365
}
363
- pcb_recently_closed = NULL ;
364
366
return msg->err ;
365
367
}
366
368
367
- static esp_err_t _tcp_output (tcp_pcb * pcb) {
369
+ static esp_err_t _tcp_output (tcp_pcb * pcb, int8_t closed_slot ) {
368
370
if (!pcb){
369
371
return ERR_CONN;
370
372
}
371
373
tcp_api_call_t msg;
372
374
msg.pcb = pcb;
375
+ msg.closed_slot = closed_slot;
373
376
tcpip_api_call (_tcp_output_api, (struct tcpip_api_call_data *)&msg);
374
377
return msg.err ;
375
378
}
376
379
377
380
static err_t _tcp_write_api (struct tcpip_api_call_data *api_call_msg){
378
381
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
379
382
msg->err = ERR_CONN;
380
- if (msg->pcb != pcb_recently_closed ) {
383
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
381
384
msg->err = tcp_write (msg->pcb , msg->write .data , msg->write .size , msg->write .apiflags );
382
385
}
383
- pcb_recently_closed = NULL ;
384
386
return msg->err ;
385
387
}
386
388
387
- static esp_err_t _tcp_write (tcp_pcb * pcb, const char * data, size_t size, uint8_t apiflags) {
389
+ static esp_err_t _tcp_write (tcp_pcb * pcb, int8_t closed_slot, const char * data, size_t size, uint8_t apiflags) {
388
390
if (!pcb){
389
391
return ERR_CONN;
390
392
}
391
393
tcp_api_call_t msg;
392
394
msg.pcb = pcb;
395
+ msg.closed_slot = closed_slot;
393
396
msg.write .data = data;
394
397
msg.write .size = size;
395
398
msg.write .apiflags = apiflags;
@@ -400,20 +403,20 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, const char* data, size_t size, uint8_
400
403
static err_t _tcp_recved_api (struct tcpip_api_call_data *api_call_msg){
401
404
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
402
405
msg->err = ERR_CONN;
403
- if (msg->pcb != pcb_recently_closed ) {
406
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
404
407
msg->err = 0 ;
405
408
tcp_recved (msg->pcb , msg->received );
406
409
}
407
- pcb_recently_closed = NULL ;
408
410
return msg->err ;
409
411
}
410
412
411
- static esp_err_t _tcp_recved (tcp_pcb * pcb, size_t len) {
413
+ static esp_err_t _tcp_recved (tcp_pcb * pcb, int8_t closed_slot, size_t len) {
412
414
if (!pcb){
413
415
return ERR_CONN;
414
416
}
415
417
tcp_api_call_t msg;
416
418
msg.pcb = pcb;
419
+ msg.closed_slot = closed_slot;
417
420
msg.received = len;
418
421
tcpip_api_call (_tcp_recved_api, (struct tcpip_api_call_data *)&msg);
419
422
return msg.err ;
@@ -422,39 +425,39 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, size_t len) {
422
425
static err_t _tcp_close_api (struct tcpip_api_call_data *api_call_msg){
423
426
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
424
427
msg->err = ERR_CONN;
425
- if (msg->pcb != pcb_recently_closed ) {
428
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
426
429
msg->err = tcp_close (msg->pcb );
427
430
}
428
- pcb_recently_closed = NULL ;
429
431
return msg->err ;
430
432
}
431
433
432
- static esp_err_t _tcp_close (tcp_pcb * pcb) {
434
+ static esp_err_t _tcp_close (tcp_pcb * pcb, int8_t closed_slot ) {
433
435
if (!pcb){
434
436
return ERR_CONN;
435
437
}
436
438
tcp_api_call_t msg;
437
439
msg.pcb = pcb;
440
+ msg.closed_slot = closed_slot;
438
441
tcpip_api_call (_tcp_close_api, (struct tcpip_api_call_data *)&msg);
439
442
return msg.err ;
440
443
}
441
444
442
445
static err_t _tcp_abort_api (struct tcpip_api_call_data *api_call_msg){
443
446
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
444
447
msg->err = ERR_CONN;
445
- if (msg->pcb != pcb_recently_closed ) {
448
+ if (msg->closed_slot == - 1 || !_closed_slots[msg-> closed_slot ] ) {
446
449
tcp_abort (msg->pcb );
447
450
}
448
- pcb_recently_closed = NULL ;
449
451
return msg->err ;
450
452
}
451
453
452
- static esp_err_t _tcp_abort (tcp_pcb * pcb) {
454
+ static esp_err_t _tcp_abort (tcp_pcb * pcb, int8_t closed_slot ) {
453
455
if (!pcb){
454
456
return ERR_CONN;
455
457
}
456
458
tcp_api_call_t msg;
457
459
msg.pcb = pcb;
460
+ msg.closed_slot = closed_slot;
458
461
tcpip_api_call (_tcp_abort_api, (struct tcpip_api_call_data *)&msg);
459
462
return msg.err ;
460
463
}
@@ -465,12 +468,13 @@ static err_t _tcp_connect_api(struct tcpip_api_call_data *api_call_msg){
465
468
return msg->err ;
466
469
}
467
470
468
- static esp_err_t _tcp_connect (tcp_pcb * pcb, ip_addr_t * addr, uint16_t port, tcp_connected_fn cb) {
471
+ static esp_err_t _tcp_connect (tcp_pcb * pcb, int8_t closed_slot, ip_addr_t * addr, uint16_t port, tcp_connected_fn cb) {
469
472
if (!pcb){
470
473
return ESP_FAIL;
471
474
}
472
475
tcp_api_call_t msg;
473
476
msg.pcb = pcb;
477
+ msg.closed_slot = closed_slot;
474
478
msg.connect .addr = addr;
475
479
msg.connect .port = port;
476
480
msg.connect .cb = cb;
@@ -490,6 +494,7 @@ static esp_err_t _tcp_bind(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port) {
490
494
}
491
495
tcp_api_call_t msg;
492
496
msg.pcb = pcb;
497
+ msg.closed_slot = -1 ;
493
498
msg.bind .addr = addr;
494
499
msg.bind .port = port;
495
500
tcpip_api_call (_tcp_bind_api, (struct tcpip_api_call_data *)&msg);
@@ -509,6 +514,7 @@ static tcp_pcb * _tcp_listen_with_backlog(tcp_pcb * pcb, uint8_t backlog) {
509
514
}
510
515
tcp_api_call_t msg;
511
516
msg.pcb = pcb;
517
+ msg.closed_slot = -1 ;
512
518
msg.backlog = backlog?backlog:0xFF ;
513
519
tcpip_api_call (_tcp_listen_api, (struct tcpip_api_call_data *)&msg);
514
520
return msg.pcb ;
@@ -546,7 +552,25 @@ AsyncClient::AsyncClient(tcp_pcb* pcb)
546
552
, next(NULL )
547
553
{
548
554
_pcb = pcb;
555
+ _closed_slot = -1 ;
549
556
if (_pcb){
557
+ _closed_slot = 0 ;
558
+ if (_closed_index == 0 ) {
559
+ _closed_index = 1 ;
560
+ for (int i = 0 ; i < _number_of_closed_slots; ++ i) {
561
+ _closed_slots[i] = 1 ;
562
+ }
563
+ } else {
564
+ int closed_slot_min_index = _closed_slots[0 ];
565
+ for (int i = 0 ; i < _number_of_closed_slots; ++ i) {
566
+ if (_closed_slots[i] <= closed_slot_min_index && _closed_slots[i] != 0 ) {
567
+ closed_slot_min_index = _closed_slots[i];
568
+ _closed_slot = i;
569
+ }
570
+ }
571
+ }
572
+ _closed_slots[_closed_slot] = 0 ;
573
+
550
574
_rx_last_packet = millis ();
551
575
tcp_arg (_pcb, this );
552
576
tcp_recv (_pcb, &_tcp_recv);
@@ -572,6 +596,7 @@ AsyncClient& AsyncClient::operator=(const AsyncClient& other){
572
596
}
573
597
574
598
_pcb = other._pcb ;
599
+ _closed_slot = other._closed_slot ;
575
600
if (_pcb) {
576
601
_rx_last_packet = millis ();
577
602
tcp_arg (_pcb, this );
@@ -676,7 +701,7 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
676
701
tcp_sent (pcb, &_tcp_sent);
677
702
tcp_poll (pcb, &_tcp_poll, 1 );
678
703
// _tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected);
679
- _tcp_connect (pcb, &addr, port,(tcp_connected_fn)&_tcp_connected);
704
+ _tcp_connect (pcb, _closed_slot, &addr, port,(tcp_connected_fn)&_tcp_connected);
680
705
return true ;
681
706
}
682
707
@@ -702,14 +727,14 @@ bool AsyncClient::connect(const char* host, uint16_t port){
702
727
703
728
void AsyncClient::close (bool now){
704
729
if (_pcb){
705
- _tcp_recved (_pcb, _rx_ack_len);
730
+ _tcp_recved (_pcb, _closed_slot, _rx_ack_len);
706
731
}
707
732
_close ();
708
733
}
709
734
710
735
int8_t AsyncClient::abort (){
711
736
if (_pcb) {
712
- _tcp_abort (_pcb);
737
+ _tcp_abort (_pcb, _closed_slot );
713
738
_pcb = NULL ;
714
739
}
715
740
return ERR_ABRT;
@@ -732,7 +757,7 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
732
757
}
733
758
size_t will_send = (room < size) ? room : size;
734
759
int8_t err = ERR_OK;
735
- err = _tcp_write (_pcb, data, will_send, apiflags);
760
+ err = _tcp_write (_pcb, _closed_slot, data, will_send, apiflags);
736
761
if (err != ERR_OK) {
737
762
return 0 ;
738
763
}
@@ -741,7 +766,7 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
741
766
742
767
bool AsyncClient::send (){
743
768
int8_t err = ERR_OK;
744
- err = _tcp_output (_pcb);
769
+ err = _tcp_output (_pcb, _closed_slot );
745
770
if (err == ERR_OK){
746
771
_pcb_busy = true ;
747
772
_pcb_sent_at = millis ();
@@ -754,7 +779,7 @@ size_t AsyncClient::ack(size_t len){
754
779
if (len > _rx_ack_len)
755
780
len = _rx_ack_len;
756
781
if (len){
757
- _tcp_recved (_pcb, len);
782
+ _tcp_recved (_pcb, _closed_slot, len);
758
783
}
759
784
_rx_ack_len -= len;
760
785
return len;
@@ -764,7 +789,7 @@ void AsyncClient::ackPacket(struct pbuf * pb){
764
789
if (!pb){
765
790
return ;
766
791
}
767
- _tcp_recved (_pcb, pb->len );
792
+ _tcp_recved (_pcb, _closed_slot, pb->len );
768
793
pbuf_free (pb);
769
794
}
770
795
@@ -783,7 +808,7 @@ int8_t AsyncClient::_close(){
783
808
tcp_err (_pcb, NULL );
784
809
tcp_poll (_pcb, NULL , 0 );
785
810
_tcp_clear_events (this );
786
- err = _tcp_close (_pcb);
811
+ err = _tcp_close (_pcb, _closed_slot );
787
812
if (err != ERR_OK) {
788
813
err = abort ();
789
814
}
@@ -845,7 +870,8 @@ int8_t AsyncClient::_lwip_fin(tcp_pcb* pcb, int8_t err) {
845
870
if (tcp_close (_pcb) != ERR_OK) {
846
871
tcp_abort (_pcb);
847
872
}
848
- pcb_recently_closed = _pcb;
873
+ _closed_slots[_closed_slot] = _closed_index;
874
+ ++ _closed_index;
849
875
_pcb = NULL ;
850
876
return ERR_OK;
851
877
}
@@ -886,7 +912,7 @@ int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) {
886
912
if (!_ack_pcb) {
887
913
_rx_ack_len += b->len ;
888
914
} else if (_pcb) {
889
- _tcp_recved (_pcb, b->len );
915
+ _tcp_recved (_pcb, _closed_slot, b->len );
890
916
}
891
917
pbuf_free (b);
892
918
}
@@ -1233,7 +1259,7 @@ void AsyncServer::begin(){
1233
1259
err = _tcp_bind (_pcb, &local_addr, _port);
1234
1260
1235
1261
if (err != ERR_OK) {
1236
- _tcp_close (_pcb);
1262
+ _tcp_close (_pcb, - 1 );
1237
1263
log_e (" bind error: %d" , err);
1238
1264
return ;
1239
1265
}
@@ -1253,7 +1279,7 @@ void AsyncServer::end(){
1253
1279
tcp_arg (_pcb, NULL );
1254
1280
tcp_accept (_pcb, NULL );
1255
1281
if (tcp_close (_pcb) != ERR_OK){
1256
- _tcp_abort (_pcb);
1282
+ _tcp_abort (_pcb, - 1 );
1257
1283
}
1258
1284
_pcb = NULL ;
1259
1285
}
0 commit comments