Skip to content
This repository was archived by the owner on Jan 20, 2025. It is now read-only.

Commit 9a4a58a

Browse files
committed
Allow for multiple close events.
1 parent 911414e commit 9a4a58a

File tree

2 files changed

+49
-29
lines changed

2 files changed

+49
-29
lines changed

src/AsyncTCP.cpp

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ typedef struct {
7878

7979
static xQueueHandle _async_queue;
8080
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 };
8284

8385
static inline bool _init_async_event_queue(){
8486
if(!_async_queue){
@@ -328,6 +330,7 @@ static int8_t _tcp_accept(void * arg, AsyncClient * client) {
328330
typedef struct {
329331
struct tcpip_api_call_data call;
330332
tcp_pcb * pcb;
333+
int8_t closed_slot;
331334
int8_t err;
332335
union {
333336
struct {
@@ -352,39 +355,39 @@ typedef struct {
352355
static err_t _tcp_output_api(struct tcpip_api_call_data *api_call_msg){
353356
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
354357
msg->err = ERR_CONN;
355-
if(msg->pcb != pcb_recently_closed) {
358+
if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
356359
msg->err = tcp_output(msg->pcb);
357360
}
358-
pcb_recently_closed = NULL;
359361
return msg->err;
360362
}
361363

362-
static esp_err_t _tcp_output(tcp_pcb * pcb) {
364+
static esp_err_t _tcp_output(tcp_pcb * pcb, int8_t closed_slot) {
363365
if(!pcb){
364366
return ERR_CONN;
365367
}
366368
tcp_api_call_t msg;
367369
msg.pcb = pcb;
370+
msg.closed_slot = closed_slot;
368371
tcpip_api_call(_tcp_output_api, (struct tcpip_api_call_data*)&msg);
369372
return msg.err;
370373
}
371374

372375
static err_t _tcp_write_api(struct tcpip_api_call_data *api_call_msg){
373376
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
374377
msg->err = ERR_CONN;
375-
if(msg->pcb != pcb_recently_closed) {
378+
if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
376379
msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags);
377380
}
378-
pcb_recently_closed = NULL;
379381
return msg->err;
380382
}
381383

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) {
383385
if(!pcb){
384386
return ERR_CONN;
385387
}
386388
tcp_api_call_t msg;
387389
msg.pcb = pcb;
390+
msg.closed_slot = closed_slot;
388391
msg.write.data = data;
389392
msg.write.size = size;
390393
msg.write.apiflags = apiflags;
@@ -395,20 +398,20 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, const char* data, size_t size, uint8_
395398
static err_t _tcp_recved_api(struct tcpip_api_call_data *api_call_msg){
396399
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
397400
msg->err = ERR_CONN;
398-
if(msg->pcb != pcb_recently_closed) {
401+
if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
399402
msg->err = 0;
400403
tcp_recved(msg->pcb, msg->received);
401404
}
402-
pcb_recently_closed = NULL;
403405
return msg->err;
404406
}
405407

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) {
407409
if(!pcb){
408410
return ERR_CONN;
409411
}
410412
tcp_api_call_t msg;
411413
msg.pcb = pcb;
414+
msg.closed_slot = closed_slot;
412415
msg.received = len;
413416
tcpip_api_call(_tcp_recved_api, (struct tcpip_api_call_data*)&msg);
414417
return msg.err;
@@ -417,39 +420,39 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, size_t len) {
417420
static err_t _tcp_close_api(struct tcpip_api_call_data *api_call_msg){
418421
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
419422
msg->err = ERR_CONN;
420-
if(msg->pcb != pcb_recently_closed) {
423+
if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
421424
msg->err = tcp_close(msg->pcb);
422425
}
423-
pcb_recently_closed = NULL;
424426
return msg->err;
425427
}
426428

427-
static esp_err_t _tcp_close(tcp_pcb * pcb) {
429+
static esp_err_t _tcp_close(tcp_pcb * pcb, int8_t closed_slot) {
428430
if(!pcb){
429431
return ERR_CONN;
430432
}
431433
tcp_api_call_t msg;
432434
msg.pcb = pcb;
435+
msg.closed_slot = closed_slot;
433436
tcpip_api_call(_tcp_close_api, (struct tcpip_api_call_data*)&msg);
434437
return msg.err;
435438
}
436439

437440
static err_t _tcp_abort_api(struct tcpip_api_call_data *api_call_msg){
438441
tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg;
439442
msg->err = ERR_CONN;
440-
if(msg->pcb != pcb_recently_closed) {
443+
if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) {
441444
tcp_abort(msg->pcb);
442445
}
443-
pcb_recently_closed = NULL;
444446
return msg->err;
445447
}
446448

447-
static esp_err_t _tcp_abort(tcp_pcb * pcb) {
449+
static esp_err_t _tcp_abort(tcp_pcb * pcb, int8_t closed_slot) {
448450
if(!pcb){
449451
return ERR_CONN;
450452
}
451453
tcp_api_call_t msg;
452454
msg.pcb = pcb;
455+
msg.closed_slot = closed_slot;
453456
tcpip_api_call(_tcp_abort_api, (struct tcpip_api_call_data*)&msg);
454457
return msg.err;
455458
}
@@ -460,12 +463,13 @@ static err_t _tcp_connect_api(struct tcpip_api_call_data *api_call_msg){
460463
return msg->err;
461464
}
462465

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) {
464467
if(!pcb){
465468
return ESP_FAIL;
466469
}
467470
tcp_api_call_t msg;
468471
msg.pcb = pcb;
472+
msg.closed_slot = closed_slot;
469473
msg.connect.addr = addr;
470474
msg.connect.port = port;
471475
msg.connect.cb = cb;
@@ -485,6 +489,7 @@ static esp_err_t _tcp_bind(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port) {
485489
}
486490
tcp_api_call_t msg;
487491
msg.pcb = pcb;
492+
msg.closed_slot = -1;
488493
msg.bind.addr = addr;
489494
msg.bind.port = port;
490495
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) {
504509
}
505510
tcp_api_call_t msg;
506511
msg.pcb = pcb;
512+
msg.closed_slot = -1;
507513
msg.backlog = backlog?backlog:0xFF;
508514
tcpip_api_call(_tcp_listen_api, (struct tcpip_api_call_data*)&msg);
509515
return msg.pcb;
@@ -541,7 +547,18 @@ AsyncClient::AsyncClient(tcp_pcb* pcb)
541547
, next(NULL)
542548
{
543549
_pcb = pcb;
550+
_closed_slot = -1;
544551
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+
545562
_rx_last_packet = millis();
546563
tcp_arg(_pcb, this);
547564
tcp_recv(_pcb, &_tcp_recv);
@@ -567,6 +584,7 @@ AsyncClient& AsyncClient::operator=(const AsyncClient& other){
567584
}
568585

569586
_pcb = other._pcb;
587+
_closed_slot = other._closed_slot;
570588
if (_pcb) {
571589
_rx_last_packet = millis();
572590
tcp_arg(_pcb, this);
@@ -671,7 +689,7 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
671689
tcp_sent(pcb, &_tcp_sent);
672690
tcp_poll(pcb, &_tcp_poll, 1);
673691
//_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);
675693
return true;
676694
}
677695

@@ -697,14 +715,14 @@ bool AsyncClient::connect(const char* host, uint16_t port){
697715

698716
void AsyncClient::close(bool now){
699717
if(_pcb){
700-
_tcp_recved(_pcb, _rx_ack_len);
718+
_tcp_recved(_pcb, _closed_slot, _rx_ack_len);
701719
}
702720
_close();
703721
}
704722

705723
int8_t AsyncClient::abort(){
706724
if(_pcb) {
707-
_tcp_abort(_pcb);
725+
_tcp_abort(_pcb, _closed_slot );
708726
_pcb = NULL;
709727
}
710728
return ERR_ABRT;
@@ -727,7 +745,7 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
727745
}
728746
size_t will_send = (room < size) ? room : size;
729747
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);
731749
if(err != ERR_OK) {
732750
return 0;
733751
}
@@ -736,7 +754,7 @@ size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) {
736754

737755
bool AsyncClient::send(){
738756
int8_t err = ERR_OK;
739-
err = _tcp_output(_pcb);
757+
err = _tcp_output(_pcb, _closed_slot);
740758
if(err == ERR_OK){
741759
_pcb_busy = true;
742760
_pcb_sent_at = millis();
@@ -749,7 +767,7 @@ size_t AsyncClient::ack(size_t len){
749767
if(len > _rx_ack_len)
750768
len = _rx_ack_len;
751769
if(len){
752-
_tcp_recved(_pcb, len);
770+
_tcp_recved(_pcb, _closed_slot, len);
753771
}
754772
_rx_ack_len -= len;
755773
return len;
@@ -759,7 +777,7 @@ void AsyncClient::ackPacket(struct pbuf * pb){
759777
if(!pb){
760778
return;
761779
}
762-
_tcp_recved(_pcb, pb->len);
780+
_tcp_recved(_pcb, _closed_slot, pb->len);
763781
pbuf_free(pb);
764782
}
765783

@@ -778,7 +796,7 @@ int8_t AsyncClient::_close(){
778796
tcp_err(_pcb, NULL);
779797
tcp_poll(_pcb, NULL, 0);
780798
_tcp_clear_events(this);
781-
err = _tcp_close(_pcb);
799+
err = _tcp_close(_pcb, _closed_slot);
782800
if(err != ERR_OK) {
783801
err = abort();
784802
}
@@ -840,7 +858,8 @@ int8_t AsyncClient::_lwip_fin(tcp_pcb* pcb, int8_t err) {
840858
if(tcp_close(_pcb) != ERR_OK) {
841859
tcp_abort(_pcb);
842860
}
843-
pcb_recently_closed = _pcb;
861+
_closed_slots[_closed_slot] = _closed_index;
862+
++ _closed_index;
844863
_pcb = NULL;
845864
return ERR_OK;
846865
}
@@ -881,7 +900,7 @@ int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) {
881900
if(!_ack_pcb) {
882901
_rx_ack_len += b->len;
883902
} else if(_pcb) {
884-
_tcp_recved(_pcb, b->len);
903+
_tcp_recved(_pcb, _closed_slot, b->len);
885904
}
886905
pbuf_free(b);
887906
}
@@ -1228,7 +1247,7 @@ void AsyncServer::begin(){
12281247
err = _tcp_bind(_pcb, &local_addr, _port);
12291248

12301249
if (err != ERR_OK) {
1231-
_tcp_close(_pcb);
1250+
_tcp_close(_pcb, -1);
12321251
log_e("bind error: %d", err);
12331252
return;
12341253
}
@@ -1247,7 +1266,7 @@ void AsyncServer::end(){
12471266
if(_pcb){
12481267
tcp_arg(_pcb, NULL);
12491268
tcp_accept(_pcb, NULL);
1250-
_tcp_abort(_pcb);
1269+
_tcp_abort(_pcb, -1);
12511270
_pcb = NULL;
12521271
}
12531272
}

src/AsyncTCP.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ class AsyncClient {
141141

142142
protected:
143143
tcp_pcb* _pcb;
144+
int8_t _closed_slot;
144145

145146
AcConnectHandler _connect_cb;
146147
void* _connect_cb_arg;

0 commit comments

Comments
 (0)