@@ -111,6 +111,20 @@ typedef struct {
111
111
};
112
112
} lwip_tcp_event_packet_t ;
113
113
114
+ // Detail class for interacting with AsyncClient internals, but without exposing the API
115
+ class AsyncTCP_detail {
116
+ public:
117
+ // Helper functions
118
+ static void __attribute__ ((visibility(" internal" ))) handle_async_event(lwip_tcp_event_packet_t *event);
119
+
120
+ // LwIP TCP event callbacks that (will) require privileged access
121
+ static int8_t __attribute__ ((visibility(" internal" ))) tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err);
122
+ static int8_t __attribute__ ((visibility(" internal" ))) tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len);
123
+ static void __attribute__ ((visibility(" internal" ))) tcp_error(void *arg, int8_t err);
124
+ static int8_t __attribute__ ((visibility(" internal" ))) tcp_poll(void *arg, struct tcp_pcb *pcb);
125
+ static int8_t __attribute__ ((visibility(" internal" ))) tcp_accept(void *arg, tcp_pcb *pcb, int8_t err);
126
+ };
127
+
114
128
static QueueHandle_t _async_queue = NULL ;
115
129
static TaskHandle_t _async_service_task_handle = NULL ;
116
130
@@ -257,36 +271,36 @@ static bool _remove_events_with_arg(void *arg) {
257
271
return true ;
258
272
}
259
273
260
- static void _handle_async_event (lwip_tcp_event_packet_t *e) {
274
+ void AsyncTCP_detail::handle_async_event (lwip_tcp_event_packet_t *e) {
261
275
if (e->arg == NULL ) {
262
276
// do nothing when arg is NULL
263
277
// ets_printf("event arg == NULL: 0x%08x\n", e->recv.pcb);
264
278
} else if (e->event == LWIP_TCP_CLEAR) {
265
279
_remove_events_with_arg (e->arg );
266
280
} else if (e->event == LWIP_TCP_RECV) {
267
281
// ets_printf("-R: 0x%08x\n", e->recv.pcb);
268
- AsyncClient::_s_recv (e->arg , e->recv .pcb , e->recv .pb , e->recv .err );
282
+ reinterpret_cast < AsyncClient *> (e->arg )-> _recv ( e->recv .pcb , e->recv .pb , e->recv .err );
269
283
} else if (e->event == LWIP_TCP_FIN) {
270
284
// ets_printf("-F: 0x%08x\n", e->fin.pcb);
271
- AsyncClient::_s_fin (e->arg , e->fin .pcb , e->fin .err );
285
+ reinterpret_cast < AsyncClient *> (e->arg )-> _fin ( e->fin .pcb , e->fin .err );
272
286
} else if (e->event == LWIP_TCP_SENT) {
273
287
// ets_printf("-S: 0x%08x\n", e->sent.pcb);
274
- AsyncClient::_s_sent (e->arg , e->sent .pcb , e->sent .len );
288
+ reinterpret_cast < AsyncClient *> (e->arg )-> _sent ( e->sent .pcb , e->sent .len );
275
289
} else if (e->event == LWIP_TCP_POLL) {
276
290
// ets_printf("-P: 0x%08x\n", e->poll.pcb);
277
- AsyncClient::_s_poll (e->arg , e->poll .pcb );
291
+ reinterpret_cast < AsyncClient *> (e->arg )-> _poll ( e->poll .pcb );
278
292
} else if (e->event == LWIP_TCP_ERROR) {
279
293
// ets_printf("-E: 0x%08x %d\n", e->arg, e->error.err);
280
- AsyncClient::_s_error (e->arg , e->error .err );
294
+ reinterpret_cast < AsyncClient *> (e->arg )-> _error ( e->error .err );
281
295
} else if (e->event == LWIP_TCP_CONNECTED) {
282
296
// ets_printf("C: 0x%08x 0x%08x %d\n", e->arg, e->connected.pcb, e->connected.err);
283
- AsyncClient::_s_connected (e->arg , e->connected .pcb , e->connected .err );
297
+ reinterpret_cast < AsyncClient *> (e->arg )-> _connected ( e->connected .pcb , e->connected .err );
284
298
} else if (e->event == LWIP_TCP_ACCEPT) {
285
299
// ets_printf("A: 0x%08x 0x%08x\n", e->arg, e->accept.client);
286
- AsyncServer::_s_accepted (e->arg , e->accept .client );
300
+ reinterpret_cast < AsyncServer *> (e->arg )-> _accepted ( e->accept .client );
287
301
} else if (e->event == LWIP_TCP_DNS) {
288
302
// ets_printf("D: 0x%08x %s = %s\n", e->arg, e->dns.name, ipaddr_ntoa(&e->dns.addr));
289
- AsyncClient::_s_dns_found (e->dns . name , &e->dns .addr , e-> arg );
303
+ reinterpret_cast < AsyncClient *> (e->arg )-> _dns_found ( &e->dns .addr );
290
304
}
291
305
free ((void *)(e));
292
306
}
@@ -300,7 +314,7 @@ static void _async_service_task(void *pvParameters) {
300
314
lwip_tcp_event_packet_t *packet = NULL ;
301
315
for (;;) {
302
316
if (_get_async_event (&packet)) {
303
- _handle_async_event (packet);
317
+ AsyncTCP_detail::handle_async_event (packet);
304
318
}
305
319
#if CONFIG_ASYNC_TCP_USE_WDT
306
320
esp_task_wdt_reset ();
@@ -388,7 +402,7 @@ static int8_t _tcp_connected(void *arg, tcp_pcb *pcb, int8_t err) {
388
402
return ERR_OK;
389
403
}
390
404
391
- static int8_t _tcp_poll (void *arg, struct tcp_pcb *pcb) {
405
+ int8_t AsyncTCP_detail::tcp_poll (void *arg, struct tcp_pcb *pcb) {
392
406
// throttle polling events queueing when event queue is getting filled up, let it handle _onack's
393
407
// log_d("qs:%u", uxQueueMessagesWaiting(_async_queue));
394
408
if (uxQueueMessagesWaiting (_async_queue) > (rand () % CONFIG_ASYNC_TCP_QUEUE_SIZE / 2 + CONFIG_ASYNC_TCP_QUEUE_SIZE / 4 )) {
@@ -413,7 +427,7 @@ static int8_t _tcp_poll(void *arg, struct tcp_pcb *pcb) {
413
427
return ERR_OK;
414
428
}
415
429
416
- static int8_t _tcp_recv (void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err) {
430
+ int8_t AsyncTCP_detail::tcp_recv (void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err) {
417
431
lwip_tcp_event_packet_t *e = (lwip_tcp_event_packet_t *)malloc (sizeof (lwip_tcp_event_packet_t ));
418
432
if (!e) {
419
433
log_e (" Failed to allocate event packet" );
@@ -432,7 +446,7 @@ static int8_t _tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t
432
446
e->fin .pcb = pcb;
433
447
e->fin .err = err;
434
448
// close the PCB in LwIP thread
435
- AsyncClient::_s_lwip_fin (e-> arg , e->fin .pcb , e->fin .err );
449
+ reinterpret_cast < AsyncClient *>(arg)-> _lwip_fin ( e->fin .pcb , e->fin .err );
436
450
}
437
451
if (!_send_async_event (&e)) {
438
452
free ((void *)(e));
@@ -441,7 +455,7 @@ static int8_t _tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t
441
455
return ERR_OK;
442
456
}
443
457
444
- static int8_t _tcp_sent (void *arg, struct tcp_pcb *pcb, uint16_t len) {
458
+ int8_t AsyncTCP_detail::tcp_sent (void *arg, struct tcp_pcb *pcb, uint16_t len) {
445
459
// ets_printf("+S: 0x%08x\n", pcb);
446
460
lwip_tcp_event_packet_t *e = (lwip_tcp_event_packet_t *)malloc (sizeof (lwip_tcp_event_packet_t ));
447
461
if (!e) {
@@ -459,16 +473,16 @@ static int8_t _tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len) {
459
473
return ERR_OK;
460
474
}
461
475
462
- void AsyncClient::_tcp_error (void *arg, int8_t err) {
476
+ void AsyncTCP_detail::tcp_error (void *arg, int8_t err) {
463
477
// ets_printf("+E: 0x%08x\n", arg);
464
478
AsyncClient *client = reinterpret_cast <AsyncClient *>(arg);
465
479
if (client && client->_pcb ) {
466
480
tcp_arg (client->_pcb , NULL );
467
481
if (client->_pcb ->state == LISTEN) {
468
- tcp_sent (client->_pcb , NULL );
469
- tcp_recv (client->_pcb , NULL );
470
- tcp_err (client->_pcb , NULL );
471
- tcp_poll (client->_pcb , NULL , 0 );
482
+ :: tcp_sent (client->_pcb, NULL );
483
+ :: tcp_recv (client->_pcb, NULL );
484
+ :: tcp_err (client->_pcb, NULL );
485
+ :: tcp_poll (client->_pcb, NULL , 0 );
472
486
}
473
487
client->_pcb = nullptr ;
474
488
client->_free_closed_slot ();
@@ -508,23 +522,6 @@ static void _tcp_dns_found(const char *name, struct ip_addr *ipaddr, void *arg)
508
522
}
509
523
}
510
524
511
- // Used to switch out from LwIP thread
512
- static int8_t _tcp_accept (void *arg, AsyncClient *client) {
513
- lwip_tcp_event_packet_t *e = (lwip_tcp_event_packet_t *)malloc (sizeof (lwip_tcp_event_packet_t ));
514
- if (!e) {
515
- log_e (" Failed to allocate event packet" );
516
- return ERR_MEM;
517
- }
518
- e->event = LWIP_TCP_ACCEPT;
519
- e->arg = arg;
520
- e->accept .client = client;
521
- if (!_prepend_async_event (&e)) {
522
- free ((void *)(e));
523
- return ERR_TIMEOUT;
524
- }
525
- return ERR_OK;
526
- }
527
-
528
525
/*
529
526
* TCP/IP API Calls
530
527
* */
@@ -734,10 +731,10 @@ AsyncClient::AsyncClient(tcp_pcb *pcb)
734
731
if (_pcb) {
735
732
_rx_last_packet = millis ();
736
733
tcp_arg (_pcb, this );
737
- tcp_recv (_pcb, &_tcp_recv );
738
- tcp_sent (_pcb, &_tcp_sent );
739
- tcp_err (_pcb, &_tcp_error );
740
- tcp_poll (_pcb, &_tcp_poll , CONFIG_ASYNC_TCP_POLL_TIMER);
734
+ tcp_recv (_pcb, &AsyncTCP_detail::tcp_recv );
735
+ tcp_sent (_pcb, &AsyncTCP_detail::tcp_sent );
736
+ tcp_err (_pcb, &AsyncTCP_detail::tcp_error );
737
+ tcp_poll (_pcb, &AsyncTCP_detail::tcp_poll , CONFIG_ASYNC_TCP_POLL_TIMER);
741
738
if (!_allocate_closed_slot ()) {
742
739
_close ();
743
740
}
@@ -831,10 +828,10 @@ bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) {
831
828
return false ;
832
829
}
833
830
tcp_arg (pcb, this );
834
- tcp_err (pcb, &_tcp_error );
835
- tcp_recv (pcb, &_tcp_recv );
836
- tcp_sent (pcb, &_tcp_sent );
837
- tcp_poll (pcb, &_tcp_poll , CONFIG_ASYNC_TCP_POLL_TIMER);
831
+ tcp_err (pcb, &AsyncTCP_detail::tcp_error );
832
+ tcp_recv (pcb, &AsyncTCP_detail::tcp_recv );
833
+ tcp_sent (pcb, &AsyncTCP_detail::tcp_sent );
834
+ tcp_poll (pcb, &AsyncTCP_detail::tcp_poll , CONFIG_ASYNC_TCP_POLL_TIMER);
838
835
}
839
836
840
837
esp_err_t err = _tcp_connect (pcb, _closed_slot, &addr, port, (tcp_connected_fn)&_tcp_connected);
@@ -1455,42 +1452,6 @@ const char *AsyncClient::stateToString() const {
1455
1452
}
1456
1453
}
1457
1454
1458
- /*
1459
- * Static Callbacks (LwIP C2C++ interconnect)
1460
- * */
1461
-
1462
- void AsyncClient::_s_dns_found (const char *name, struct ip_addr *ipaddr, void *arg) {
1463
- reinterpret_cast <AsyncClient *>(arg)->_dns_found (ipaddr);
1464
- }
1465
-
1466
- int8_t AsyncClient::_s_poll (void *arg, struct tcp_pcb *pcb) {
1467
- return reinterpret_cast <AsyncClient *>(arg)->_poll (pcb);
1468
- }
1469
-
1470
- int8_t AsyncClient::_s_recv (void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err) {
1471
- return reinterpret_cast <AsyncClient *>(arg)->_recv (pcb, pb, err);
1472
- }
1473
-
1474
- int8_t AsyncClient::_s_fin (void *arg, struct tcp_pcb *pcb, int8_t err) {
1475
- return reinterpret_cast <AsyncClient *>(arg)->_fin (pcb, err);
1476
- }
1477
-
1478
- int8_t AsyncClient::_s_lwip_fin (void *arg, struct tcp_pcb *pcb, int8_t err) {
1479
- return reinterpret_cast <AsyncClient *>(arg)->_lwip_fin (pcb, err);
1480
- }
1481
-
1482
- int8_t AsyncClient::_s_sent (void *arg, struct tcp_pcb *pcb, uint16_t len) {
1483
- return reinterpret_cast <AsyncClient *>(arg)->_sent (pcb, len);
1484
- }
1485
-
1486
- void AsyncClient::_s_error (void *arg, int8_t err) {
1487
- reinterpret_cast <AsyncClient *>(arg)->_error (err);
1488
- }
1489
-
1490
- int8_t AsyncClient::_s_connected (void *arg, struct tcp_pcb *pcb, int8_t err) {
1491
- return reinterpret_cast <AsyncClient *>(arg)->_connected (pcb, err);
1492
- }
1493
-
1494
1455
/*
1495
1456
Async TCP Server
1496
1457
*/
@@ -1580,7 +1541,7 @@ void AsyncServer::begin() {
1580
1541
}
1581
1542
tcp_core_guard tcg;
1582
1543
tcp_arg (_pcb, (void *)this );
1583
- tcp_accept (_pcb, &_s_accept );
1544
+ tcp_accept (_pcb, &AsyncTCP_detail::tcp_accept );
1584
1545
}
1585
1546
1586
1547
void AsyncServer::end () {
@@ -1596,18 +1557,28 @@ void AsyncServer::end() {
1596
1557
}
1597
1558
1598
1559
// runs on LwIP thread
1599
- int8_t AsyncServer::_accept ( tcp_pcb *pcb, int8_t err) {
1560
+ int8_t AsyncTCP_detail::tcp_accept ( void *arg, tcp_pcb *pcb, int8_t err) {
1600
1561
if (!pcb) {
1601
1562
log_e (" _accept failed: pcb is NULL" );
1602
1563
return ERR_ABRT;
1603
1564
}
1604
- if (_connect_cb) {
1565
+ auto server = reinterpret_cast <AsyncServer *>(arg);
1566
+ if (server->_connect_cb ) {
1605
1567
AsyncClient *c = new (std::nothrow) AsyncClient (pcb);
1606
1568
if (c && c->pcb ()) {
1607
- c->setNoDelay (_noDelay);
1608
- if (_tcp_accept (this , c) == ERR_OK) {
1609
- return ERR_OK; // success
1569
+ c->setNoDelay (server->_noDelay );
1570
+
1571
+ lwip_tcp_event_packet_t *e = (lwip_tcp_event_packet_t *)malloc (sizeof (lwip_tcp_event_packet_t ));
1572
+ if (e) {
1573
+ e->event = LWIP_TCP_ACCEPT;
1574
+ e->arg = arg;
1575
+ e->accept .client = c;
1576
+ if (_prepend_async_event (&e)) {
1577
+ return ERR_OK; // success
1578
+ }
1579
+ free ((void *)(e));
1610
1580
}
1581
+
1611
1582
// Couldn't allocate accept event
1612
1583
// 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
1613
1584
c->_pcb = nullptr ;
@@ -1652,11 +1623,3 @@ uint8_t AsyncServer::status() const {
1652
1623
}
1653
1624
return _pcb->state ;
1654
1625
}
1655
-
1656
- int8_t AsyncServer::_s_accept (void *arg, tcp_pcb *pcb, int8_t err) {
1657
- return reinterpret_cast <AsyncServer *>(arg)->_accept (pcb, err);
1658
- }
1659
-
1660
- int8_t AsyncServer::_s_accepted (void *arg, AsyncClient *client) {
1661
- return reinterpret_cast <AsyncServer *>(arg)->_accepted (client);
1662
- }
0 commit comments