Skip to content
This repository was archived by the owner on Sep 6, 2022. It is now read-only.

Commit 6008d5f

Browse files
committed
support for IPv6 in AsyncTCP fork by esphome, based on me-no-dev#105
1 parent 7c767c3 commit 6008d5f

File tree

2 files changed

+91
-10
lines changed

2 files changed

+91
-10
lines changed

src/AsyncTCP.cpp

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ void AsyncClient::onPoll(AcConnectHandler cb, void* arg){
693693
* Main Public Methods
694694
* */
695695

696-
bool AsyncClient::connect(IPAddress ip, uint16_t port){
696+
bool AsyncClient::_connect(ip_addr_t addr, uint16_t port){
697697
if (_pcb){
698698
log_w("already connected, state %d", _pcb->state);
699699
return false;
@@ -703,11 +703,7 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
703703
return false;
704704
}
705705

706-
ip_addr_t addr;
707-
addr.type = IPADDR_TYPE_V4;
708-
addr.u_addr.ip4.addr = ip;
709-
710-
tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
706+
tcp_pcb* pcb = tcp_new_ip_type(addr.type);
711707
if (!pcb){
712708
log_e("pcb == NULL");
713709
return false;
@@ -723,6 +719,22 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
723719
return true;
724720
}
725721

722+
bool AsyncClient::connect(IPAddress ip, uint16_t port){
723+
ip_addr_t addr;
724+
addr.type = IPADDR_TYPE_V4;
725+
addr.u_addr.ip4.addr = ip;
726+
727+
return _connect(addr, port);
728+
}
729+
730+
bool AsyncClient::connect(IPv6Address ip, uint16_t port){
731+
ip_addr_t addr;
732+
addr.type = IPADDR_TYPE_V6;
733+
memcpy(addr.u_addr.ip6.addr, static_cast<const uint32_t*>(ip), sizeof(uint32_t) * 4);
734+
735+
return _connect(addr, port);
736+
}
737+
726738
bool AsyncClient::connect(const char* host, uint16_t port){
727739
ip_addr_t addr;
728740

@@ -733,6 +745,9 @@ bool AsyncClient::connect(const char* host, uint16_t port){
733745

734746
err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
735747
if(err == ERR_OK) {
748+
if(addr.type == IPADDR_TYPE_V6) {
749+
return connect(IPv6Address(addr.u_addr.ip6.addr), port);
750+
}
736751
return connect(IPAddress(addr.u_addr.ip4.addr), port);
737752
} else if(err == ERR_INPROGRESS) {
738753
_connect_port = port;
@@ -1000,7 +1015,9 @@ int8_t AsyncClient::_poll(tcp_pcb* pcb){
10001015
void AsyncClient::_dns_found(struct ip_addr *ipaddr){
10011016
if(ipaddr && ipaddr->u_addr.ip4.addr){
10021017
connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port);
1003-
} else {
1018+
} else if(ipaddr && ipaddr->u_addr.ip6.addr){
1019+
connect(IPv6Address(ipaddr->u_addr.ip6.addr), _connect_port);
1020+
else {
10041021
if(_error_cb) {
10051022
_error_cb(_error_cb_arg, this, -55);
10061023
}
@@ -1091,6 +1108,15 @@ uint32_t AsyncClient::getRemoteAddress() {
10911108
return _pcb->remote_ip.u_addr.ip4.addr;
10921109
}
10931110

1111+
ip6_addr_t AsyncClient::getRemoteAddress6() {
1112+
if(!_pcb) {
1113+
ip6_addr_t nulladdr;
1114+
ip6_addr_set_zero(&nulladdr);
1115+
return nulladdr;
1116+
}
1117+
return _pcb->remote_ip.u_addr.ip6;
1118+
}
1119+
10941120
uint16_t AsyncClient::getRemotePort() {
10951121
if(!_pcb) {
10961122
return 0;
@@ -1105,6 +1131,15 @@ uint32_t AsyncClient::getLocalAddress() {
11051131
return _pcb->local_ip.u_addr.ip4.addr;
11061132
}
11071133

1134+
ip6_addr_t AsyncClient::getLocalAddress6() {
1135+
if(!_pcb) {
1136+
ip6_addr_t nulladdr;
1137+
ip6_addr_set_zero(&nulladdr);
1138+
return nulladdr;
1139+
}
1140+
return _pcb->local_ip.u_addr.ip6;
1141+
}
1142+
11081143
uint16_t AsyncClient::getLocalPort() {
11091144
if(!_pcb) {
11101145
return 0;
@@ -1116,14 +1151,24 @@ IPAddress AsyncClient::remoteIP() {
11161151
return IPAddress(getRemoteAddress());
11171152
}
11181153

1154+
IPv6Address AsyncClient::remoteIP6() {
1155+
return IPv6Address(getRemoteAddress6().addr);
1156+
}
1157+
1158+
11191159
uint16_t AsyncClient::remotePort() {
11201160
return getRemotePort();
11211161
}
11221162

1163+
11231164
IPAddress AsyncClient::localIP() {
11241165
return IPAddress(getLocalAddress());
11251166
}
11261167

1168+
IPv6Address AsyncClient::localIP6() {
1169+
return IPv6Address(getLocalAddress6().addr);
1170+
}
1171+
11271172
uint16_t AsyncClient::localPort() {
11281173
return getLocalPort();
11291174
}
@@ -1256,16 +1301,30 @@ int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err){
12561301

12571302
AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
12581303
: _port(port)
1304+
, _bind4(true)
12591305
, _addr(addr)
12601306
, _noDelay(false)
12611307
, _pcb(0)
12621308
, _connect_cb(0)
12631309
, _connect_cb_arg(0)
12641310
{}
12651311

1312+
AsyncServer::AsyncServer(IPv6Address addr, uint16_t port)
1313+
: _port(port)
1314+
, _bind6(true)
1315+
, _addr6(addr)
1316+
, _noDelay(false)
1317+
, _pcb(0)
1318+
, _connect_cb(0)
1319+
, _connect_cb_arg(0)
1320+
{}
1321+
12661322
AsyncServer::AsyncServer(uint16_t port)
12671323
: _port(port)
1324+
, _bind4(true)
1325+
, _bind6(true)
12681326
, _addr((uint32_t) IPADDR_ANY)
1327+
, _addr6()
12691328
, _noDelay(false)
12701329
, _pcb(0)
12711330
, _connect_cb(0)
@@ -1290,16 +1349,26 @@ void AsyncServer::begin(){
12901349
log_e("failed to start task");
12911350
return;
12921351
}
1293-
int8_t err;
1294-
_pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
1352+
int8_t err, bind_type;
1353+
1354+
if(_bind4 && _bind6) {
1355+
bind_type = IPADDR_TYPE_ANY;
1356+
} else if (_bind6) {
1357+
bind_type = IPADDR_TYPE_V6;
1358+
} else {
1359+
bind_type = IPADDR_TYPE_V4;
1360+
}
1361+
1362+
_pcb = tcp_new_ip_type(bind_type);
12951363
if (!_pcb){
12961364
log_e("_pcb == NULL");
12971365
return;
12981366
}
12991367

13001368
ip_addr_t local_addr;
1301-
local_addr.type = IPADDR_TYPE_V4;
1369+
local_addr.type = bind_type;
13021370
local_addr.u_addr.ip4.addr = (uint32_t) _addr;
1371+
memcpy(local_addr.u_addr.ip6.addr, static_cast<const uint32_t*>(_addr6), sizeof(uint32_t) * 4);
13031372
err = _tcp_bind(_pcb, &local_addr, _port);
13041373

13051374
if (err != ERR_OK) {

src/AsyncTCP.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define ASYNCTCP_H_
2424

2525
#include "IPAddress.h"
26+
#include "IPv6Address.h"
2627
#include "sdkconfig.h"
2728
#include <functional>
2829
extern "C" {
@@ -66,6 +67,7 @@ class AsyncClient {
6667
return !(*this == other);
6768
}
6869
bool connect(IPAddress ip, uint16_t port);
70+
bool connect(IPv6Address ip, uint16_t port);
6971
bool connect(const char* host, uint16_t port);
7072
void close(bool now = false);
7173
void stop();
@@ -100,14 +102,18 @@ class AsyncClient {
100102
bool getNoDelay();
101103

102104
uint32_t getRemoteAddress();
105+
ip6_addr_t getRemoteAddress6();
103106
uint16_t getRemotePort();
104107
uint32_t getLocalAddress();
108+
ip6_addr_t getLocalAddress6();
105109
uint16_t getLocalPort();
106110

107111
//compatibility
108112
IPAddress remoteIP();
113+
IPv6Address remoteIP6();
109114
uint16_t remotePort();
110115
IPAddress localIP();
116+
IPv6Address localIP6();
111117
uint16_t localPort();
112118

113119
void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect
@@ -140,6 +146,8 @@ class AsyncClient {
140146
tcp_pcb * pcb(){ return _pcb; }
141147

142148
protected:
149+
bool _connect(ip_addr_t addr, uint16_t port);
150+
143151
tcp_pcb* _pcb;
144152
int8_t _closed_slot;
145153

@@ -188,6 +196,7 @@ class AsyncClient {
188196
class AsyncServer {
189197
public:
190198
AsyncServer(IPAddress addr, uint16_t port);
199+
AsyncServer(IPv6Address addr, uint16_t port);
191200
AsyncServer(uint16_t port);
192201
~AsyncServer();
193202
void onClient(AcConnectHandler cb, void* arg);
@@ -203,7 +212,10 @@ class AsyncServer {
203212

204213
protected:
205214
uint16_t _port;
215+
bool _bind4 = false;
216+
bool _bind6 = false;
206217
IPAddress _addr;
218+
IPv6Address _addr6;
207219
bool _noDelay;
208220
tcp_pcb* _pcb;
209221
AcConnectHandler _connect_cb;

0 commit comments

Comments
 (0)