Skip to content

Commit 9fc92ba

Browse files
committed
Add some IPv6 WiFi client connectivity support.
1 parent 2d4b7e8 commit 9fc92ba

File tree

3 files changed

+98
-4
lines changed

3 files changed

+98
-4
lines changed

libraries/WiFi/src/WiFiClient.cpp

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,13 +299,90 @@ int WiFiClient::connect(const char *host, uint16_t port)
299299
return connect(host,port,_timeout);
300300
}
301301

302-
int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout_ms)
302+
int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout)
303303
{
304-
IPAddress srv((uint32_t)0);
305-
if(!WiFiGenericClass::hostByName(host, srv)){
304+
struct addrinfo hints, *addr_list, *cur;
305+
/* Do name resolution with both IPv6 and IPv4 */
306+
memset( &hints, 0, sizeof( hints ) );
307+
hints.ai_family = AF_UNSPEC;
308+
hints.ai_socktype = SOCK_STREAM;
309+
hints.ai_protocol = IPPROTO_TCP;
310+
char aport[6]; itoa(port, aport, 10);
311+
312+
if( getaddrinfo( host, aport, &hints, &addr_list ) != 0 )
313+
return 0;
314+
315+
/* Try the sockaddrs until a connection succeeds */
316+
int sockfd;
317+
int res = 0;
318+
for( cur = addr_list; cur != NULL; cur = cur->ai_next )
319+
{
320+
sockfd = (int) socket( cur->ai_family, cur->ai_socktype,
321+
cur->ai_protocol );
322+
if( sockfd < 0 )
323+
{
324+
res = 0;
325+
continue;
326+
}
327+
328+
fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) | O_NONBLOCK );
329+
#ifdef ESP_IDF_VERSION_MAJOR
330+
res = lwip_connect(sockfd, cur->ai_addr, (int) cur->ai_addrlen);
331+
#else
332+
res = lwip_connect_r(sockfd, cur->ai_addr, (int) cur->ai_addrlen);
333+
#endif
334+
if (res >= 0 || errno == EINPROGRESS) {
335+
res = 1;
336+
break;
337+
}
338+
339+
close( sockfd );
340+
res = 0;
341+
}
342+
343+
freeaddrinfo( addr_list );
344+
345+
if (!res) return 0;
346+
347+
fd_set fdset;
348+
struct timeval tv;
349+
FD_ZERO(&fdset);
350+
FD_SET(sockfd, &fdset);
351+
tv.tv_sec = 0;
352+
tv.tv_usec = timeout * 1000;
353+
354+
res = select(sockfd + 1, nullptr, &fdset, nullptr, timeout<0 ? nullptr : &tv);
355+
if (res < 0) {
356+
log_e("select on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno));
357+
close(sockfd);
306358
return 0;
359+
} else if (res == 0) {
360+
log_i("select returned due to timeout %d ms for fd %d", timeout, sockfd);
361+
close(sockfd);
362+
return 0;
363+
} else {
364+
int sockerr;
365+
socklen_t len = (socklen_t)sizeof(int);
366+
res = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &sockerr, &len);
367+
368+
if (res < 0) {
369+
log_e("getsockopt on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno));
370+
close(sockfd);
371+
return 0;
372+
}
373+
374+
if (sockerr != 0) {
375+
log_e("socket error on fd %d, errno: %d, \"%s\"", sockfd, sockerr, strerror(sockerr));
376+
close(sockfd);
377+
return 0;
378+
}
307379
}
308-
return connect(srv, port, timeout_ms);
380+
381+
fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) & (~O_NONBLOCK) );
382+
clientSocketHandle.reset(new WiFiClientSocketHandle(sockfd));
383+
_rxBuffer.reset(new WiFiClientRxBuffer(sockfd));
384+
_connected = true;
385+
return 1;
309386
}
310387

311388
int WiFiClient::setSocketOption(int option, char* value, size_t len)

libraries/WiFi/src/WiFiSTA.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,22 @@ IPv6Address WiFiSTAClass::localIPv6()
764764
return IPv6Address(addr.addr);
765765
}
766766

767+
/**
768+
* Get the station interface global IPv6 address.
769+
* @return IPv6Address
770+
*/
771+
IPv6Address WiFiSTAClass::globalIPv6()
772+
{
773+
esp_ip6_addr_t addr;
774+
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
775+
return IPv6Address();
776+
}
777+
if(esp_netif_get_ip6_global(get_esp_interface_netif(ESP_IF_WIFI_STA), &addr)) {
778+
return IPv6Address();
779+
}
780+
return IPv6Address(addr.addr);
781+
}
782+
767783

768784
bool WiFiSTAClass::_smartConfigStarted = false;
769785
bool WiFiSTAClass::_smartConfigDone = false;

libraries/WiFi/src/WiFiSTA.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class WiFiSTAClass
9292

9393
bool enableIpV6();
9494
IPv6Address localIPv6();
95+
IPv6Address globalIPv6();
9596

9697
// STA WiFi info
9798
static wl_status_t status();

0 commit comments

Comments
 (0)