Skip to content

Commit 42a8644

Browse files
HeManpidpawel
andauthored
IPv6 support added (#5)
Co-authored-by: Paweł pidpawel Kozubal <[email protected]>
1 parent dc64fed commit 42a8644

File tree

2 files changed

+96
-28
lines changed

2 files changed

+96
-28
lines changed

src/AsyncTCP.cpp

Lines changed: 78 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ void AsyncClient::onPoll(AcConnectHandler cb, void* arg){
695695
* Main Public Methods
696696
* */
697697

698-
bool AsyncClient::connect(IPAddress ip, uint16_t port){
698+
bool AsyncClient::_connect(ip_addr_t addr, uint16_t port){
699699
if (_pcb){
700700
log_w("already connected, state %d", _pcb->state);
701701
return false;
@@ -705,15 +705,7 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
705705
return false;
706706
}
707707

708-
ip_addr_t addr;
709-
#if LWIP_IPV4 && LWIP_IPV6
710-
addr.type = IPADDR_TYPE_V4;
711-
addr.u_addr.ip4.addr = ip;
712-
#else
713-
addr.addr = ip;
714-
#endif
715-
716-
tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
708+
tcp_pcb* pcb = tcp_new_ip_type(addr.type);
717709
if (!pcb){
718710
log_e("pcb == NULL");
719711
return false;
@@ -724,22 +716,39 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
724716
tcp_recv(pcb, &_tcp_recv);
725717
tcp_sent(pcb, &_tcp_sent);
726718
tcp_poll(pcb, &_tcp_poll, 1);
727-
//_tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected);
728719
_tcp_connect(pcb, _closed_slot, &addr, port,(tcp_connected_fn)&_tcp_connected);
729720
return true;
730721
}
731722

723+
bool AsyncClient::connect(IPAddress ip, uint16_t port){
724+
ip_addr_t addr;
725+
addr.type = IPADDR_TYPE_V4;
726+
addr.u_addr.ip4.addr = ip;
727+
728+
return _connect(addr, port);
729+
}
730+
731+
bool AsyncClient::connect(IPv6Address ip, uint16_t port){
732+
ip_addr_t addr;
733+
addr.type = IPADDR_TYPE_V6;
734+
memcpy(addr.u_addr.ip6.addr, static_cast<const uint32_t*>(ip), sizeof(uint32_t) * 4);
735+
736+
return _connect(addr, port);
737+
}
738+
732739
bool AsyncClient::connect(const char* host, uint16_t port){
733740
ip_addr_t addr;
734-
741+
735742
if(!_start_async_task()){
736743
log_e("failed to start task");
737744
return false;
738745
}
739-
746+
740747
err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
741748
if(err == ERR_OK) {
742-
#if LWIP_IPV4 && LWIP_IPV6
749+
if(addr.type == IPADDR_TYPE_V6) {
750+
return connect(IPv6Address(addr.u_addr.ip6.addr), port);
751+
}
743752
return connect(IPAddress(addr.u_addr.ip4.addr), port);
744753
#else
745754
return connect(IPAddress(addr.addr), port);
@@ -1011,10 +1020,8 @@ void AsyncClient::_dns_found(struct ip_addr *ipaddr){
10111020
#if LWIP_IPV4 && LWIP_IPV6
10121021
if(ipaddr && ipaddr->u_addr.ip4.addr){
10131022
connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port);
1014-
#else
1015-
if (ipaddr && ipaddr->addr){
1016-
connect(IPAddress(ipaddr->addr), _connect_port);
1017-
#endif
1023+
} else if(ipaddr && ipaddr->u_addr.ip6.addr){
1024+
connect(IPv6Address(ipaddr->u_addr.ip6.addr), _connect_port);
10181025
} else {
10191026
if(_error_cb) {
10201027
_error_cb(_error_cb_arg, this, -55);
@@ -1110,6 +1117,15 @@ uint32_t AsyncClient::getRemoteAddress() {
11101117
#endif
11111118
}
11121119

1120+
ip6_addr_t AsyncClient::getRemoteAddress6() {
1121+
if(!_pcb) {
1122+
ip6_addr_t nulladdr;
1123+
ip6_addr_set_zero(&nulladdr);
1124+
return nulladdr;
1125+
}
1126+
return _pcb->remote_ip.u_addr.ip6;
1127+
}
1128+
11131129
uint16_t AsyncClient::getRemotePort() {
11141130
if(!_pcb) {
11151131
return 0;
@@ -1128,6 +1144,15 @@ uint32_t AsyncClient::getLocalAddress() {
11281144
#endif
11291145
}
11301146

1147+
ip6_addr_t AsyncClient::getLocalAddress6() {
1148+
if(!_pcb) {
1149+
ip6_addr_t nulladdr;
1150+
ip6_addr_set_zero(&nulladdr);
1151+
return nulladdr;
1152+
}
1153+
return _pcb->local_ip.u_addr.ip6;
1154+
}
1155+
11311156
uint16_t AsyncClient::getLocalPort() {
11321157
if(!_pcb) {
11331158
return 0;
@@ -1139,6 +1164,10 @@ IPAddress AsyncClient::remoteIP() {
11391164
return IPAddress(getRemoteAddress());
11401165
}
11411166

1167+
IPv6Address AsyncClient::remoteIP6() {
1168+
return IPv6Address(getRemoteAddress6().addr);
1169+
}
1170+
11421171
uint16_t AsyncClient::remotePort() {
11431172
return getRemotePort();
11441173
}
@@ -1147,6 +1176,10 @@ IPAddress AsyncClient::localIP() {
11471176
return IPAddress(getLocalAddress());
11481177
}
11491178

1179+
IPv6Address AsyncClient::localIP6() {
1180+
return IPv6Address(getLocalAddress6().addr);
1181+
}
1182+
11501183
uint16_t AsyncClient::localPort() {
11511184
return getLocalPort();
11521185
}
@@ -1279,16 +1312,30 @@ int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err){
12791312

12801313
AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
12811314
: _port(port)
1315+
, _bind4(true)
12821316
, _addr(addr)
12831317
, _noDelay(false)
12841318
, _pcb(0)
12851319
, _connect_cb(0)
12861320
, _connect_cb_arg(0)
12871321
{}
12881322

1323+
AsyncServer::AsyncServer(IPv6Address addr, uint16_t port)
1324+
: _port(port)
1325+
, _bind6(true)
1326+
, _addr6(addr)
1327+
, _noDelay(false)
1328+
, _pcb(0)
1329+
, _connect_cb(0)
1330+
, _connect_cb_arg(0)
1331+
{}
1332+
12891333
AsyncServer::AsyncServer(uint16_t port)
12901334
: _port(port)
1335+
, _bind4(true)
1336+
, _bind6(true)
12911337
, _addr((uint32_t) IPADDR_ANY)
1338+
, _addr6()
12921339
, _noDelay(false)
12931340
, _pcb(0)
12941341
, _connect_cb(0)
@@ -1313,20 +1360,26 @@ void AsyncServer::begin(){
13131360
log_e("failed to start task");
13141361
return;
13151362
}
1316-
int8_t err;
1317-
_pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
1363+
int8_t err, bind_type;
1364+
1365+
if(_bind4 && _bind6) {
1366+
bind_type = IPADDR_TYPE_ANY;
1367+
} else if (_bind6) {
1368+
bind_type = IPADDR_TYPE_V6;
1369+
} else {
1370+
bind_type = IPADDR_TYPE_V4;
1371+
}
1372+
1373+
_pcb = tcp_new_ip_type(bind_type);
13181374
if (!_pcb){
13191375
log_e("_pcb == NULL");
13201376
return;
13211377
}
13221378

13231379
ip_addr_t local_addr;
1324-
#if LWIP_IPV4 && LWIP_IPV6
1325-
local_addr.type = IPADDR_TYPE_V4;
1380+
local_addr.type = bind_type;
13261381
local_addr.u_addr.ip4.addr = (uint32_t) _addr;
1327-
#else
1328-
local_addr.addr = (uint32_t) _addr;
1329-
#endif
1382+
memcpy(local_addr.u_addr.ip6.addr, static_cast<const uint32_t*>(_addr6), sizeof(uint32_t) * 4);
13301383
err = _tcp_bind(_pcb, &local_addr, _port);
13311384

13321385
if (err != ERR_OK) {

src/AsyncTCP.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@
2323
#define ASYNCTCP_H_
2424

2525
#include "IPAddress.h"
26+
#include "IPv6Address.h"
27+
#include "sdkconfig.h"
2628
#include <functional>
2729

2830
#ifndef LIBRETINY
2931
#include "sdkconfig.h"
3032
extern "C" {
3133
#include "freertos/semphr.h"
3234
#include "lwip/pbuf.h"
35+
#include "lwip/ip_addr.h"
36+
#include "lwip/ip6_addr.h"
3337
}
3438
#else
3539
extern "C" {
@@ -80,7 +84,8 @@ class AsyncClient {
8084
return !(*this == other);
8185
}
8286
bool connect(IPAddress ip, uint16_t port);
83-
bool connect(const char* host, uint16_t port);
87+
bool connect(IPv6Address ip, uint16_t port);
88+
bool connect(const char *host, uint16_t port);
8489
void close(bool now = false);
8590
void stop();
8691
int8_t abort();
@@ -114,15 +119,19 @@ class AsyncClient {
114119
bool getNoDelay();
115120

116121
uint32_t getRemoteAddress();
122+
ip6_addr_t getRemoteAddress6();
117123
uint16_t getRemotePort();
118124
uint32_t getLocalAddress();
125+
ip6_addr_t getLocalAddress6();
119126
uint16_t getLocalPort();
120127

121128
//compatibility
122129
IPAddress remoteIP();
123-
uint16_t remotePort();
130+
IPv6Address remoteIP6();
131+
uint16_t remotePort();
124132
IPAddress localIP();
125-
uint16_t localPort();
133+
IPv6Address localIP6();
134+
uint16_t localPort();
126135

127136
void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect
128137
void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected
@@ -154,6 +163,8 @@ class AsyncClient {
154163
tcp_pcb * pcb(){ return _pcb; }
155164

156165
protected:
166+
bool _connect(ip_addr_t addr, uint16_t port);
167+
157168
tcp_pcb* _pcb;
158169
int8_t _closed_slot;
159170

@@ -202,6 +213,7 @@ class AsyncClient {
202213
class AsyncServer {
203214
public:
204215
AsyncServer(IPAddress addr, uint16_t port);
216+
AsyncServer(IPv6Address addr, uint16_t port);
205217
AsyncServer(uint16_t port);
206218
~AsyncServer();
207219
void onClient(AcConnectHandler cb, void* arg);
@@ -217,7 +229,10 @@ class AsyncServer {
217229

218230
protected:
219231
uint16_t _port;
232+
bool _bind4 = false;
233+
bool _bind6 = false;
220234
IPAddress _addr;
235+
IPv6Address _addr6;
221236
bool _noDelay;
222237
tcp_pcb* _pcb;
223238
AcConnectHandler _connect_cb;

0 commit comments

Comments
 (0)