@@ -126,6 +126,20 @@ typedef struct {
126
126
};
127
127
} lwip_tcp_event_packet_t ;
128
128
129
+ // Detail class for interacting with AsyncClient internals, but without exposing the API
130
+ class AsyncTCP_detail {
131
+ public:
132
+ // Helper functions
133
+ static void __attribute__ ((visibility(" internal" ))) handle_async_event(lwip_tcp_event_packet_t *event);
134
+
135
+ // LwIP TCP event callbacks that (will) require privileged access
136
+ static int8_t __attribute__ ((visibility(" internal" ))) tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err);
137
+ static int8_t __attribute__ ((visibility(" internal" ))) tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len);
138
+ static void __attribute__ ((visibility(" internal" ))) tcp_error(void *arg, int8_t err);
139
+ static int8_t __attribute__ ((visibility(" internal" ))) tcp_poll(void *arg, struct tcp_pcb *pcb);
140
+ static int8_t __attribute__ ((visibility(" internal" ))) tcp_accept(void *arg, tcp_pcb *pcb, int8_t err);
141
+ };
142
+
129
143
static QueueHandle_t _async_queue = NULL ;
130
144
static TaskHandle_t _async_service_task_handle = NULL ;
131
145
@@ -272,36 +286,36 @@ static bool _remove_events_with_arg(void *arg) {
272
286
return true ;
273
287
}
274
288
275
- static void _handle_async_event (lwip_tcp_event_packet_t *e) {
289
+ void AsyncTCP_detail::handle_async_event (lwip_tcp_event_packet_t *e) {
276
290
if (e->arg == NULL ) {
277
291
// do nothing when arg is NULL
278
292
// ets_printf("event arg == NULL: 0x%08x\n", e->recv.pcb);
279
293
} else if (e->event == LWIP_TCP_CLEAR) {
280
294
_remove_events_with_arg (e->arg );
281
295
} else if (e->event == LWIP_TCP_RECV) {
282
296
// ets_printf("-R: 0x%08x\n", e->recv.pcb);
283
- AsyncClient::_s_recv (e->arg , e->recv .pcb , e->recv .pb , e->recv .err );
297
+ reinterpret_cast < AsyncClient *> (e->arg )-> _recv ( e->recv .pcb , e->recv .pb , e->recv .err );
284
298
} else if (e->event == LWIP_TCP_FIN) {
285
299
// ets_printf("-F: 0x%08x\n", e->fin.pcb);
286
- AsyncClient::_s_fin (e->arg , e->fin .pcb , e->fin .err );
300
+ reinterpret_cast < AsyncClient *> (e->arg )-> _fin ( e->fin .pcb , e->fin .err );
287
301
} else if (e->event == LWIP_TCP_SENT) {
288
302
// ets_printf("-S: 0x%08x\n", e->sent.pcb);
289
- AsyncClient::_s_sent (e->arg , e->sent .pcb , e->sent .len );
303
+ reinterpret_cast < AsyncClient *> (e->arg )-> _sent ( e->sent .pcb , e->sent .len );
290
304
} else if (e->event == LWIP_TCP_POLL) {
291
305
// ets_printf("-P: 0x%08x\n", e->poll.pcb);
292
- AsyncClient::_s_poll (e->arg , e->poll .pcb );
306
+ reinterpret_cast < AsyncClient *> (e->arg )-> _poll ( e->poll .pcb );
293
307
} else if (e->event == LWIP_TCP_ERROR) {
294
308
// ets_printf("-E: 0x%08x %d\n", e->arg, e->error.err);
295
- AsyncClient::_s_error (e->arg , e->error .err );
309
+ reinterpret_cast < AsyncClient *> (e->arg )-> _error ( e->error .err );
296
310
} else if (e->event == LWIP_TCP_CONNECTED) {
297
311
// ets_printf("C: 0x%08x 0x%08x %d\n", e->arg, e->connected.pcb, e->connected.err);
298
- AsyncClient::_s_connected (e->arg , e->connected .pcb , e->connected .err );
312
+ reinterpret_cast < AsyncClient *> (e->arg )-> _connected ( e->connected .pcb , e->connected .err );
299
313
} else if (e->event == LWIP_TCP_ACCEPT) {
300
314
// ets_printf("A: 0x%08x 0x%08x\n", e->arg, e->accept.client);
301
- AsyncServer::_s_accepted (e->arg , e->accept .client );
315
+ reinterpret_cast < AsyncServer *> (e->arg )-> _accepted ( e->accept .client );
302
316
} else if (e->event == LWIP_TCP_DNS) {
303
317
// ets_printf("D: 0x%08x %s = %s\n", e->arg, e->dns.name, ipaddr_ntoa(&e->dns.addr));
304
- AsyncClient::_s_dns_found (e->dns . name , &e->dns .addr , e-> arg );
318
+ reinterpret_cast < AsyncClient *> (e->arg )-> _dns_found ( &e->dns .addr );
305
319
}
306
320
free ((void *)(e));
307
321
}
@@ -315,7 +329,7 @@ static void _async_service_task(void *pvParameters) {
315
329
lwip_tcp_event_packet_t *packet = NULL ;
316
330
for (;;) {
317
331
if (_get_async_event (&packet)) {
318
- _handle_async_event (packet);
332
+ AsyncTCP_detail::handle_async_event (packet);
319
333
}
320
334
#if CONFIG_ASYNC_TCP_USE_WDT
321
335
esp_task_wdt_reset ();
@@ -403,7 +417,7 @@ static int8_t _tcp_connected(void *arg, tcp_pcb *pcb, int8_t err) {
403
417
return ERR_OK;
404
418
}
405
419
406
- static int8_t _tcp_poll (void *arg, struct tcp_pcb *pcb) {
420
+ int8_t AsyncTCP_detail::tcp_poll (void *arg, struct tcp_pcb *pcb) {
407
421
// throttle polling events queueing when event queue is getting filled up, let it handle _onack's
408
422
// log_d("qs:%u", uxQueueMessagesWaiting(_async_queue));
409
423
if (uxQueueMessagesWaiting (_async_queue) > (rand () % CONFIG_ASYNC_TCP_QUEUE_SIZE / 2 + CONFIG_ASYNC_TCP_QUEUE_SIZE / 4 )) {
@@ -428,7 +442,7 @@ static int8_t _tcp_poll(void *arg, struct tcp_pcb *pcb) {
428
442
return ERR_OK;
429
443
}
430
444
431
- static int8_t _tcp_recv (void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err) {
445
+ int8_t AsyncTCP_detail::tcp_recv (void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err) {
432
446
lwip_tcp_event_packet_t *e = (lwip_tcp_event_packet_t *)malloc (sizeof (lwip_tcp_event_packet_t ));
433
447
if (!e) {
434
448
log_e (" Failed to allocate event packet" );
@@ -447,7 +461,7 @@ static int8_t _tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t
447
461
e->fin .pcb = pcb;
448
462
e->fin .err = err;
449
463
// close the PCB in LwIP thread
450
- AsyncClient::_s_lwip_fin (e-> arg , e->fin .pcb , e->fin .err );
464
+ reinterpret_cast < AsyncClient *>(arg)-> _lwip_fin ( e->fin .pcb , e->fin .err );
451
465
}
452
466
if (!_send_async_event (&e)) {
453
467
free ((void *)(e));
@@ -456,7 +470,7 @@ static int8_t _tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t
456
470
return ERR_OK;
457
471
}
458
472
459
- static int8_t _tcp_sent (void *arg, struct tcp_pcb *pcb, uint16_t len) {
473
+ int8_t AsyncTCP_detail::tcp_sent (void *arg, struct tcp_pcb *pcb, uint16_t len) {
460
474
// ets_printf("+S: 0x%08x\n", pcb);
461
475
lwip_tcp_event_packet_t *e = (lwip_tcp_event_packet_t *)malloc (sizeof (lwip_tcp_event_packet_t ));
462
476
if (!e) {
@@ -474,16 +488,16 @@ static int8_t _tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len) {
474
488
return ERR_OK;
475
489
}
476
490
477
- void AsyncClient::_tcp_error (void *arg, int8_t err) {
491
+ void AsyncTCP_detail::tcp_error (void *arg, int8_t err) {
478
492
// ets_printf("+E: 0x%08x\n", arg);
479
493
AsyncClient *client = reinterpret_cast <AsyncClient *>(arg);
480
494
if (client && client->_pcb ) {
481
495
tcp_arg (client->_pcb , NULL );
482
496
if (client->_pcb ->state == LISTEN) {
483
- tcp_sent (client->_pcb , NULL );
484
- tcp_recv (client->_pcb , NULL );
485
- tcp_err (client->_pcb , NULL );
486
- tcp_poll (client->_pcb , NULL , 0 );
497
+ :: tcp_sent (client->_pcb, NULL );
498
+ :: tcp_recv (client->_pcb, NULL );
499
+ :: tcp_err (client->_pcb, NULL );
500
+ :: tcp_poll (client->_pcb, NULL , 0 );
487
501
}
488
502
client->_pcb = nullptr ;
489
503
client->_free_closed_slot ();
@@ -523,23 +537,6 @@ static void _tcp_dns_found(const char *name, struct ip_addr *ipaddr, void *arg)
523
537
}
524
538
}
525
539
526
- // Used to switch out from LwIP thread
527
- static int8_t _tcp_accept (void *arg, AsyncClient *client) {
528
- lwip_tcp_event_packet_t *e = (lwip_tcp_event_packet_t *)malloc (sizeof (lwip_tcp_event_packet_t ));
529
- if (!e) {
530
- log_e (" Failed to allocate event packet" );
531
- return ERR_MEM;
532
- }
533
- e->event = LWIP_TCP_ACCEPT;
534
- e->arg = arg;
535
- e->accept .client = client;
536
- if (!_prepend_async_event (&e)) {
537
- free ((void *)(e));
538
- return ERR_TIMEOUT;
539
- }
540
- return ERR_OK;
541
- }
542
-
543
540
/*
544
541
* TCP/IP API Calls
545
542
* */
@@ -749,10 +746,10 @@ AsyncClient::AsyncClient(tcp_pcb *pcb)
749
746
if (_pcb) {
750
747
_rx_last_packet = millis ();
751
748
tcp_arg (_pcb, this );
752
- tcp_recv (_pcb, &_tcp_recv );
753
- tcp_sent (_pcb, &_tcp_sent );
754
- tcp_err (_pcb, &_tcp_error );
755
- tcp_poll (_pcb, &_tcp_poll , CONFIG_ASYNC_TCP_POLL_TIMER);
749
+ tcp_recv (_pcb, &AsyncTCP_detail::tcp_recv );
750
+ tcp_sent (_pcb, &AsyncTCP_detail::tcp_sent );
751
+ tcp_err (_pcb, &AsyncTCP_detail::tcp_error );
752
+ tcp_poll (_pcb, &AsyncTCP_detail::tcp_poll , CONFIG_ASYNC_TCP_POLL_TIMER);
756
753
if (!_allocate_closed_slot ()) {
757
754
_close ();
758
755
}
@@ -846,10 +843,10 @@ bool AsyncClient::connect(ip_addr_t addr, uint16_t port) {
846
843
return false ;
847
844
}
848
845
tcp_arg (pcb, this );
849
- tcp_err (pcb, &_tcp_error );
850
- tcp_recv (pcb, &_tcp_recv );
851
- tcp_sent (pcb, &_tcp_sent );
852
- tcp_poll (pcb, &_tcp_poll , CONFIG_ASYNC_TCP_POLL_TIMER);
846
+ tcp_err (pcb, &AsyncTCP_detail::tcp_error );
847
+ tcp_recv (pcb, &AsyncTCP_detail::tcp_recv );
848
+ tcp_sent (pcb, &AsyncTCP_detail::tcp_sent );
849
+ tcp_poll (pcb, &AsyncTCP_detail::tcp_poll , CONFIG_ASYNC_TCP_POLL_TIMER);
853
850
}
854
851
855
852
esp_err_t err = _tcp_connect (pcb, _closed_slot, &addr, port, (tcp_connected_fn)&_tcp_connected);
@@ -1479,42 +1476,6 @@ const char *AsyncClient::stateToString() const {
1479
1476
}
1480
1477
}
1481
1478
1482
- /*
1483
- * Static Callbacks (LwIP C2C++ interconnect)
1484
- * */
1485
-
1486
- void AsyncClient::_s_dns_found (const char *name, struct ip_addr *ipaddr, void *arg) {
1487
- reinterpret_cast <AsyncClient *>(arg)->_dns_found (ipaddr);
1488
- }
1489
-
1490
- int8_t AsyncClient::_s_poll (void *arg, struct tcp_pcb *pcb) {
1491
- return reinterpret_cast <AsyncClient *>(arg)->_poll (pcb);
1492
- }
1493
-
1494
- int8_t AsyncClient::_s_recv (void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err) {
1495
- return reinterpret_cast <AsyncClient *>(arg)->_recv (pcb, pb, err);
1496
- }
1497
-
1498
- int8_t AsyncClient::_s_fin (void *arg, struct tcp_pcb *pcb, int8_t err) {
1499
- return reinterpret_cast <AsyncClient *>(arg)->_fin (pcb, err);
1500
- }
1501
-
1502
- int8_t AsyncClient::_s_lwip_fin (void *arg, struct tcp_pcb *pcb, int8_t err) {
1503
- return reinterpret_cast <AsyncClient *>(arg)->_lwip_fin (pcb, err);
1504
- }
1505
-
1506
- int8_t AsyncClient::_s_sent (void *arg, struct tcp_pcb *pcb, uint16_t len) {
1507
- return reinterpret_cast <AsyncClient *>(arg)->_sent (pcb, len);
1508
- }
1509
-
1510
- void AsyncClient::_s_error (void *arg, int8_t err) {
1511
- reinterpret_cast <AsyncClient *>(arg)->_error (err);
1512
- }
1513
-
1514
- int8_t AsyncClient::_s_connected (void *arg, struct tcp_pcb *pcb, int8_t err) {
1515
- return reinterpret_cast <AsyncClient *>(arg)->_connected (pcb, err);
1516
- }
1517
-
1518
1479
/*
1519
1480
Async TCP Server
1520
1481
*/
@@ -1590,7 +1551,7 @@ void AsyncServer::begin() {
1590
1551
}
1591
1552
tcp_core_guard tcg;
1592
1553
tcp_arg (_pcb, (void *)this );
1593
- tcp_accept (_pcb, &_s_accept );
1554
+ tcp_accept (_pcb, &AsyncTCP_detail::tcp_accept );
1594
1555
}
1595
1556
1596
1557
void AsyncServer::end () {
@@ -1606,18 +1567,28 @@ void AsyncServer::end() {
1606
1567
}
1607
1568
1608
1569
// runs on LwIP thread
1609
- int8_t AsyncServer::_accept ( tcp_pcb *pcb, int8_t err) {
1570
+ int8_t AsyncTCP_detail::tcp_accept ( void *arg, tcp_pcb *pcb, int8_t err) {
1610
1571
if (!pcb) {
1611
1572
log_e (" _accept failed: pcb is NULL" );
1612
1573
return ERR_ABRT;
1613
1574
}
1614
- if (_connect_cb) {
1575
+ auto server = reinterpret_cast <AsyncServer *>(arg);
1576
+ if (server->_connect_cb ) {
1615
1577
AsyncClient *c = new (std::nothrow) AsyncClient (pcb);
1616
1578
if (c && c->pcb ()) {
1617
- c->setNoDelay (_noDelay);
1618
- if (_tcp_accept (this , c) == ERR_OK) {
1619
- return ERR_OK; // success
1579
+ c->setNoDelay (server->_noDelay );
1580
+
1581
+ lwip_tcp_event_packet_t *e = (lwip_tcp_event_packet_t *)malloc (sizeof (lwip_tcp_event_packet_t ));
1582
+ if (e) {
1583
+ e->event = LWIP_TCP_ACCEPT;
1584
+ e->arg = arg;
1585
+ e->accept .client = c;
1586
+ if (_prepend_async_event (&e)) {
1587
+ return ERR_OK; // success
1588
+ }
1589
+ free ((void *)(e));
1620
1590
}
1591
+
1621
1592
// Couldn't allocate accept event
1622
1593
// We can't let the client object call in to close, as we're on the LWIP thread; it could deadlock trying to RPC to itself
1623
1594
c->_pcb = nullptr ;
@@ -1662,11 +1633,3 @@ uint8_t AsyncServer::status() const {
1662
1633
}
1663
1634
return _pcb->state ;
1664
1635
}
1665
-
1666
- int8_t AsyncServer::_s_accept (void *arg, tcp_pcb *pcb, int8_t err) {
1667
- return reinterpret_cast <AsyncServer *>(arg)->_accept (pcb, err);
1668
- }
1669
-
1670
- int8_t AsyncServer::_s_accepted (void *arg, AsyncClient *client) {
1671
- return reinterpret_cast <AsyncServer *>(arg)->_accepted (client);
1672
- }
0 commit comments